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.
AWS ECS with Container Instances and Automation API (pulumi#845)
Co-authored-by: Justin Van Patten <[email protected]>
- Loading branch information
1 parent
1990689
commit 248d41e
Showing
7 changed files
with
466 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,104 @@ | ||
# Logs | ||
logs | ||
*.log | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
lerna-debug.log* | ||
|
||
# Diagnostic reports (https://nodejs.org/api/report.html) | ||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json | ||
|
||
# Runtime data | ||
pids | ||
*.pid | ||
*.seed | ||
*.pid.lock | ||
|
||
# Directory for instrumented libs generated by jscoverage/JSCover | ||
lib-cov | ||
|
||
# Coverage directory used by tools like istanbul | ||
coverage | ||
*.lcov | ||
|
||
# nyc test coverage | ||
.nyc_output | ||
|
||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) | ||
.grunt | ||
|
||
# Bower dependency directory (https://bower.io/) | ||
bower_components | ||
|
||
# node-waf configuration | ||
.lock-wscript | ||
|
||
# Compiled binary addons (https://nodejs.org/api/addons.html) | ||
build/Release | ||
|
||
# Dependency directories | ||
node_modules/ | ||
jspm_packages/ | ||
|
||
# TypeScript v1 declaration files | ||
typings/ | ||
|
||
# TypeScript cache | ||
*.tsbuildinfo | ||
|
||
# Optional npm cache directory | ||
.npm | ||
|
||
# Optional eslint cache | ||
.eslintcache | ||
|
||
# Microbundle cache | ||
.rpt2_cache/ | ||
.rts2_cache_cjs/ | ||
.rts2_cache_es/ | ||
.rts2_cache_umd/ | ||
|
||
# Optional REPL history | ||
.node_repl_history | ||
|
||
# Output of 'npm pack' | ||
*.tgz | ||
|
||
# Yarn Integrity file | ||
.yarn-integrity | ||
|
||
# dotenv environment variables file | ||
.env | ||
.env.test | ||
|
||
# parcel-bundler cache (https://parceljs.org/) | ||
.cache | ||
|
||
# Next.js build output | ||
.next | ||
|
||
# Nuxt.js build / generate output | ||
.nuxt | ||
dist | ||
|
||
# Gatsby files | ||
.cache/ | ||
# Comment in the public line in if your project uses Gatsby and *not* Next.js | ||
# https://nextjs.org/blog/next-9-1#public-directory-support | ||
# public | ||
|
||
# vuepress build output | ||
.vuepress/dist | ||
|
||
# Serverless directories | ||
.serverless/ | ||
|
||
# FuseBox cache | ||
.fusebox/ | ||
|
||
# DynamoDB Local files | ||
.dynamodb/ | ||
|
||
# TernJS port file | ||
.tern-port |
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,82 @@ | ||
# AWS ECS with Container Instances and Delete Orchestration | ||
|
||
This example demonstrates three use-cases: | ||
|
||
- AWS ECS using Container Instances (Python): A Python Pulumi program that stands up a custom AWS ECS cluster that uses instances instead of fargate for the infrastructure. | ||
- Automation API Orchestration: Destroying this stack without any sort of orchestration will fail due to this issue in the underlying provider: https://github.com/hashicorp/terraform-provider-aws/issues/4852. So, Automation API to the rescue. By orchestrating sizing of the autoscaling group to 0 before the destroy, the destroy is able to complete as expected. | ||
- Automation API cross-language support: Although the automation logic is written in TypeScript, the ECS cluster stack is written in Python. | ||
|
||
## Project Structure | ||
|
||
### `/py-ecs-instance`: | ||
|
||
This is a Pulumi project/stack python program that deploys the following: | ||
|
||
- ECS Cluster using "container instances" instead of Fargate. | ||
- An nginx "hello world" test container and related load balancer and networking. | ||
One can change to this directory and run `pulumi up` and deploy the stack just as would be done with any Pulumi project ... | ||
|
||
But wait, there's more ... | ||
|
||
### `/automation` | ||
|
||
This directory contains the automation api code (`index.ts`) that handles deploying and, more importantly, orchestrating the deletion of the stack to avoid a dependency constraint. | ||
|
||
## How to Use | ||
|
||
To run this example you'll need a few pre-reqs: | ||
|
||
1. A Pulumi CLI installation ([v2.15.6](https://www.pulumi.com/docs/get-started/install/versions/) or later) | ||
2. Python 3.6+ | ||
3. The AWS CLI, with appropriate credentials. | ||
|
||
To run our automation program we just `cd` to the `automation` directory and use `yarn` to run the automation api code. | ||
|
||
```shell | ||
$ yarn install | ||
$ yarn start | ||
yarn run v1.19.1 | ||
$ ./node_modules/ts-node/dist/bin.js index.ts | ||
successfully initialized stack | ||
setting up config | ||
config set | ||
refreshing stack... | ||
Refreshing (dev) | ||
... | ||
refresh complete | ||
updating stack... | ||
Updating (dev) | ||
... | ||
|
||
update summary: | ||
{ | ||
"same": 0, | ||
"update": 16 | ||
} | ||
website url: http:https://load-balancer-xxxxxxxxx.us-east-1.elb.amazonaws.com | ||
``` | ||
|
||
To destroy the stack, we run the automation program with an additional `destroy` argument: | ||
|
||
```shell | ||
$ yarn start destroy | ||
yarn run v1.19.1 | ||
$ ./node_modules/ts-node/dist/bin.js index.ts destroy | ||
successfully initialized stack | ||
setting up config | ||
config set | ||
refreshing stack... | ||
Refreshing (dev) | ||
destroying stack ... | ||
Destroying (dev) | ||
... | ||
@ Destroying ... | ||
... | ||
Resources: | ||
- 16 deleted | ||
|
||
The resources in the stack have been deleted, but the history and configuration associated with the stack are still maintained. | ||
If you want to remove the stack completely, run 'pulumi stack rm dev'. | ||
|
||
stack destroy complete | ||
``` |
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,56 @@ | ||
import { LocalProgramArgs, LocalWorkspace } from "@pulumi/pulumi/x/automation"; | ||
import * as upath from "upath"; | ||
|
||
const process = require("process"); | ||
|
||
const args = process.argv.slice(2); | ||
let destroy = false; | ||
if (args.length > 0 && args[0]) { | ||
destroy = args[0] === "destroy"; | ||
} | ||
|
||
const run = async () => { | ||
|
||
|
||
// Create our stack using a local program | ||
// in the ../fargate directory | ||
const args: LocalProgramArgs = { | ||
stackName: "dev", | ||
workDir: upath.joinSafe(__dirname, "..", "py-ecs-instance"), | ||
}; | ||
const asgSize = "1" | ||
|
||
// create (or select if one already exists) a stack that uses our local program | ||
const stack = await LocalWorkspace.createOrSelectStack(args); | ||
|
||
console.info("successfully initialized stack"); | ||
console.info("setting up config"); | ||
await stack.setConfig("aws:region", { value: "us-east-1" }); | ||
await stack.setConfig("cfg:autoscalingGroupSize", { value: asgSize }); | ||
console.info("config set"); | ||
console.info("refreshing stack..."); | ||
await stack.refresh({ onOutput: console.info }); | ||
console.info("refresh complete"); | ||
|
||
if (destroy) { | ||
// The autoscaling group is sized down to 0 so that there are no instances running. | ||
// This allows the cluster to be deleted. Otherwise, the cluster delete will fail due to the existence of instances. | ||
console.info("resizing autoscaling group size to 0 before destroying the stack ...") | ||
await stack.setConfig("cfg:autoscalingGroupSize", { value: "0" }); | ||
await stack.up({ onOutput: console.info }); | ||
await stack.setConfig("cfg:autoscalingGroupSize", { value: asgSize }); | ||
|
||
console.info("destroying stack..."); | ||
await stack.destroy({onOutput: console.info}); | ||
|
||
console.info("stack destroy complete"); | ||
process.exit(0); | ||
} | ||
|
||
console.info("updating stack..."); | ||
const upRes = await stack.up({ onOutput: console.info }); | ||
console.log(`update summary: \n${JSON.stringify(upRes.summary.resourceChanges, null, 4)}`); | ||
console.log(`website url: ${upRes.outputs.app_url.value}`); | ||
}; | ||
|
||
run().catch(err => console.log(err)); |
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,18 @@ | ||
{ | ||
"name": "automation", | ||
"version": "1.0.0", | ||
"main": "index.ts", | ||
"repository": "github.com/pulumi/automation-api-examples", | ||
"author": "EvanBoyle", | ||
"license": "MIT", | ||
"dependencies": { | ||
"@pulumi/aws": "^3.6.1", | ||
"@pulumi/pulumi": "^2.12.0", | ||
"@types/node": "^14.14.20", | ||
"ts-node": "^9.0.0", | ||
"upath": "^2.0.0" | ||
}, | ||
"scripts": { | ||
"start": "./node_modules/ts-node/dist/bin.js index.ts" | ||
} | ||
} |
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,6 @@ | ||
name: aws-py-ecs-instances-autoapi | ||
description: A container running in AWS ECS Container Instance, using Python infrastructure as code | ||
runtime: | ||
name: python | ||
options: | ||
virtualenv: venv |
Oops, something went wrong.