Last active
October 16, 2023 10:17
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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