forked from pulumi/examples
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a Docker on AWS Fargate example (pulumi#290)
- Loading branch information
Showing
9 changed files
with
234 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
/bin/ | ||
/node_modules/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
name: aws-ts-hello-fargate | ||
runtime: nodejs | ||
description: A minimal "Hello, World" container in Fargate. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
[![Deploy](https://get.pulumi.com/new/button.svg)](https://app.pulumi.com/new) | ||
|
||
# Get Started with Docker on AWS Fargate | ||
|
||
This example, inspired by the [Docker Getting Started Tutorial](https://docs.docker.com/get-started/), builds, deploys, | ||
and runs a simple containerized application to a private container registry, and scales out five load balanced replicas, | ||
all in just a handful of lines of Node.js code, and leveraging modern and best-in-class AWS features. | ||
|
||
To do this, we use Pulumi infrastructure as code to provision an | ||
[Elastic Container Service (ECS)](https://aws.amazon.com/ecs/) cluster, build our `Dockerfile` and deploy the | ||
resulting image to a private [Elastic Container Registry (ECR)](https://aws.amazon.com/ecr/) repository, and then create | ||
a scaled-out [Fargate](https://aws.amazon.com/fargate/) service behind an | ||
[Elastic Application Load Balancer](https://aws.amazon.com/elasticloadbalancing/) that allows traffic from the Internet | ||
on port 80. Because this example using AWS services directly, you can mix in other resources, like S3 buckets, RDS | ||
databases, and so on. | ||
|
||
# Prerequisites | ||
|
||
- [Node.js](https://nodejs.org/en/download/) | ||
- [Download and install the Pulumi CLI](https://pulumi.io/install) | ||
- [Connect Pulumi with your AWS account](https://pulumi.io/quickstart/aws/setup.html) (if your AWS CLI is | ||
configured, this will just work) | ||
|
||
# Running the Example | ||
|
||
After cloning this repo, `cd` into it and run these commands: | ||
|
||
1. Create a new stack, which is an isolated deployment target for this example: | ||
|
||
```bash | ||
$ pulumi stack init dev | ||
``` | ||
|
||
2. Set your desired AWS region: | ||
|
||
```bash | ||
$ pulumi config set aws:region us-east-1 # any valid AWS region will work | ||
``` | ||
|
||
3. Deploy everything with a single `pulumi up` command. This will show you a preview of changes first, which | ||
includes all of the required AWS resources (clusters, services, and the like). Don't worry if it's more than | ||
you expected -- this is one of the benefits of Pulumi, it configures everything so that so you don't need to! | ||
|
||
```bash | ||
$ pulumi up | ||
``` | ||
|
||
After being prompted and selecting "yes", your deployment will begin. It'll complete in a few minutes: | ||
|
||
``` | ||
Updating (dev): | ||
Type Name Status | ||
+ pulumi:pulumi:Stack aws-ts-hello-fargate-dev created | ||
+ ├─ awsx:x:ecs:Cluster cluster created | ||
+ │ ├─ awsx:x:ec2:SecurityGroup cluster created | ||
+ │ │ ├─ awsx:x:ec2:EgressSecurityGroupRule cluster-egress created | ||
+ │ │ │ └─ aws:ec2:SecurityGroupRule cluster-egress created | ||
+ │ │ ├─ awsx:x:ec2:IngressSecurityGroupRule cluster-ssh created | ||
+ │ │ │ └─ aws:ec2:SecurityGroupRule cluster-ssh created | ||
+ │ │ ├─ awsx:x:ec2:IngressSecurityGroupRule cluster-containers created | ||
+ │ │ │ └─ aws:ec2:SecurityGroupRule cluster-containers created | ||
+ │ │ └─ aws:ec2:SecurityGroup cluster created | ||
+ │ └─ aws:ecs:Cluster cluster created | ||
+ ├─ awsx:x:elasticloadbalancingv2:ApplicationLoadBalancer net-lb created | ||
+ │ ├─ awsx:x:elasticloadbalancingv2:ApplicationTargetGroup web created | ||
+ │ │ └─ aws:elasticloadbalancingv2:TargetGroup ca84d134 created | ||
+ │ ├─ awsx:x:elasticloadbalancingv2:ApplicationListener web created | ||
+ │ │ ├─ awsx:x:ec2:IngressSecurityGroupRule web-external-0-ingress created | ||
+ │ │ │ └─ aws:ec2:SecurityGroupRule web-external-0-ingress created | ||
+ │ │ └─ aws:elasticloadbalancingv2:Listener web created | ||
+ │ └─ aws:elasticloadbalancingv2:LoadBalancer 218ffe37 created | ||
+ ├─ awsx:x:ec2:Vpc default-vpc created | ||
+ │ ├─ awsx:x:ec2:Subnet default-vpc-public-0 created | ||
+ │ ├─ awsx:x:ec2:Subnet default-vpc-public-1 created | ||
> │ ├─ aws:ec2:Subnet default-vpc-public-0 read | ||
> │ └─ aws:ec2:Subnet default-vpc-public-1 read | ||
+ ├─ awsx:x:ecs:FargateTaskDefinition app-svc created | ||
+ │ ├─ aws:ecr:Repository app-img created | ||
+ │ ├─ aws:cloudwatch:LogGroup app-svc created | ||
+ │ ├─ aws:iam:Role app-svc-task created | ||
+ │ ├─ aws:iam:Role app-svc-execution created | ||
+ │ ├─ aws:ecr:LifecyclePolicy app-img created | ||
+ │ ├─ aws:iam:RolePolicyAttachment app-svc-task-32be53a2 created | ||
+ │ ├─ aws:iam:RolePolicyAttachment app-svc-task-fd1a00e5 created | ||
+ │ ├─ aws:iam:RolePolicyAttachment app-svc-execution-9a42f520 created | ||
+ │ └─ aws:ecs:TaskDefinition app-svc created | ||
+ ├─ awsx:x:ecs:FargateService app-svc created | ||
+ │ └─ aws:ecs:Service app-svc created | ||
> └─ aws:ec2:Vpc default-vpc read | ||
Outputs: | ||
url: "218ffe37-e8023b7-1429118690.us-east-1.elb.amazonaws.com" | ||
Resources: | ||
+ 34 created | ||
Duration: 3m30s | ||
Permalink: https://app.pulumi.com/acmecorp/aws-ts-hello-fargate/dev/updates/1 | ||
``` | ||
|
||
4. At this point, your app is running! The URL was published so it's easy to interact with: | ||
|
||
```bash | ||
$ curl http:https://$(pulumi stack output url) | ||
<h3>Hello World!</h3> | ||
<b>Hostname:</b> ip-172-31-39-18.ec2.internal<br/> | ||
<b>Visits:</b> <i>cannot connect to Redis, counter disabled</i> | ||
``` | ||
|
||
For more details on how to enable Redis or advanced options, please see the instructions in the | ||
[Docker Getting Started guide](https://docs.docker.com/get-started/part6/). | ||
|
||
6. Once you are done, you can destroy all of the resources, and the stack: | ||
|
||
```bash | ||
$ pulumi destroy | ||
$ pulumi stack rm | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# Use an official Python runtime as a parent image | ||
FROM python:2.7-slim | ||
|
||
# Set the working directory to /app | ||
WORKDIR /app | ||
|
||
# Copy the current directory contents into the container at /app | ||
COPY . /app | ||
|
||
# Install any needed packages specified in requirements.txt | ||
RUN pip install --trusted-host pypi.python.org -r requirements.txt | ||
|
||
# Make port 80 available to the world outside this container | ||
EXPOSE 80 | ||
|
||
# Define environment variable | ||
ENV NAME World | ||
|
||
# Run app.py when the container launches | ||
CMD ["python", "app.py"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
from flask import Flask | ||
from redis import Redis, RedisError | ||
import os | ||
import socket | ||
|
||
# Connect to Redis | ||
redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2) | ||
|
||
app = Flask(__name__) | ||
|
||
@app.route("/") | ||
def hello(): | ||
try: | ||
visits = redis.incr("counter") | ||
except RedisError: | ||
visits = "<i>cannot connect to Redis, counter disabled</i>" | ||
|
||
html = "<h3>Hello {name}!</h3>" \ | ||
"<b>Hostname:</b> {hostname}<br/>" \ | ||
"<b>Visits:</b> {visits}" | ||
return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits) | ||
|
||
if __name__ == "__main__": | ||
app.run(host='0.0.0.0', port=80) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
Flask | ||
Redis |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import * as awsx from "@pulumi/awsx"; | ||
|
||
// Step 1: Create an ECS Fargate cluster. | ||
const cluster = new awsx.ecs.Cluster("cluster"); | ||
|
||
// Step 2: Define the Networking for our service. | ||
const alb = new awsx.elasticloadbalancingv2.ApplicationLoadBalancer( | ||
"net-lb", { external: true, securityGroups: cluster.securityGroups }); | ||
const web = alb.createListener("web", { port: 80, external: true }); | ||
|
||
// Step 3: Build and publish a Docker image to a private ECR registry. | ||
const img = awsx.ecs.Image.fromPath("app-img", "./app"); | ||
|
||
// Step 4: Create a Fargate service task that can scale out. | ||
const appService = new awsx.ecs.FargateService("app-svc", { | ||
cluster, | ||
taskDefinitionArgs: { | ||
container: { | ||
image: img, | ||
cpu: 102 /*10% of 1024*/, | ||
memory: 50 /*MB*/, | ||
portMappings: [ web ], | ||
}, | ||
}, | ||
desiredCount: 5, | ||
}); | ||
|
||
// Step 5: Export the Internet address for the service. | ||
export const url = web.endpoint.hostname; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{ | ||
"name": "aws-typescript", | ||
"devDependencies": { | ||
"@types/node": "latest" | ||
}, | ||
"dependencies": { | ||
"@pulumi/aws": "latest", | ||
"@pulumi/awsx": "^0.18.3", | ||
"@pulumi/docker": "^0.17.0", | ||
"@pulumi/pulumi": "latest" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
{ | ||
"compilerOptions": { | ||
"outDir": "bin", | ||
"target": "es6", | ||
"lib": [ | ||
"es6" | ||
], | ||
"module": "commonjs", | ||
"moduleResolution": "node", | ||
"sourceMap": true, | ||
"experimentalDecorators": true, | ||
"pretty": true, | ||
"noFallthroughCasesInSwitch": true, | ||
"noImplicitAny": true, | ||
"noImplicitReturns": true, | ||
"forceConsistentCasingInFileNames": true, | ||
"strictNullChecks": true | ||
}, | ||
"files": [ | ||
"index.ts" | ||
] | ||
} |