217 lines
6.6 KiB
Python
217 lines
6.6 KiB
Python
|
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])
|
||
|
)
|