1. Packages
  2. AWS
  3. How-to Guides
  4. Running Containers on ECS Fargate
AWS v6.60.0 published on Tuesday, Nov 19, 2024 by Pulumi

Running Containers on ECS Fargate

aws logo
AWS v6.60.0 published on Tuesday, Nov 19, 2024 by Pulumi

    View TypeScript Code

    In this tutorial, we’ll build and publish a Docker container to a private Elastic Container Registry (ECR), and spin up a load-balanced Amazon Elastic Container Service (Amazon ECS) Fargate service, all in a handful of lines of code, using Pulumi Crosswalk for AWS.

    Prerequisites

    1. Install Docker Engine - Community
    2. Install Pulumi
    3. Configure Pulumi to use your AWS account

    Deploy the App

    Step 1: Create a new project from a template

    Create a project directory, hello-fargate, and change into it. Run pulumi new aws-typescript --name myproject to create a new project using the AWS template for TypeScript. Replace myproject with your desired project name.

    Run pulumi new to create a new project:

    $ mkdir hello-fargate && cd hello-fargate
    $ pulumi new aws-typescript --name myproject
    

    Step 2: Build the Dockerized app

    Create a subdirectory, app, which will contain your sample Dockerized application. From the app subdirectory, add the following files:

    Dockerfile

    FROM nginx
    COPY index.html /usr/share/nginx/html
    

    index.html

    <html>
      <head><meta charset="UTF-8">
        <title>Hello Fargate</title>
      </head>
      <body>
          <p>Hello AWS Fargate!</p>
          <p>Made with ❤️ with <a href="https://pulumi.com">Pulumi</a></p>
      </body>
    </html>
    

    Step 3: Create the ECS cluster

    Replace the contents of index.ts with the following:

    import * as aws from "@pulumi/aws";
    import * as awsx from "@pulumi/awsx";
    import * as pulumi from "@pulumi/pulumi";
    
    // An ECS cluster to deploy into.
    const cluster = new aws.ecs.Cluster("cluster", {});
    

    Step 4: Create the load balancer

    Add the following lines to index.ts:

    // Create a load balancer to listen for requests and route them to the container.
    const loadbalancer = new awsx.lb.ApplicationLoadBalancer("loadbalancer", {});
    

    Step 5: Define the service and publish the Docker image

    Add the following lines to index.ts:

    
    // Create the ECR repository to store our container image
    const repo = new awsx.ecr.Repository("repo", {
        forceDelete: true,
    });
    
    // Build and publish our application's container image from ./app to the ECR repository.
    const image = new awsx.ecr.Image("image", {
        repositoryUrl: repo.url,
        context: "./app",
        platform: "linux/amd64",
    });
    
    // Define the service and configure it to use our image and load balancer.
    const service = new awsx.ecs.FargateService("service", {
        cluster: cluster.arn,
        assignPublicIp: true,
        taskDefinitionArgs: {
            container: {
                name: "awsx-ecs",
                image: image.imageUri,
                cpu: 128,
                memory: 512,
                essential: true,
                portMappings: [{
                    containerPort: 80,
                    targetGroup: loadbalancer.defaultTargetGroup,
                }],
            },
        },
    });
    
    // Export the URL so we can easily access it.
    export const frontendURL = pulumi.interpolate `http://${loadbalancer.loadBalancer.dnsName}`;
    

    You just created an automatic cluster in the default AWS VPC to run a Fargate service.

    Step 6: Verify your app structure

    In addition to the node_modules directory and related npm package files, ensure you have the following directory structure:

    Pulumi.yaml
    index.ts
    app/
      Dockerfile
      index.html
    

    Step 7: Set your AWS region

    Configure the AWS region you would like to use:

    $ pulumi config set aws:region us-east-1
    

    Step 8: Preview and deploy your resources

    To preview your Pulumi program, run pulumi up. The command shows a preview of the resources that will be created and prompts you to proceed with the deployment. Note that the stack itself is counted as a resource, though it does not correspond to a physical cloud resource.

    $ pulumi up
    Previewing update (dev)
    ...
    Do you want to perform this update? yes
    Updating (dev)
    ...
    Diagnostics:
      awsx:x:ecs:FargateTaskDefinition (nginx):
      ...
    
    Outputs:
        frontendURL: "http://nginx-4c517b3-c98ba6a1e62b644e.elb.us-east-1.amazonaws.com/"
    
    Resources:
        + 32 created
    
    Duration: 3m39s
    

    The deployment takes a few minutes. With your pulumi up invocation, Pulumi automatically does the following for you:

    • Build and provision a container registry using ECR
    • Build the Docker image
    • Push the resulting image to the repository

    Step 9: Test the resulting load balancer URL

    Now that you’ve deployed your app, confirm that the service is working via curl.

    $ curl $(pulumi stack output frontendURL)
    <html>
        <head><meta charset="UTF-8">
            <title>Hello Fargate</title>
        </head>
        <body>
            <p>Hello, containers!</p>
            <p>Made with ❤️ with <a href="https://pulumi.com">Pulumi</a></p>
        </body>
    </html>
    

    Step 10: View container logs (Optional)

    To view the runtime logs from the container, use the pulumi logs command. To get a log stream, use pulumi logs --follow.

    $ pulumi logs --follow
    Collecting logs for stack dev since 2021-03-26T10:49:57.000-07:00.
    
     2021-03-26T11:45:02.624-07:00[nginx-185c47c] 172.31.38.69 - - [26/Mar/2021:18:45:02 +0000] "GET / HTTP/1.1" 200 205 "-" "curl/7.64.1" "-"
     2021-03-26T11:48:44.585-07:00[nginx-185c47c] 172.31.38.69 - - [26/Mar/2021:18:48:44 +0000] "GET / HTTP/1.1" 200 205 "-" "Mozilla/5.0 (compatible; Nimbostratus-Bot/v1.3.2; http://cloudsystemnetworks.com)" "-"
    

    Clean Up

    Before moving on, tear down the resources that are part of your stack to avoid incurring any charges.

    1. Run pulumi destroy to tear down all resources. You'll be prompted to make sure you really want to delete these resources. A destroy operation may take some time, since Pulumi waits for the resources to finish shutting down before it considers the destroy operation to be complete.
    2. To delete the stack itself, run pulumi stack rm. Note that this command deletes all deployment history from the Pulumi Service.

    Summary

    In this tutorial, we showed you how to write a Pulumi program in Typescript, and leverage Pulumi Crosswalk for AWS (via the }}">@pulumi/awsx package) in order to build and publish a Dockerized application to a private Elastic Container Registry (ECR), spin up an ECS Fargate cluster, and run a scalable, load balanced service.

    You also learned how to work with the Pulumi CLI. To recap:

    • Run pulumi new <cloud>-<language> --name myproject to create a new project from a language and cloud template.
    • Run pulumi up to preview and update your infrastructure.
    • Run pulumi destroy to clean up your resources.
    • Run pulumi stack rm to delete your stack.

    For a similar example in other languages and clouds, see the Pulumi examples repo.

    Next Steps

    For more information about containerized applications on AWS, please read these User Guides:

    For an end-to-end application also includes serverless functions, see the Serverless plus Containers Thumbnailer tutorial.

    For an example application that connects two containers, see the Voting App sample.

    The code for this tutorial is available on GitHub.

    aws logo
    AWS v6.60.0 published on Tuesday, Nov 19, 2024 by Pulumi