-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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(assets): surface the CFN Parameters that Assets create #2057
Changes from all commits
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 |
---|---|---|
|
@@ -324,9 +324,69 @@ This package defines the following actions: | |
changes from the people (or system) applying the changes. | ||
* **CloudFormationExecuteChangeSetAction** - Execute a change set prepared previously. | ||
|
||
##### Lambda deployed through CodePipeline | ||
|
||
If you want to deploy your Lambda through CodePipeline, | ||
you need to override the Parameters that are present in the Asset of the Lambda Code. | ||
Note that your Lambda must be in a different Stack than your Pipeline. | ||
The Lambda itself will be deployed, alongside the entire Stack it belongs to, | ||
using a CloudFormation CodePipeline Action. Example: | ||
|
||
```typescript | ||
const lambdaStack = new cdk.Stack(app, 'LambdaStack', { | ||
autoDeploy: false, // to make working with the 2 Stacks easier in the toolkit | ||
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. Change the comment to describe what this does |
||
}); | ||
const lambdaCode = lambda.Code.asset('path/to/directory/or/zip/file'); | ||
const func = new lambda.Function(lambdaStack, 'Lambda', { | ||
code: lambdaCode, | ||
handler: 'index.handler', | ||
runtime: lambda.Runtime.NodeJS810, | ||
}); | ||
// other resources that your Lambda needs, added to the lambdaStack... | ||
|
||
const pipeline = new codepipeline.Pipeline(pipelineStack, 'Pipeline'); | ||
// add the source code repository containing this code to your Pipeline, | ||
// and the source code of the Lambda Function, if they're separate | ||
pipeline.addStage({ | ||
name: 'Source', | ||
actions: [ | ||
// ... | ||
], | ||
}); | ||
// add a build Action to your Pipeline, that calls `cdk synth` on the lambdaStack, | ||
// and saves it to some file, and a separate build for your Lambda source code - if needed | ||
pipeline.addStage({ | ||
name: 'Build', | ||
actions: [ | ||
lambdaBuildAction, | ||
cdkBuildAction, | ||
], | ||
}); | ||
// finally, deploy your Lambda Stack | ||
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. Style: new line before each "//" line |
||
pipeline.addStage({ | ||
name: 'Deploy', | ||
actions: [ | ||
new codepipeline_actions.CloudFormationCreateUpdateStackAction({ | ||
actionName: 'Lambda_CFN_Deploy', | ||
templatePath: cdkBuildAction.outputArtifact.atPath('template.yaml'), | ||
stackName: 'YourDeployStackHere', | ||
adminPermissions: true, | ||
parameterOverrides: { | ||
...lambdaBuildAction.outputArtifact.overrideAsset(lambdaCode.asset), | ||
}, | ||
additionalInputArtifacts: [ | ||
lambdaBuildAction.outputArtifact, | ||
], | ||
}), | ||
], | ||
}); | ||
``` | ||
|
||
#### AWS CodeDeploy | ||
|
||
To use CodeDeploy in a Pipeline: | ||
##### Server deployments | ||
|
||
To use CodeDeploy for EC2/on-premise deployments in a Pipeline: | ||
|
||
```ts | ||
import codedeploy = require('@aws-cdk/aws-codedeploy'); | ||
|
@@ -348,6 +408,35 @@ pipeline.addStage({ | |
}); | ||
``` | ||
|
||
##### Lambda deployments | ||
|
||
To use CodeDeploy for blue-green Lambda deployments in a Pipeline: | ||
|
||
```typescript | ||
const lambdaCode = lambda.Code.asset('path/to/directory/or/zip/file'); | ||
const func = new lambda.Function(lambdaStack, 'Lambda', { | ||
code: lambdaCode, | ||
handler: 'index.handler', | ||
runtime: lambda.Runtime.NodeJS810, | ||
}); | ||
// used to make sure each CDK synthesis produces a different Version | ||
const version = func.newVersion(); | ||
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 sounds weird and scary?... We can't have "cdk synth" produce a different result each time. Is this just temporary until we have #1400? 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's meant to be used in a Pipeline, so I believe that's fine. |
||
const alias = new lambda.Alias(lambdaStack, 'LambdaAlias', { | ||
aliasName: 'Prod', | ||
version, | ||
}); | ||
|
||
new codedeploy.LambdaDeploymentGroup(lambdaStack, 'DeploymentGroup', { | ||
alias, | ||
deploymentConfig: codedeploy.LambdaDeploymentConfig.Linear10PercentEvery1Minute, | ||
}); | ||
``` | ||
|
||
Then, you need to create your Pipeline Stack, | ||
where you will define your Pipeline, | ||
and deploy the `lambdaStack` using a CloudFormation CodePipeline Action | ||
(see above for a complete example). | ||
|
||
#### AWS S3 | ||
|
||
To use an S3 Bucket as a deployment target in CodePipeline: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
import assets = require('@aws-cdk/assets'); | ||
import { Token } from "@aws-cdk/cdk"; | ||
|
||
/** | ||
|
@@ -51,6 +52,13 @@ export class Artifact { | |
public toString() { | ||
return this.artifactName; | ||
} | ||
|
||
public overrideAsset(asset: assets.Asset): { [name: string]: string } { | ||
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. Missing documentation. I am not sure about this name... Reads weird: 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. The word used is But if you prefer |
||
const ret: { [name: string]: string } = {}; | ||
ret[asset.bucketNameParam] = this.bucketName; | ||
ret[asset.objectKeyParam] = this.objectKey; | ||
return ret; | ||
} | ||
} | ||
|
||
/** | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import assets = require('@aws-cdk/assets'); | ||
import cdk = require('@aws-cdk/cdk'); | ||
import { Test } from 'nodeunit'; | ||
import codepipeline = require('../lib'); | ||
|
||
export = { | ||
'CodePipeline Artifacts': { | ||
'can override Assets'(test: Test) { | ||
// given | ||
const stack = new cdk.Stack(); | ||
const asset = new assets.ZipDirectoryAsset(stack, 'MyAsset', { | ||
path: __dirname | ||
}); | ||
|
||
const artifact = new codepipeline.Artifact('MyArtifact'); | ||
|
||
// when | ||
const overrides = stack.node.resolve(artifact.overrideAsset(asset)); | ||
|
||
// then | ||
test.deepEqual(overrides.MyAssetS3Bucket68C9B344, { | ||
'Fn::GetArtifactAtt': ['MyArtifact', 'BucketName'] | ||
}); | ||
|
||
test.deepEqual(overrides.MyAssetS3VersionKey68E1A45D, { | ||
'Fn::GetArtifactAtt': ['MyArtifact', 'ObjectKey'] | ||
}); | ||
|
||
test.done(); | ||
}, | ||
}, | ||
}; |
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.
This section makes me feel that maybe we should merge the README files of aws-codepipeline and aws-codepipeline-actions. It feels artificial to have to jump between the two... What do you think?
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 don't have any philosophical objections to that, I do have one practical concern though: nesting. As you can see, we've reached H5 in the ReadMe for
codepipeline-actions
, and I assume we'll need to increase the nesting of the headings by at least one level if we move them to thecodepipeline
ReadMe.