Skip to content
This repository was archived by the owner on Nov 4, 2022. It is now read-only.

Commit 415f757

Browse files
authored
Merge pull request #14 from aws-samples/dev
Release v2.0.1
2 parents 3e3ded2 + b616bcd commit 415f757

File tree

17 files changed

+198
-89
lines changed

17 files changed

+198
-89
lines changed

workshop/content/buildpipe/cdkinit/_index.en.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ date = 2019-11-01T15:26:09-07:00
44
weight = 21
55
+++
66

7-
First of all, install the CDK CLI by running the following command from your terminal.
7+
## Install the latest CDK
8+
9+
If you are using Cloud9, the CDK is already pre-installed but it will likely be a few versions old. Run the following commands from the Cloud9 terminal to remove your current version and install the latest one:
810
```
11+
npm uninstall -g aws-cdk
912
npm install -g aws-cdk
1013
```
1114

workshop/content/canaries/rollbacks/faketraffic/_index.en.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ In your terminal, run the following command to invoke the Lambda function:
1010

1111
```
1212
aws lambda invoke --function-name \
13-
$(aws lambda list-functions | jq -r .Functions[0].FunctionName):live \
13+
$(aws lambda list-functions | jq -r -c '.Functions[] | select( .FunctionName | contains("sam-app-HelloWorldFunction")).FunctionName'):live \
1414
--payload '{}' \
1515
response.json
1616
```
@@ -34,7 +34,7 @@ counter=1
3434
while [ $counter -le 15 ]
3535
do
3636
aws lambda invoke --function-name \
37-
$(aws lambda list-functions | jq -r .Functions[0].FunctionName):live \
37+
$(aws lambda list-functions | jq -r -c '.Functions[] | select( .FunctionName | contains("sam-app-HelloWorldFunction")).FunctionName'):live \
3838
--payload '{}' \
3939
response.json
4040
sleep 1

workshop/content/crossaccount/_index.en.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
title = "Cross Account Deployments"
33
date = 2019-10-02T16:10:44-07:00
44
weight = 40
5-
chapter = true
5+
chapter = false
66
draft = true
77
hidden = true
88
pre = "<b>6. </b>"
99
+++
1010
# Cross Account Deployments
1111

12-
Cross-account deployments are useful for customers who separate their environments (Dev, Test, Prod) into different AWS accounts. In this chapter you will learn how to deploy across multiple accounts using AWS Code Pipeline.
12+
Cross-account deployments are useful for customers who separate their environments (Dev, Test, Prod) into different AWS accounts. In this chapter you will learn how to deploy a Serverless application across multiple accounts using Code Pipeline.
1313

14-
![DevWorkflow](/images/cross-account-chapter.png)
14+
![DevWorkflow](/images/chapter6/cross-account-chapter.png)

workshop/content/crossaccount/artifactstore/_index.en.md

