import pulumi from pulumi import Config, Output, export import pulumi_aws as aws from pulumi_aws import acm, alb, ecs, ec2, lb, iam, ecr import pulumi_awsx as awsx import json config = Config() # container_port = config.get_int("containerPort", 80) cpu = config.get_int("cpu", 512) memory = config.get_int("memory", 128) # Create a VPC vpc = ec2.Vpc("production", cidr_block="10.0.0.0/16") # Create a Gateway ig = ec2.InternetGateway("internet-gateway", vpc_id=vpc.id) cert = acm.Certificate( "air-tech", domain_name="air-tech.ahosking.com", validation_method="DNS", ) # Public Subnet public_subnet = ec2.Subnet( "public-subnet", vpc_id=vpc.id, cidr_block="10.0.1.0/26", availability_zone="us-east-2a", # Allow the Internet Gateway to handle public traffic map_public_ip_on_launch=True ) public_subnet2 = ec2.Subnet( "public-subnet2", vpc_id=vpc.id, cidr_block="10.0.2.0/26", availability_zone="us-east-2b", # Allow the Internet Gateway to handle public traffic map_public_ip_on_launch=True ) # Associate the Gateway to a route route_table = ec2.RouteTable('route-table', vpc_id=vpc.id) route = ec2.Route('route', route_table_id=route_table.id, destination_cidr_block='0.0.0.0/0', gateway_id=ig.id) # Private Subnet private_subnet = ec2.Subnet( "private-subnet", vpc_id=vpc.id, cidr_block="10.0.3.0/26", availability_zone="us-east-2a", map_public_ip_on_launch=False ) private_subnet2 = ec2.Subnet( "private-subnet2", vpc_id=vpc.id, cidr_block="10.0.4.0/26", availability_zone="us-east-2b", map_public_ip_on_launch=False ) repo = ecr.Repository("repo") # Create an IAM role ecs_task_execution_role = iam.Role("ecsExecutionRole", path="/", assume_role_policy=iam.get_policy_document(statements=[{ "actions": ["sts:AssumeRole"], "principals": { "type": "Service", "identifiers": ["ecs-tasks.amazonaws.com"] } } ]).json, ) # Attach a policy to the execution role that will allow it to pull images from ECR iam.RolePolicy("accessECRImages", role=ecs_task_execution_role.id, policy={ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ecr:GetDownloadUrlForLayer", "ecr:BatchGetImage", "ecr:BatchCheckLayerAvailability", ], "Resource": repo.repository_arn } ] } ) image_web = awsx.ecr.Image( "image_web", repository_url=repo.url, path=".", dockerfile=".\infra-web\Dockerfile") image_api = awsx.ecr.Image( "image_api", repository_url=repo.url, path=".", dockerfile=".\infra-api\Dockerfile") security_group = aws.ec2.SecurityGroup( "securityGroup", vpc_id=vpc.id, egress=[aws.ec2.SecurityGroupEgressArgs( from_port=0, to_port=0, protocol="-1", cidr_blocks=["0.0.0.0/0"], ipv6_cidr_blocks=["::/0"], )]) # Create an ECS Cluster cluster = ecs.Cluster("cluster") pulumi.export("certificateArn", cert.arn) loadbalancer = lb.LoadBalancer( "loadbalancer", load_balancer_type="application", security_groups=[security_group.id], subnets=[public_subnet.id, public_subnet2.id]) target_group = lb.TargetGroup('target-group', port=5000, protocol="HTTP", target_type="ip", vpc_id=vpc.id) # Create a listener for the ALB at port 80 listener = lb.Listener('listener', load_balancer_arn=loadbalancer.arn, port=80, default_actions=[{ 'type': "forward", 'target_group_arn': target_group.arn # Forward to our target group }]) web_sg = ec2.SecurityGroup('web-sg', vpc_id=vpc.id, ingress=[ { 'protocol': 'tcp', 'from_port': 80, 'to_port': 80, 'cidr_blocks': ['0.0.0.0/0'], } ], egress=[ { 'protocol': '-1', 'from_port': 0, 'to_port': 0, 'cidr_blocks': ['0.0.0.0/0'], } ] ) api = awsx.ecs.FargateService( "api", cluster=cluster.arn, network_configuration={ 'assignPublicIp': "false", 'subnets': [private_subnet.id], 'securityGroups': [web_sg.id] }, task_definition_args=awsx.ecs.FargateServiceTaskDefinitionArgs( container=awsx.ecs.TaskDefinitionContainerDefinitionArgs( name="theApi", image=image_api.image_uri, cpu=cpu, memory=memory, essential=True, port_mappings=[awsx.ecs.TaskDefinitionPortMappingArgs( container_port=5000, host_port=5000, )], ), )) service = awsx.ecs.FargateService( "web", cluster=cluster.arn, network_configuration={ 'assignPublicIp': "true", 'subnets': [public_subnet.id], 'securityGroups': [web_sg.id] }, # assign_public_ip=True, task_definition_args=awsx.ecs.FargateServiceTaskDefinitionArgs( container=awsx.ecs.TaskDefinitionContainerDefinitionArgs( name="theOne", image=image_web.image_uri, cpu=cpu, memory=memory, essential=True, port_mappings=[awsx.ecs.TaskDefinitionPortMappingArgs( container_port=5000, host_port=5000, target_group=target_group, )], ), ), opts=pulumi.ResourceOptions(depends_on=[api, target_group]) )