-
Notifications
You must be signed in to change notification settings - Fork 4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(docs): Updated examples topic to use ECS L2 construct #1195
Changes from 6 commits
1caf425
8c8be92
c6bc455
f342d3b
29dfa0b
5cb3d90
908f28a
b5b3dd4
9105f97
6b36eb7
8e783ea
675b8a8
0f8713b
307b34a
aa359ac
d0e2aa2
34275d9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,205 +14,175 @@ | |
|cdk| Examples | ||
############## | ||
|
||
This topic contains some usage examples to help you get started understanding | ||
the |cdk|. | ||
This topic contains some examples to help you get started using some of the advanced constructs | ||
offered by the |cdk|. | ||
|
||
.. We'll include this if we ever implement DeploymentPipeline | ||
_multiple_stacks_example: | ||
.. _creating_ecs_l2_example: | ||
|
||
Creating an App with Multiple Stacks | ||
==================================== | ||
Creating an |ECS| Construct | ||
=========================== | ||
|
||
The following example creates the following stacks and one deployment pipeline: | ||
|ECSlong| (|ECS|) is a highly scalable, fast, container management service | ||
that makes it easy to run, stop, and manage Docker containers on a cluster. | ||
You can host your cluster on a serverless infrastructure that is managed by | ||
|ECS| by launching your services or tasks using the Fargate launch type. | ||
For more control you can host your tasks on a cluster of | ||
|EC2long| (|EC2|) instances that you manage by using the EC2 launch type. | ||
|
||
- **Dev** uses the default environment | ||
- **PreProd** in the **us-west-2** Region | ||
- **NAEast** in the **us-east-1** Region | ||
- **NAWest** in the **us-west-2** Region | ||
- **EU** in the **eu-west-1** Region | ||
- **DeploymentPipeline** in the **us-east-1** Region | ||
Since |ECS| can be used with a number of AWS services, | ||
you should understand how the |ECS| construct that we use in this example | ||
gives you a leg up on using AWS services: | ||
|
||
Implement the class **MyStack** in the *my-stack* sub-folder, | ||
that extends the |stack-class| class | ||
(this is the same code as shown in the :doc:`concepts` topic). | ||
* Automatic security group opening for load balancers | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These are not sentences, maybe rephrase to a list of the form "it will open up ..." etc. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep. I wrote these based on some notes and forgot to re-visit. |
||
* Automatic ordering dependency between service and load balancer attaching to a target group | ||
* Automatic userdata configuration on auto-scaling group | ||
* Early validation of parameter combinations, | ||
which exposes |CFN| issues earlier, | ||
thus saving you deployment time | ||
* Automatically adds permissions for |ECR| if you use an image from |ECR| | ||
* Convenient API for autoscaling | ||
* Asset support, so that you can deploy source from your machine to |ECS| in one step | ||
|
||
code-block:: js | ||
.. _creating_ecs_l2_example_1: | ||
|
||
import { Stack, StackProps } from '@aws-cdk/cdk' | ||
Step 1: Create the Directory and Initialze the |cdk| | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typo. Wouldn't capitalize Directory and Initialize here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is AWS docs style. We capitalize pretty much everything but articles (the, and, etc.). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Still typo |
||
---------------------------------------------------- | ||
|
||
interface MyStackProps extends StackProps { | ||
encryptedStorage: boolean; | ||
} | ||
Let's start with creating a new directory to hold our |cdk| code | ||
and create a new app in that directory. | ||
|
||
export class MyStack extends Stack { | ||
constructor(parent: Construct, name: string, props?: MyStackProps) { | ||
super(parent, name, props); | ||
.. code-block:: sh | ||
|
||
new MyStorageLayer(this, 'Storage', { encryptedStorage: props.encryptedStorage }); | ||
new MyControlPlane(this, 'CPlane'); | ||
new MyDataPlane(this, 'DPlane'); | ||
} | ||
} | ||
mkdir MyEcsConstruct | ||
cd MyEcsConstruct | ||
|
||
Implement the class **DeploymentPipeline** in the *my-deployment* sub-folder, | ||
that extends the |stack-class| class | ||
(this is the same code as shown in the :doc:`concepts` topic). | ||
.. tabs:: | ||
|
||
code-block:: js | ||
.. group-tab:: TypeScript | ||
|
||
Use **MyStack** and **DeploymentPipeline** to create the stacks and deployment pipeline. | ||
.. code-block:: sh | ||
|
||
code-block:: js | ||
cdk init --language typescript | ||
|
||
import { App } from '@aws-cdk/cdk' | ||
import { MyStack } from './my-stack' | ||
import { DeploymentPipeline } from './my-deployment' | ||
Update *my_ecs_construct.ts* in the *bin* directory to only contain the following code: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will have gotten changed to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed the typo (sheesh); I just tested There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know. The change is not released yet. That's why I wrote:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I removed this part as the template has changed. |
||
|
||
const app = new App(); | ||
.. code-block:: ts | ||
|
||
// Use the default environment | ||
new MyStack(app, { name: 'Dev' }); | ||
import cdk = require('@aws-cdk/cdk'); | ||
|
||
// Pre-production stack | ||
const preProd = new MyStack(app, { | ||
name: 'PreProd', | ||
env: { region: 'us-west-2' }, | ||
preProd: true | ||
}); | ||
class MyEcsConstructStack extends cdk.Stack { | ||
constructor(parent: cdk.App, name: string, props?: cdk.StackProps) { | ||
super(parent, name, props); | ||
|
||
// Production stacks | ||
const prod = [ | ||
new MyStack(app, { | ||
name: 'NAEast', | ||
env: { region: 'us-east-1' } | ||
}), | ||
|
||
new MyStack(app, { | ||
name: 'NAWest', | ||
env: { region: 'us-west-2' } | ||
}), | ||
} | ||
} | ||
|
||
new MyStack(app, { | ||
name: 'EU', | ||
env: { region: 'eu-west-1' }, | ||
encryptedStorage: true | ||
}) | ||
] | ||
const app = new cdk.App(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In fact these lines will also be gone. These lines will live in a file in the Here's the new version of the app template: https://github.com/awslabs/aws-cdk/tree/master/packages/aws-cdk/lib/init-templates/app/typescript |
||
|
||
// CI/CD pipeline stack | ||
new DeploymentPipeline(app, { | ||
env: { region: 'us-east-1' }, | ||
strategy: DeploymentStrategy.Waved, | ||
preProdStages: [ preProd ], | ||
prodStages: prod | ||
}); | ||
new MyEcsConstructStack(app, 'MyEcsConstructStack'); | ||
|
||
app.run(); | ||
app.run(); | ||
|
||
.. _dynamodb_example: | ||
Save it and make sure it builds and creates an empty stack. | ||
|
||
Creating a |DDB| Table | ||
====================== | ||
.. code-block:: sh | ||
|
||
The following example creates a | ||
|DDB| table with the partition key **Alias** | ||
and sort key **Timestamp**. | ||
npm run build | ||
cdk synth | ||
|
||
.. code-block:: js | ||
You should see a stack like the following, | ||
where CDK-VERSION is the version of the CDK. | ||
|
||
import dynamodb = require('@aws-cdk/aws-dynamodb'); | ||
import cdk = require('@aws-cdk/cdk'); | ||
.. code-block:: sh | ||
|
||
class MyStack extends cdk.Stack { | ||
constructor(parent: cdk.App, name: string, props?: cdk.StackProps) { | ||
super(parent, name, props); | ||
Resources: | ||
CDKMetadata: | ||
Type: 'AWS::CDK::Metadata' | ||
Properties: | ||
Modules: @aws-cdk/cdk=CDK-VERSION,@aws-cdk/cx-api=CDK-VERSION,my_ecs_construct=0.1.0 | ||
|
||
const table = new dynamodb.Table(this, 'Table', { | ||
tableName: 'MyAppTable', | ||
readCapacity: 5, | ||
writeCapacity: 5 | ||
}); | ||
.. _creating_ecs_l2_example_2: | ||
|
||
table.addPartitionKey({ name: 'Alias', type: dynamodb.AttributeType.String }); | ||
table.addSortKey({ name: 'Timestamp', type: dynamodb.AttributeType.String }); | ||
} | ||
} | ||
Step 2: Add the |EC2| and |ECS| Packages | ||
---------------------------------------- | ||
|
||
const app = new cdk.App(); | ||
Install support for |EC2| and |ECS|. | ||
|
||
new MyStack(app, 'MyStack'); | ||
.. tabs:: | ||
|
||
app.run(); | ||
.. group-tab:: TypeScript | ||
|
||
.. _creating_rds_example: | ||
.. code-block:: sh | ||
|
||
Creating an |RDS| Database | ||
========================== | ||
npm install @aws-cdk/aws-ec2 @aws-cdk/aws-ecs | ||
|
||
The following example creates the Aurora database **MyAuroraDatabase**. | ||
.. _creating_ecs_l2_example_3: | ||
|
||
.. code-block:: js | ||
Step 3: Create a Fargate Service | ||
-------------------------------- | ||
|
||
import ec2 = require('@aws-cdk/aws-ec2'); | ||
import rds = require('@aws-cdk/aws-rds'); | ||
import cdk = require('@aws-cdk/cdk'); | ||
There are two different ways of creating a serverless infrastructure with |ECS|: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would write "two different ways of running your container tasks" There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok |
||
|
||
class MyStack extends cdk.Stack { | ||
constructor(parent: cdk.App, name: string, props?: cdk.StackProps) { | ||
super(parent, name, props); | ||
- Using the **Fargate** launch type, where |ECS| manages your cluster resources | ||
- Using the **EC2** launch type, where you manage your cluster resources | ||
|
||
const vpc = new ec2.VpcNetwork(this, 'VPC'); | ||
This example creates a Fargate service, | ||
which requires a VPC, a cluster, a task definition, and a security group. | ||
Later on we'll show you how to launch an EC2 service. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. how to launch services on EC2 instances you manage yourself There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok |
||
|
||
new rds.DatabaseCluster(this, 'MyRdsDb', { | ||
defaultDatabaseName: 'MyAuroraDatabase', | ||
masterUser: { | ||
username: 'admin', | ||
password: '123456' | ||
}, | ||
engine: rds.DatabaseClusterEngine.Aurora, | ||
instanceProps: { | ||
instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.Burstable2, ec2.InstanceSize.Small), | ||
vpc: vpc, | ||
vpcPlacement: { | ||
subnetsToUse: ec2.SubnetType.Public | ||
} | ||
} | ||
}); | ||
} | ||
} | ||
.. tabs:: | ||
|
||
const app = new cdk.App(); | ||
.. group-tab:: TypeScript | ||
|
||
new MyStack(app, 'MyStack'); | ||
Add the following import statements: | ||
|
||
app.run(); | ||
.. code-block:: typescript | ||
|
||
.. _creating_s3_example: | ||
import ec2 = require('@aws-cdk/aws-ec2'); | ||
import ecs = require('@aws-cdk/aws-ecs'); | ||
|
||
Creating an |S3| Bucket | ||
======================= | ||
Add the following code to the end of the constructor: | ||
|
||
The following example creates the |S3| bucket **MyS3Bucket** with server-side KMS | ||
encryption provided by |S3|. | ||
.. code-block:: typescript | ||
|
||
.. code-block:: js | ||
const vpc = new ec2.VpcNetwork(this, 'MyVpc', { | ||
maxAZs: 2 // Default is all AZs in region | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 3 is actually a better default if we're going to teach people best practices. 2 is just for tests. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok |
||
}); | ||
|
||
import s3 = require('@aws-cdk/aws-s3'); | ||
import cdk = require('@aws-cdk/cdk'); | ||
// Create an ECS cluster | ||
const cluster = new ecs.Cluster(this, 'MyCluster', { | ||
vpc: vpc | ||
}); | ||
|
||
class MyStack extends cdk.Stack { | ||
constructor(parent: cdk.App, name: string, props?: cdk.StackProps) { | ||
super(parent, name, props); | ||
const taskDefinition = new ecs.FargateTaskDefinition(this, 'MyFargateTaskDefinition', { | ||
cpu: '256', // Default | ||
memoryMiB: '2048' // Default is 512 | ||
}); | ||
|
||
new s3.Bucket(this, 'MyBucket', { | ||
bucketName: 'MyS3Bucket', | ||
encryption: s3.BucketEncryption.KmsManaged | ||
}); | ||
} | ||
} | ||
// The task definition must have at least one container. | ||
// Otherwise you cannot synthesize or deploy your app. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It sounds like a constraint if you put it like this. But also, if you don't add a container, WHAT are you even launching? Empty tasks that do nothing? That's not very useful. So I wouldn't call attention to it in this way. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I rewrote the first comment line and removed the second comment line. |
||
taskDefinition.addContainer('MyContainer', { | ||
image: ecs.ContainerImage.fromDockerHub('MyDockerImage') // Required | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe launch |
||
}); | ||
|
||
const app = new cdk.App(); | ||
const securityGroup = new ec2.SecurityGroup(this, 'MySecurityGroup', { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is actually not necessary. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. removed |
||
vpc: vpc | ||
}); | ||
|
||
new MyStack(app, 'MyStack'); | ||
new ecs.FargateService(this, 'MyFargateService', { | ||
taskDefinition: taskDefinition, // Required | ||
cluster: cluster, // Required | ||
desiredCount: 6, // Default is 1 | ||
securityGroup: securityGroup, // Required | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No it's not. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yep |
||
platformVersion: ecs.FargatePlatformVersion.Latest // Default | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't even call attention to this, just leave it out. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
}); | ||
|
||
app.run() | ||
Save it and make sure it builds and creates a stack. | ||
|
||
.. code-block:: sh | ||
|
||
npm run build | ||
cdk synth | ||
|
||
You should see a stack of about 300 lines, so we won't show it here. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wouldn't call it "creating an ECS construct", that implies you're building a reusable thing.
Maybe "Writing an |ECS| CDK app" ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point.