Lines changed: 0 additions & 75 deletions
This file was deleted.
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
+++
2+
title = "CDK prod environment"
3+
date = 2019-11-11T14:46:02-08:00
4+
weight = 35
5+
draft = true
6+
hidden = true
7+
+++
8+
9+
Before we define any resources in the stack, we need to configure the CDK project to deploy this stack in the Production account. For this, the CDK has the concept of [Environments](https://docs.aws.amazon.com/cdk/latest/guide/environments.html), which allows you to deploy Stacks in different AWS accounts from within the same CDK project.
10+
11+
Open the file `bin/pipeline.ts` and replace its content with the following snippet:
12+
13+
{{< highlight js "hl_lines=11 17" >}}
14+
#!/usr/bin/env node
15+
import 'source-map-support/register';
16+
import * as cdk from '@aws-cdk/core';
17+
import { PipelineStack } from '../lib/pipeline-stack';
18+
import { ProdIAMStack } from '../lib/prod-iam-stack';
19+
20+
const app = new cdk.App();
21+
22+
new PipelineStack(app, 'sam-app-cicd', {
23+
env: {
24+
account: '0123456789', // dev account
25+
}
26+
});
27+
28+
new ProdIAMStack(app, 'sam-app-iam-cross-account', {
29+
env: {
30+
account: '9876543210', // prod account
31+
}
32+
});
33+
{{< / highlight >}}
34+
35+
**NOTE**: Replace the account IDs corresponding to your dev and production AWS accounts.
36+
37+
{{% notice tip %}}
38+
The command `aws sts get-caller-identity` is an easy way to get your AWS Account ID. You can also check here for other forms to find it: https://docs.aws.amazon.com/IAM/latest/UserGuide/console_account-alias.html.
39+
{{% /notice%}}
40+
41+
### Test deployment
42+
43+
```
44+
cd ~/environment/sam-app/pipeline
45+
npm run build
46+
cdk deploy sam-app-iam-cross-account --profile prod
47+
```
48+
49+
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
+++
2+
title = "Cross account roles"
3+
date = 2019-11-11T14:46:02-08:00
4+
weight = 40
5+
draft = true
6+
hidden = true
7+
+++
8+
9+
Now that we have verified that we can deploy an empty stack to production, lets create the actual cross account roles in the `lib/prod-iam-stack.ts` file we created earlier. Add the following content to the file:
10+
11+
{{< highlight js "hl_lines=26" >}}
12+
import * as cdk from '@aws-cdk/core';
13+
import iam = require('@aws-cdk/aws-iam');
14+
15+
export class ProdIAMStack extends cdk.Stack {
16+
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
17+
super(scope, id, props);
18+
19+
/**
20+
* IAM Deployer Role. Will be used to deploy
21+
* the serverless app. Needs admin permissions.
22+
*/
23+
const deployerRole = new iam.Role(this, 'DeployerRole', {
24+
assumedBy: new iam.ServicePrincipal('cloudformation.amazonaws.com')
25+
});
26+
27+
deployerRole.addManagedPolicy(
28+
iam.ManagedPolicy.fromAwsManagedPolicyName("AdministratorAccess")
29+
);
30+
31+
/**
32+
* IAM Cross Account Access Role. Will be assumed by
33+
* the CodePipeline in the dev account, needs permissions
34+
* to pass the Deployer role defined above.
35+
*/
36+
const crossAccountRole = new iam.Role(this, 'CrossAccountRole', {
37+
assumedBy: new iam.AccountPrincipal("REPLACE ME"), // replace with dev account id
38+
});
39+
40+
// Needs CloudFormation permissions
41+
crossAccountRole.addManagedPolicy(
42+
iam.ManagedPolicy.fromAwsManagedPolicyName("AWSCloudFormationFullAccess")
43+
);
44+
45+
// Needs permissions to pass the deployer role defined above
46+
crossAccountRole.addToPolicy(new iam.PolicyStatement({
47+
actions: ['iam:PassRole'],
48+
resources: [deployerRole.roleArn]
49+
}));
50+
51+
// Needs S3 permissions to access artifacts in the DEV account
52+
crossAccountRole.addToPolicy(new iam.PolicyStatement({
53+
actions: ['s3:GetObject'],
54+
resources: ['*']
55+
}));
56+
57+
// Needs KMS permissions to decrypt objects in the DEV account
58+
crossAccountRole.addToPolicy(new iam.PolicyStatement({
59+
actions: ['kms:Decrypt'],
60+
resources: ['*']
61+
}));
62+
63+
/**
64+
* Outputs
65+
*/
66+
new cdk.CfnOutput(this, 'ProdCrossAccountRoleArn', {
67+
value: crossAccountRole.roleArn,
68+
});
69+
70+
new cdk.CfnOutput(this, 'DeployerRoleArn', {
71+
value: deployerRole.roleArn,
72+
});
73+
74+
}
75+
}
76+
{{< / highlight >}}
77+
78+
**NOTE:** Replace the highlighted line with the corresponding DEV account id.
79+
80+
### Deploy stack
81+
82+
```
83+
npm run build
84+
cdk deploy sam-app-iam-cross-account --profile prod
85+
```

workshop/content/crossaccount/howitworks/_index.en.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
+++
2-
title = "How does it work"
2+
title = "How it works"
33
date = 2019-11-11T14:46:02-08:00
44
weight = 20
55
draft = true
@@ -8,15 +8,15 @@ hidden = true
88

99
Before jumping to the implementation, we need to understand the different pieces that allow Code Pipeline to deploy across a different account. The following diagram shows a zoomed-in view of the services and roles involved in this process.
1010

11-
![CrossAccountDeploy](/images/cross-account-deploy.png)
11+
![CrossAccountDeploy](/images/chapter6/cross-account-deploy.png)
1212

1313
#### Explanation
1414

15-
The diagram above illustrates what happens when CodePipeline begins a deployment to the Production account. The first step is to assume the **IAM Pipeline Role** that exists in the Production account; This is possible because the role has a Trust Policy that allows the Development account to assume it. The second step is CodePipeline uses that role to trigger a deployment in CloudFormation by passing the **IAM Deployer Role**. This action is called [PassRole](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_passrole.html) and is needed for CloudFormation to create resources on your behalf. Finally, as you learned in previous chapters, CloudFormation gets the deployment artifacts from S3 and decrypts them by using the KMS Customer Managed Key.
15+
The diagram above illustrates what happens when CodePipeline begins a deployment to the Production account. The first step is to assume the **IAM Cross Account Role** that exists in the Production account; This is possible because the role has a Trust Policy that allows the Dev account to assume it. The second step is CodePipeline uses that role to trigger a deployment in CloudFormation by passing the **IAM Deployer Role**. This action is called [PassRole](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_passrole.html) and is needed for CloudFormation to create resources on your behalf. Finally, as you learned in previous chapters, CloudFormation gets the deployment artifacts from S3 and decrypts them by using the KMS Customer Managed Key.
1616

