|
| 1 | +// Copyright 2024, Pulumi Corporation. All rights reserved. |
| 2 | + |
| 3 | +// Pulumi program to build with DBC and push a Docker image |
| 4 | +// to AWS ECR and deploys it in AWS Fargate with an ALB. |
| 5 | + |
| 6 | +// Pre-requisites: |
| 7 | +// - AWS Credentials |
| 8 | +// - Docker Build Cloud (DBC) |
| 9 | +// - Docker Desktop / CLI |
| 10 | +// - Pulumi CLI (https://www.pulumi.com/docs/get-started/install/) |
| 11 | +// - *Recommended* Pulumi Cloud account (https://app.pulumi.com/signup) |
| 12 | + |
| 13 | +// This Pulumi template is meant to be copied via: |
| 14 | +// $ pulumi new https://github.com/pulumi/examples/tree/master/aws-ts-containers-dbc |
| 15 | +// Once copied to your machine, feel free to edit as needed. |
| 16 | + |
| 17 | +// As a good practice, update any dependencies to the latest version. |
| 18 | +// $ npm update --save |
| 19 | + |
| 20 | +// How to run this program in your terminal: |
| 21 | +// $ pulumi up |
| 22 | + |
| 23 | +// Import required libraries, update package.json if you add more. |
| 24 | +// (Recommended to run `npm update --save` after adding more libraries) |
| 25 | +import * as aws from "@pulumi/aws"; // Required for ECS |
| 26 | +import * as awsx from "@pulumi/awsx"; |
| 27 | +import * as dockerBuild from "@pulumi/docker-build"; |
| 28 | +import * as pulumi from "@pulumi/pulumi"; // Required for Config and interpolation |
| 29 | + |
| 30 | +// Read the current stack configuration, see Pulumi.<STACK>.yaml file |
| 31 | +// Configuration values can be set with the pulumi config set command |
| 32 | +// OR by editing the Pulumi.<STACK>.yaml file. |
| 33 | +// OR during the pulumi new wizard. |
| 34 | +const config = new pulumi.Config(); |
| 35 | +// Docker Build Cloud (DBC) builder name |
| 36 | +const builder = config.require("builder"); // Example, "cloud-pulumi-my-cool-builder" |
| 37 | + |
| 38 | +// An ECS cluster to deploy into. |
| 39 | +const cluster = new aws.ecs.Cluster("cluster", {}); |
| 40 | + |
| 41 | +// An ALB to serve the container endpoint to the internet. |
| 42 | +const loadbalancer = new awsx.lb.ApplicationLoadBalancer("loadbalancer", {}); |
| 43 | + |
| 44 | +// An ECR repository to store our application's container image. |
| 45 | +const ecr = new awsx.ecr.Repository("repo", { |
| 46 | + forceDelete: true, |
| 47 | +}); |
| 48 | + |
| 49 | +// Grab auth credentials for ECR. |
| 50 | +const auth = aws.ecr.getAuthorizationTokenOutput({ |
| 51 | + registryId: ecr.repository.registryId, |
| 52 | +}); |
| 53 | + |
| 54 | +// Build and publish our application's container image from ./app to the ECR repository. |
| 55 | +// This image will be built with Docker Build Cloud (DBC) and pushed to ECR. |
| 56 | +// It uses the Docker Build provider |
| 57 | +const image = new dockerBuild.Image("image", { |
| 58 | + // ____ _ ____ _ _ _ |
| 59 | + // | _ \ ___ ___| | _____ _ __ | __ ) _ _(_) | __| | |
| 60 | + // | | | |/ _ \ / __| |/ / _ \ '__| | _ \| | | | | |/ _` | |
| 61 | + // | |_| | (_) | (__| < __/ | | |_) | |_| | | | (_| | |
| 62 | + // |____/ \___/ \___|_|\_\___|_| |____/ \__,_|_|_|\__,_| |
| 63 | + // / ___| | ___ _ _ __| | |
| 64 | + // | | | |/ _ \| | | |/ _` | |
| 65 | + // | |___| | (_) | |_| | (_| | |
| 66 | + // \____|_|\___/ \__,_|\__,_| |
| 67 | + // Enable exec to run a custom docker-buildx binary with support |
| 68 | + // for Docker Build Cloud (DBC). |
| 69 | + exec: true, |
| 70 | + // Configures the name of your existing buildx builder to use. |
| 71 | + builder: { |
| 72 | + name: builder, // Example, "cloud-pulumi-my-cool-builder", |
| 73 | + }, |
| 74 | + // _ _ |
| 75 | + // ___ __ _ ___| |__ (_)_ __ __ _ |
| 76 | + // / __/ _` |/ __| '_ \| | '_ \ / _` | |
| 77 | + // | (_| (_| | (__| | | | | | | | (_| | |
| 78 | + // \___\__,_|\___|_| |_|_|_| |_|\__, | |
| 79 | + // |___/ |
| 80 | + // Use the pushed image as a cache source. |
| 81 | + cacheFrom: [{ |
| 82 | + registry: { |
| 83 | + ref: pulumi.interpolate`${ecr.repository.repositoryUrl}:cache`, |
| 84 | + }, |
| 85 | + }], |
| 86 | + cacheTo: [{ |
| 87 | + registry: { |
| 88 | + imageManifest: true, |
| 89 | + ociMediaTypes: true, |
| 90 | + ref: pulumi.interpolate`${ecr.repository.repositoryUrl}:cache`, |
| 91 | + }, |
| 92 | + }], |
| 93 | + // (Learn more about interpolation with Pulumi) |
| 94 | + // https://www.pulumi.com/docs/concepts/inputs-outputs/all/#using-string-interpolation |
| 95 | + |
| 96 | + // _ _ _ _ _ __ |
| 97 | + // _ __ ___ _ _| | |_(_) _ __ | | __ _| |_ / _| ___ _ __ _ __ ___ |
| 98 | + // | '_ ` _ \| | | | | __| |_____| '_ \| |/ _` | __| |_ / _ \| '__| '_ ` _ \ |
| 99 | + // | | | | | | |_| | | |_| |_____| |_) | | (_| | |_| _| (_) | | | | | | | | |
| 100 | + // |_| |_| |_|\__,_|_|\__|_| | .__/|_|\__,_|\__|_| \___/|_| |_| |_| |_| |
| 101 | + // |_| |
| 102 | + // Build multi-platforms |
| 103 | + platforms: [ |
| 104 | + dockerBuild.Platform.Linux_amd64, |
| 105 | + // add more as needed |
| 106 | + ], |
| 107 | + // _ _ |
| 108 | + // _ __ ___ __ _(_)___| |_ _ __ _ _ |
| 109 | + // | '__/ _ \/ _` | / __| __| '__| | | | |
| 110 | + // | | | __/ (_| | \__ \ |_| | | |_| | |
| 111 | + // |_| \___|\__, |_|___/\__|_| \__, | |
| 112 | + // |___/ |___/ |
| 113 | + push: true, |
| 114 | + // Provide our ECR credentials. |
| 115 | + registries: [{ |
| 116 | + address: ecr.repository.repositoryUrl, |
| 117 | + password: auth.password, |
| 118 | + username: auth.userName, |
| 119 | + }], |
| 120 | + // |
| 121 | + // Other parameters |
| 122 | + // |
| 123 | + // Tag our image with our ECR repository's address. |
| 124 | + tags: [pulumi.interpolate`${ecr.repository.repositoryUrl}:latest`], |
| 125 | + // The Dockerfile resides in the app directory for this example. |
| 126 | + context: { |
| 127 | + location: "app", |
| 128 | + }, |
| 129 | +}); |
| 130 | + |
| 131 | +// Deploy an ECS Service on Fargate to host the application container. |
| 132 | +const service = new awsx.ecs.FargateService("service", { |
| 133 | + cluster: cluster.arn, |
| 134 | + assignPublicIp: true, |
| 135 | + taskDefinitionArgs: { |
| 136 | + container: { |
| 137 | + name: "service-container", |
| 138 | + image: image.ref, |
| 139 | + cpu: 128, |
| 140 | + memory: 512, |
| 141 | + essential: true, |
| 142 | + portMappings: [{ |
| 143 | + containerPort: 80, |
| 144 | + targetGroup: loadbalancer.defaultTargetGroup, |
| 145 | + }], |
| 146 | + }, |
| 147 | + }, |
| 148 | +}); |
| 149 | + |
| 150 | +// The URL at which the container's HTTP endpoint will be available. |
| 151 | +export const url = pulumi.interpolate`http://${loadbalancer.loadBalancer.dnsName}`; |
0 commit comments