Skip to content

Instantly share code, notes, and snippets.

@HeathLoganCampbell
Last active October 16, 2023 10:17
Show Gist options
  • Save HeathLoganCampbell/b1fb043d5e6d20364616b023bf174b8e to your computer and use it in GitHub Desktop.
Save HeathLoganCampbell/b1fb043d5e6d20364616b023bf174b8e to your computer and use it in GitHub Desktop.
Using Pulumi C# creating an AWS ECS cluster that stands up MongoDB and Mongo express
namespace Main.Infra
{
using System;
using System.Text.Json;
using Pulumi;
using Pulumi.Aws.ServiceDiscovery;
using Awsx = Pulumi.Awsx;
using Aws = Pulumi.Aws;
public class MainStack : Stack
{
[Output] public Output<string> VpcId { get; private set; }
[Output] public Output<string> ClusterId { get; private set; }
[Output] public Output<string> Url { get; private set; }
[Output] public Output<string> RepositoryUrl { get; private set; }
public MainStack()
{
string resourcePrefix = "cookie";
// Create VPC
var vpc = new Awsx.Ec2.Vpc(resourcePrefix + "-vpc", new Awsx.Ec2.VpcArgs
{
NumberOfAvailabilityZones = 2,
Tags =
{
{ "Name", resourcePrefix + "-vpc" }
}
});
// Create ECS Cluster
var cluster = new Aws.Ecs.Cluster(resourcePrefix + "-cluster", new Aws.Ecs.ClusterArgs { });
var webSg = new Aws.Ec2.SecurityGroup(resourcePrefix + "-sg", new Aws.Ec2.SecurityGroupArgs
{
VpcId = vpc.VpcId,
Egress =
{
new Aws.Ec2.Inputs.SecurityGroupEgressArgs
{
Protocol = "-1",
FromPort = 0,
ToPort = 0,
CidrBlocks = { "0.0.0.0/0" }
}
},
Ingress =
{
new Aws.Ec2.Inputs.SecurityGroupIngressArgs
{
Protocol = "tcp",
FromPort = 80,
ToPort = 80,
CidrBlocks = { "0.0.0.0/0" }
},
new Aws.Ec2.Inputs.SecurityGroupIngressArgs
{
Protocol = "tcp",
FromPort = 27017,
ToPort = 27017,
CidrBlocks = { "0.0.0.0/0" }
},
new Aws.Ec2.Inputs.SecurityGroupIngressArgs
{
Protocol = "tcp",
FromPort = 2113,
ToPort = 2113,
CidrBlocks = { "0.0.0.0/0" }
},
new Aws.Ec2.Inputs.SecurityGroupIngressArgs
{
Protocol = "tcp",
FromPort = 8081,
ToPort = 8081,
CidrBlocks = { "0.0.0.0/0" }
},
}
});
var rolePolicyJson = JsonSerializer.Serialize(new
{
Version = "2008-10-17",
Statement = new[]
{
new
{
Sid = "",
Effect = "Allow",
Principal = new
{
Service = "ecs-tasks.amazonaws.com"
},
Action = "sts:AssumeRole"
}
}
});
// Create an IAM role that can be used by our service's task.
var taskExecRole = new Aws.Iam.Role("task-exec-role", new Aws.Iam.RoleArgs
{
AssumeRolePolicy = rolePolicyJson
});
var taskExecPolicyAttach = new Aws.Iam.RolePolicyAttachment("task-exec-policy",
new Aws.Iam.RolePolicyAttachmentArgs
{
Role = taskExecRole.Name,
PolicyArn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
});
var cloudWatchPolicyAttach = new Aws.Iam.RolePolicyAttachment("cloud-watch-policy",
new Aws.Iam.RolePolicyAttachmentArgs
{
Role = taskExecRole.Name,
PolicyArn = "arn:aws:iam::aws:policy/CloudWatchLogsFullAccess"
});
var mainTask = new Aws.Ecs.TaskDefinition(resourcePrefix + "-task",
new Aws.Ecs.TaskDefinitionArgs
{
Family = "main-task-definition",
Cpu = "512",
Memory = "1024",
NetworkMode = "awsvpc",
RequiresCompatibilities = { "FARGATE" },
ExecutionRoleArn = taskExecRole.Arn,
TaskRoleArn = taskExecRole.Arn,
ContainerDefinitions = JsonSerializer.Serialize(new object[]
{
new
{
name = "program-mongo",
image = "mongo:7.0.1",
environment = new[]
{
new { name = "MONGO_INITDB_ROOT_USERNAME", value = "root" },
new { name = "MONGO_INITDB_ROOT_PASSWORD", value = "password" },
},
portMappings = new[]
{
new
{
containerPort = 27017,
hostPort = 27017,
protocol = "tcp",
},
new
{
containerPort = 28017,
hostPort = 28017,
protocol = "tcp",
}
},
healthCheck = new
{
command = new[] { "CMD-SHELL", "mongosh -u root -p password --quiet --eval \"db.runCommand('ping').ok\" localhost:27017 || exit 1" },
interval = 20,
timeout = 5,
retries = 3,
startPeriod = 120
},
logConfiguration = new
{
logDriver = "awslogs",
options = new AwsLogOptions(),
secretOptions = Array.Empty<object>()
}
},
new
{
name = "mexpress",
image = "mongo-express",
Essential = false,
environment = new[]
{
new { Name = "ME_CONFIG_MONGODB_URL", Value = "mongodb://root:password@localhost:27017/" },
new { Name = "ME_CONFIG_MONGODB_ADMINUSERNAME", Value = "root" },
new { Name = "ME_CONFIG_MONGODB_ADMINPASSWORD", Value = "password" },
},
healthCheck = new
{
command = new[] { "CMD-SHELL", "curl -f localhost:8081/" },
interval = 20,
timeout = 5,
retries = 3,
startPeriod = 120
},
portMappings = new[]
{
new
{
containerPort = 8081,
hostPort = 8081,
protocol = "tcp",
}
},
logConfiguration = new
{
logDriver = "awslogs",
options = new AwsLogOptions(),
secretOptions = Array.Empty<object>()
},
dependsOn = new[]
{
new { containerName = "program-mongo", condition = "HEALTHY" }
},
}
})
});
var mainSvc = new Aws.Ecs.Service(resourcePrefix + "-svc", new Aws.Ecs.ServiceArgs
{
Cluster = cluster.Arn,
DesiredCount = 1,
LaunchType = "FARGATE",
TaskDefinition = mainTask.Arn,
NetworkConfiguration = new Aws.Ecs.Inputs.ServiceNetworkConfigurationArgs
{
AssignPublicIp = true,
Subnets = vpc.PublicSubnetIds,
SecurityGroups = { webSg.Id }
}
});
// Export LB DNS name
VpcId = vpc.VpcId.Apply(id => id);
ClusterId = cluster.Id.Apply(id => id);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment