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.
Adding aws-py-fargate example (pulumi#552)
- Loading branch information
Showing
5 changed files
with
264 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 @@ | ||
*.pyc | ||
venv/ |
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-py-fargate | ||
description: A container running in AWS ECS Fargate, using Python infrastructure as code | ||
runtime: python |
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,148 @@ | ||
[![Deploy](https://get.pulumi.com/new/button.svg)](https://app.pulumi.com/new) | ||
|
||
# NGINX on AWS ECS Fargate using Python | ||
|
||
This example shows authoring Infrastructure as Code in Python. It | ||
provisions a full [Amazon Elastic Container Service (ECS) "Fargate"](https://aws.amazon.com/ecs) cluster and | ||
related infrastructure, running a load-balanced NGINX web server accessible over the Internet on port 80. | ||
This example is inspired by [Docker's Getting Started Tutorial](https://docs.docker.com/get-started/). | ||
|
||
## Prerequisites | ||
|
||
* [Install Pulumi](https://www.pulumi.com/docs/get-started/install/) | ||
* [Configure Pulumi to Use AWS](https://www.pulumi.com/docs/intro/cloud-providers/aws/setup/) (if your AWS CLI | ||
is configured, this will just work) | ||
|
||
## Running the Example | ||
|
||
Clone this repo and `cd` into it. | ||
|
||
Next, to deploy the application and its infrastructure, follow these steps: | ||
|
||
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. Create a Python virtualenv, activate it, and install dependencies: | ||
|
||
This installs the dependent packages [needed](https://www.pulumi.com/docs/intro/concepts/how-pulumi-works/) for our Pulumi program. | ||
|
||
``` | ||
$ virtualenv -p python3 venv | ||
$ source venv/bin/activate | ||
$ pip3 install -r requirements.txt | ||
``` | ||
|
||
4. 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-py-fargate-dev created | ||
+ ├─ aws:ecs:Cluster cluster created | ||
+ ├─ aws:ec2:SecurityGroup web-secgrp created | ||
+ ├─ aws:iam:Role task-exec-role created | ||
+ ├─ aws:lb:TargetGroup app-tg created | ||
+ ├─ aws:ecs:TaskDefinition app-task created | ||
+ ├─ aws:iam:RolePolicyAttachment task-exec-policy created | ||
+ ├─ aws:lb:LoadBalancer app-lb created | ||
+ ├─ aws:lb:Listener web created | ||
+ └─ aws:ecs:Service app-svc created | ||
Outputs: | ||
url: "app-lb-ad43707-1433933240.us-west-2.elb.amazonaws.com" | ||
Resources: | ||
+ 10 created | ||
Duration: 2m56s | ||
Permalink: https://app.pulumi.com/acmecorp/aws-python-fargate/dev/updates/1 | ||
``` | ||
|
||
Notice that the automatically assigned load-balancer URL is printed as a stack output. | ||
|
||
6. At this point, your app is running -- let's curl it. The CLI makes it easy to grab the URL: | ||
|
||
```bash | ||
$ curl http:https://$(pulumi stack output url) | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<title>Welcome to nginx!</title> | ||
<style> | ||
body { | ||
width: 35em; | ||
margin: 0 auto; | ||
font-family: Tahoma, Verdana, Arial, sans-serif; | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
<h1>Welcome to nginx!</h1> | ||
<p>If you see this page, the nginx web server is successfully installed and | ||
working. Further configuration is required.</p> | ||
|
||
<p>For online documentation and support please refer to | ||
<a href="http:https://nginx.org/">nginx.org</a>.<br/> | ||
Commercial support is available at | ||
<a href="http:https://nginx.com/">nginx.com</a>.</p> | ||
|
||
<p><em>Thank you for using nginx.</em></p> | ||
</body> | ||
</html> | ||
``` | ||
|
||
**Please Note**: It may take a few minutes for the app to start up. Until that point, you may receive a 503 error response code. | ||
|
||
7. Try making some changes, and rerunning `pulumi up`. For example, let's scale up to 3 instances: | ||
|
||
Running `pulumi up` will show you the delta and then, after confirming, will deploy just those changes: | ||
|
||
```bash | ||
$ pulumi up | ||
``` | ||
|
||
Notice that `pulumi up` redeploys just the parts of the application/infrastructure that you've edited. | ||
|
||
``` | ||
Updating (dev): | ||
Type Name Status Info | ||
pulumi:pulumi:Stack aws-py-fargate-dev | ||
~ └─ aws:ecs:Service app-svc updated [diff: ~desiredCount] | ||
Outputs: | ||
url: "app-lb-ad43707-1433933240.us-west-2.elb.amazonaws.com" | ||
Resources: | ||
~ 1 updated | ||
9 unchanged | ||
Duration: 14s | ||
Permalink: https://app.pulumi.com/acmecorp/aws-python-fargate/dev/updates/2 | ||
``` | ||
|
||
8. 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,109 @@ | ||
from pulumi import export, ResourceOptions | ||
import pulumi_aws as aws | ||
import json | ||
|
||
# Create an ECS cluster to run a container-based service. | ||
cluster = aws.ecs.Cluster('cluster') | ||
|
||
# Read back the default VPC and public subnets, which we will use. | ||
default_vpc = aws.ec2.get_vpc(default='true') | ||
default_vpc_subnets = aws.ec2.get_subnet_ids(vpc_id=default_vpc.id) | ||
|
||
# Create a SecurityGroup that permits HTTP ingress and unrestricted egress. | ||
group = aws.ec2.SecurityGroup('web-secgrp', | ||
vpc_id=default_vpc.id, | ||
description='Enable HTTP access', | ||
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'], | ||
}] | ||
) | ||
|
||
# Create a load balancer to listen for HTTP traffic on port 80. | ||
alb = aws.lb.LoadBalancer('app-lb', | ||
security_groups=[group.id], | ||
subnets=default_vpc_subnets.ids | ||
) | ||
|
||
atg = aws.lb.TargetGroup('app-tg', | ||
port=80, | ||
protocol='HTTP', | ||
target_type='ip', | ||
vpc_id=default_vpc.id | ||
) | ||
|
||
wl = aws.lb.Listener('web', | ||
load_balancer_arn=alb.arn, | ||
port=80, | ||
default_actions=[{ | ||
'type': 'forward', | ||
'target_group_arn': atg.arn | ||
}] | ||
) | ||
|
||
# Create an IAM role that can be used by our service's task. | ||
role = aws.iam.Role('task-exec-role', | ||
assume_role_policy=json.dumps({ | ||
'Version': '2008-10-17', | ||
'Statement': [{ | ||
'Sid': '', | ||
'Effect': 'Allow', | ||
'Principal': { | ||
'Service': 'ecs-tasks.amazonaws.com' | ||
}, | ||
'Action': 'sts:AssumeRole', | ||
}] | ||
}) | ||
) | ||
|
||
rpa = aws.iam.RolePolicyAttachment('task-exec-policy', | ||
role=role.name, | ||
policy_arn='arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy' | ||
) | ||
|
||
# Spin up a load balanced service running our container image. | ||
task_definition = aws.ecs.TaskDefinition('app-task', | ||
family='fargate-task-definition', | ||
cpu='256', | ||
memory='512', | ||
network_mode='awsvpc', | ||
requires_compatibilities=['FARGATE'], | ||
execution_role_arn=role.arn, | ||
container_definitions=json.dumps([{ | ||
'name': 'my-app', | ||
'image': 'nginx', | ||
'portMappings': [{ | ||
'containerPort': 80, | ||
'hostPort': 80, | ||
'protocol': 'tcp' | ||
}] | ||
}]) | ||
) | ||
|
||
service = aws.ecs.Service('app-svc', | ||
cluster=cluster.arn, | ||
desired_count=3, | ||
launch_type='FARGATE', | ||
task_definition=task_definition.arn, | ||
network_configuration={ | ||
'assign_public_ip': 'true', | ||
'subnets': default_vpc_subnets.ids, | ||
'security_groups': [group.id] | ||
}, | ||
load_balancers=[{ | ||
'target_group_arn': atg.arn, | ||
'container_name': 'my-app', | ||
'container_port': 80 | ||
}], | ||
opts=ResourceOptions(depends_on=[wl]), | ||
) | ||
|
||
export('url', alb.dns_name) |
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 @@ | ||
pulumi>=1.0.0 | ||
pulumi-aws>=1.0.0 |