Hi All. I'm quite new to Pulumi. I found a brilli...
# aws
c
Hi All. I'm quite new to Pulumi. I found a brilliant tutorial showing how to very easily deploy an ECS fargate service and deploy an ERC image (with all the VPC, networks, etc added automatically by crosswalk. Does anyone know where I can find something similar, but including an RDS database that the ECS service communicates with?
s
Have you taken a look at Pulumi AI? https://www.pulumi.com/ai/ Pulumi AI can help with generating code to provision an RDS instance for your service.
c
Oh my! That is out of control.
WOW!
Ok, I'm a little less impressed after using it for a while. Its about as good as ChatGPT and it makes a ton of mistakes. Cool concept. Would be cool if it ensured that the code it offered was valid code
s
It’s not perfect, certainly. One thing you may not have been aware of: if you tried to
pulumi up
the code it gave you and got an error, you can tell Pulumi AI to fix the error and supply the error details. It is often able to correct mistakes in the initial code it provided. Might be worth a try. At the very least, it should have provided enough information on creating an RDS instance, as well as a link to the docs, to get you rolling.
b
@careful-vegetable-11632 i curate a set of examples that work: https://github.com/jaxxstorm/pulumi-examples If you have a specific desire for how you want to architect things, I can put an example together
c
Thanks @billowy-army-68599! I'll take a look through your examples. I am hoping to follow the pattern suggested here with the Fargate Instance in a private subnet, and the Loadbalancer in a public subnet connected to an internet gateway. https://docs.aws.amazon.com/AmazonECS/latest/bestpracticesguide/networking-outbound.html (The article has a NatGateway, but my understanding is that a LB should do the trick). I have tried to put it together, following this tutorial: https://www.pulumi.com/docs/clouds/aws/guides/ However, when I added the rds database, I realized that I needed to figure our the security groups and networking to allow the ecs service to access the database.
I have taken a stab at it. Will paste my code below
Copy code
import pulumi
import pulumi_aws as aws
import pulumi_awsx as awsx
import os

# Load the environment variables
PYPI_INDEX_URL = os.environ.get("PYPI_INDEX_URL")
# TODO: Get PYPI_INDEX_URL using Pulumi instead
# TODO: I have run export DOCKER_SCAN_SUGGEST=false to get rid of the warning. Need to fix vulnerabilities

# Get default VPC
vpc = aws.ec2.DefaultVpc('default')


# Create a SecurityGroup that allows HTTP ingress and unrestricted egress
web_sg = aws.ec2.SecurityGroup(
    'web-secgrp',
    vpc_id=vpc.id,
    ingress=[{
        'protocol': 'tcp',
        'from_port': 80,
        'to_port': 80,
        'cidr_blocks': ['0.0.0.0/0'],
    }]
)

# Create an RDS SecurityGroup that allows PostgreSQL egress from the Web SecurityGroup
rds_sg = aws.ec2.SecurityGroup(
    'rds-secgrp',
    egress=[aws.ec2.SecurityGroupEgressArgs(protocol='-1', from_port=0, to_port=0, cidr_blocks=['0.0.0.0/0'])],
    ingress=[aws.ec2.SecurityGroupIngressArgs(
        protocol='tcp', from_port=5432, to_port=5432, security_groups=[web_sg]),
    ]
)


# Create an AWS RDS PostgreSQL database
database = aws.rds.Instance(
    "turnstaydb",
    engine="postgres",
    engine_version = '14.7',
    instance_class="db.t3.micro",
    allocated_storage=20,
    name="turnstaybd",
    username="postgres",
    password="G1v*y3#i13P9",
    publicly_accessible=True,
    skip_final_snapshot=True,
    vpc_security_group_ids=[rds_sg.id]
)




# An ECS Fargate cluster
cluster = aws.ecs.Cluster("TurnStayCluster")


# Creating a ECR Repository
repository = awsx.ecr.Repository("TunStayAPIRepository")

#Creating a ECR Image
image = awsx.ecr.Image("tunstay-api-image",
    repository_url=repository.url,
    args ={"PYPI_INDEX_URL": PYPI_INDEX_URL},
    path="../"
    )

# Create the AWS Load Balancer
lb = awsx.lb.ApplicationLoadBalancer(
    "TurnStayLoadBalancer",
    )


# Task definition for the Fargate service
task_def = awsx.ecs.FargateTaskDefinition(
    "TurnStayApiTaskDef",
    containers={
        "TurnStayApi": awsx.ecs.TaskDefinitionContainerDefinitionArgs(
            image=image.image_uri,
            memory=128,
            cpu=512,
            essential=True,
            port_mappings=[awsx.ecs.TaskDefinitionPortMappingArgs(target_group=lb.default_target_group,)],
            environment =[
                {
                    "name": database.endpoint,
                    "value": "<http://turnstay-staging-database-1.cwxi1s8c9ygu.eu-west-1.rds.amazonaws.com|turnstay-staging-database-1.cwxi1s8c9ygu.eu-west-1.rds.amazonaws.com>"
                },
                {
                    "name": database.username,
                    "value": "postgres"
                },
                {
                    "name": "DEFAULT_DATABASE_PORT",
                    "value": "5432"
                },
                {
                    "name": "DEFAULT_DATABASE_DB",
                    "value": "postgres"
                },
                {
                    "name": "DEFAULT_DATABASE_PASSWORD",
                    "value": "G1v*y3#i13P9"
                },
                {
                    "name": "ENVIRONMENT",
                    "value": "STG"
                }
            ],
            secrets=[],
        ),
    },
)


# Create a Fargate service
fargate_service = awsx.ecs.FargateService(
    "TurnStayAPIService",
    cluster=cluster,
    task_definition=task_def,
    desired_count=1,
    assign_public_ip=True,
    # network_configuration=aws.ecs.ServiceNetworkConfigurationArgs(
    #     assign_public_ip=True,
    #     security_groups=[web_sg.id],
    # ),
)
@billowy-army-68599 Its pretty similar to your example here: https://github.com/jaxxstorm/pulumi-examples/blob/main/python/aws/fargate_awsx_vpc/__main__.py But with a database added to the mix.
b
How do you want the database to look?
A private rds? MySQL? Postgres?
c
Yup. Postgres
b
If you can find me an example app you want to deploy, happy to throw an example together
c
Amazing. I will send you one tomorrow morning (about to go to sleep here in Cape Town)
The project that I am working off is built off of this template: https://github.com/rafsaf/minimal-fastapi-postgres-template
b
so you’re working in python?
@careful-vegetable-11632 had a few mins this evening, so threw this together: https://github.com/jaxxstorm/pulumi-examples/tree/main/python/aws/fargate_postgres_webapp/deploy it should do everything you need with the example webapp you shared
c
Wow! The code you wrote worked first time!!! Thank you so much!!! I've trying to get this to work for 2 weeks!
Now that I see your solution, I understand the value of defining every resource yourself, instead of using something like awsx crosswalk. It allows you to think through each step more explicitly. Also, it's cool to see how every resource needs permission to talk to every other resource. Its a lot to keep track of, but I can see how when you are used to more the terminology you can start reasoning about things from first principals.
@billowy-army-68599 you are a total legend!!! Thank you so much
b
Really happy to help!