air-tech-assessment/air-tech/__main__.py

217 lines
6.6 KiB
Python
Raw Normal View History

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])
)