1717
#### Why encrypt the artifacts?
1818

19-
AWS CodePipeline *always* stores artifacts on S3 with encryption enabled and there is no way to disable it. The default behavior is to use the AWS Managed Key to encrypt them, but this approach doesn't work for granting access to S3 buckets across accounts. Therefore you [3] must create a KMS Customer Master Key and then give the IAM role in the Production account permissions to use it to decrypt the artifacts.
19+
AWS CodePipeline *always* stores artifacts on S3 with encryption-at-rest enabled and there is no way to disable it. The default behavior is to use the AWS Managed Key to encrypt them, but this approach doesn't work for granting access to S3 buckets across accounts. Therefore you [3] must create a KMS Customer Master Key and then give the IAM role in the Production account permissions to use it to decrypt the artifacts.
2020

2121
#### Additional reading
2222

workshop/content/crossaccount/intro/_index.en.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ hidden = true
88

99
### Environment separation
1010

11-
Separating environments (Dev, Test, Prod) into different AWS accounts is a very common practice among AWS customers. And the main motivation being the ability to give developers full administrative access to the Dev environment, so that they can innovate and iterate quickly, but give them _limited_ access to higher environments, like Production. There are other motivations as well, like managing [AWS Service Quotas](https://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html) separately and having billing details broken down per environment.
11+
Separating environments into different AWS accounts its a common practice among AWS customers. The most basic form of separation is to have 2 AWS accounts, one for non-production environments and one dedicated to Production. This gives developers the ability to have full admin permissions in the Dev environment, to iterate and experiment quickly, and have _limited_ permissions in the Production account.
1212

13-
The following diagram illustrates a simple account setup that many customers start with. And we will also be using it throughout this chapter. But the concepts that you will learn here can be applied to any form of multi-account setup.
13+
The following diagram illustrates a simple setup of 2 accounts, one for Dev and one for Prod. This is the setup we will be using as reference throughout this chapter, but the concepts learned can be applied to any form of multi-account setup.
1414

15-
![EnvironmentSeparation](/images/environment-separation.png)
15+
![EnvironmentSeparation](/images/chapter6/environment-separation.png)
1616

17-
As you can tell from the diagram, the Dev account hosts the Code Pipeline, Artifacts Bucket and the Code Repository. The CodePipeline then deploys across the Production account using an [assumed role](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html).
17+
As you can see from the diagram, the Dev account hosts the Code Pipeline, S3 bucket for artifacts and the code repository. The pipeline then deploys across the Production account using IAM [assumed roles](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html).
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
+++
2+
title = "Create Prod credentials"
3+
date = 2019-11-11T14:46:02-08:00
4+
weight = 22
5+
draft = true
6+
hidden = true
7+
+++
8+
9+
In this chapter you will be deploying to both, the DEV account and the PROD account from your Cloud9 environment, for that to work you need to have valid IAM credentials and profiles configured in your ~/.aws/credentials file.
10+
11+
**TODO: ADD STEPS TO CONFIGURE CREDENTIALS**
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
+++
2+
title = "Prod account setup"
3+
date = 2019-11-11T14:46:02-08:00
4+
weight = 30
5+
draft = true
6+
hidden = true
7+
+++
8+
9+
Let's get started creating the necessary IAM roles in the Production account to grant cross account access. We will do this as a separate stack within the same CDK project created in Chapter 4.
10+
11+
Run the following command to create a new file named _prod-iam-stack.ts_ inside the _lib_ drectory.
12+
13+
```
14+
cd ~/environment/sam-app/pipeline
15+
touch lib/prod-iam-stack.ts
16+
```
17+
18+
Paste to following content inside the file:
19+
20+
```js
21+
import * as cdk from '@aws-cdk/core';
22+
import iam = require('@aws-cdk/aws-iam');
23+
24+
export class ProdIAMStack extends cdk.Stack {
25+
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
26+
super(scope, id, props);
27+
28+
// Resource definition goes here
29+
}
30+
}
31+
```
32+
33+
It should look like this:
34+
35+
![NewIamProdStack](/images/chapter6/new-file-prod-stack.png)
36+

0 commit comments

Comments
 (0)