Skip to content

Commit

Permalink
docs(pipelines): add migration guide (#15696)
Browse files Browse the repository at this point in the history
Add a migration guide for original to modern API.

[Rendered version](https://github.com/aws/aws-cdk/blob/huijbers/pipelines-migration-guide/packages/@aws-cdk/pipelines/ORIGINAL_API.md)

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
rix0rrr authored Jul 22, 2021
1 parent 2e4cfae commit 9022d6f
Show file tree
Hide file tree
Showing 2 changed files with 245 additions and 10 deletions.
183 changes: 180 additions & 3 deletions packages/@aws-cdk/pipelines/ORIGINAL_API.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,185 @@

This document describes the API the CDK Pipelines library originally went into
Developer Preview with. The API has since been reworked, but the original one
left in place because of popular uptake. The original API still works and is
still supported, but the revised one is preferred for future projects.
left in place because of popular adoption. The original API still works and is
still supported, but the revised one is preferred for future projects as it
is more flexible and abstracts more unnecessary details from the user.

## Migrating from the original to the modern API

It's possible to migrate a pipeline in-place from the original to the modern API.
The changes necessary are the following:

### The Pipeline

Replace `new CdkPipeline` with `new CodePipeline`. Some
configuration properties have been changed:

| Old API | New API |
|--------------------------------+------------------------------------------------------------------------------------------------|
| `cloudAssemblyArtifact` | removed |
| `sourceAction` | removed |
| `synthAction` | `synth` |
| `crossAccountKeys` | new default is `false`; specify `crossAccountKeys: true` if you need cross-account deployments |
| `cdkCliVersion` | `cliVersion` |
| `selfMutating` | `selfMutation` |
| `vpc`, `subnetSelection` | `codeBuildDefaults.vpc`, codeBuildDefaults.subnetSelection` |
| `selfMutationBuildSpec` | `selfMutationCodeBuildDefaults.partialBuildSpec` |
| `assetBuildSpec` | `assetPublishingCodeBuildDefaults.partialBuildSpec` |
| `assetPreinstallCommands` | use `assetPublishingCodeBuildDefaults.partialBuildSpec` instead |
| `singlePublisherPerType: true` | `publishAssetsInParallel: false` |
| `supportDockerAssets` | `dockerEnabledForSelfMutation` |

### The synth

As the argument to `synth`, use `new ShellStep` or `new CodeBuildStep`,
depending on whether or not you want to customize the AWS CodeBuild Project that gets generated.

Contrary to `SimpleSynthAction.standardNpmSynth`, you need to specify
all commands necessary to do a full CDK build and synth, so do include
installing dependencies and running the CDK CLI. For example, the old API:

```ts
SimpleSynthAction.standardNpmSynth({
sourceArtifact,
cloudAssemblyArtifact,

// Use this if you need a build step (if you're not using ts-node
// or if you have TypeScript Lambdas that need to be compiled).
buildCommand: 'npm run build',
}),
```

Becomes:

```ts
new ShellStep('Synth', {
input: /* source */,
commands: [
'npm ci',
'npm run build',
'npx cdk synth',
],
});
```

Instead of specifying the pipeline source with the `sourceAction` property to
the pipeline, specify it as the `input` property to the `ShellStep` instead.
You can use any of the factory functions on `CodePipelineSource`.

For example, for a GitHub source, the following old API:

```ts
sourceAction: new codepipeline_actions.GitHubSourceAction({
actionName: 'GitHub',
output: sourceArtifact,
// Replace these with your actual GitHub project name
owner: 'OWNER',
repo: 'REPO',
branch: 'main', // default: 'master'
}),
```

Translates into:

```ts
input: CodePipelineSource.gitHub('OWNER/REPO', 'main', {
authentication: SecretValue.secretsManager('GITHUB_TOKEN_NAME'),
}),
```

### Deployments

Adding CDK Stages to deploy is done by calling `addStage()`, or
potentially `addWave().addStage()`. All stages inside a wave are
deployed in parallel, which was not a capability of the original API.

| Old API | New API |
|-------------------------------+-------------------------------------------------------------------------------------------------------------------------------|
| `addApplicationStage()` | `addStage()` |
| `addStage().addApplication()` | `addStage()`. Adding multiple CDK Stages into a single Pipeline stage is not supported, add multiple Pipeline stages instead. |

### Approvals

Approvals are added by adding `pre` and `post` options to `addStage()`, with
steps to execute before and after the deployments, respectively. We recommend
putting manual approvals in `pre` steps, and automated approvals in `post` steps.

#### Manual approvals

For example, specifying a manual approval on a stage deployment in old API:

```ts
const stage = pipeline.addApplicationStage(...);
stage.addAction(new ManualApprovalAction({
actionName: 'ManualApproval',
runOrder: testingStage.nextSequentialRunOrder(),
}));
```

Becomes:

```ts
pipeline.addStage(..., {
pre: [
new ManualApprovalStep('ManualApproval'),
],
});
```

Note that this we've used `pre` to put the manual approval *before* a Stage
deployment (this was not possible in the old API). Be sure to put the manual
approval in the `pre` steps list of the *next* Stage to keep
it in the same location in the pipeline.

#### Automated approvals

For example, specifying an automated approval after a stage is deployed in the following old API:

```ts
const stage = pipeline.addApplicationStage(...);
stage.addActions(new ShellScriptAction({
actionName: 'MyValidation',
commands: ['curl -Ssf $VAR'],
useOutputs: {
VAR: pipeline.stackOutput(stage.cfnOutput),
},
// Optionally specify a BuildEnvironment
environment: { ... },
}));
```

Becomes:

```ts
const stage = new MyStage(...);
pipeline.addStage(stage, {
post: [
new CodeBuildStep('MyValidation', {
commands: ['curl -Ssf $VAR'],
envFromCfnOutput: {
VAR: stage.cfnOutput,
},
// Optionally specify a BuildEnvironment
buildEnvironment: { ... },
}),
],
});
```

You can also use `ShellStep` if you don't need any of the CodeBuild Project
customizations (like `buildEnvironment`).

#### Change set approvals

In the old API, there were two properties that were used to add actions to the pipeline
in between the `CreateChangeSet` and `ExecuteChangeSet` actions: `manualApprovals` and `extraRunOrderSpace`. These are not supported in the new API.

### Custom CodePipeline Actions

See the section [**Arbitrary CodePipeline actions** in the
main `README`](https://github.com/aws/aws-cdk/blob/master/packages/@aws-cdk/pipelines/README.md#arbitrary-codepipeline-actions) for an example of how to inject arbitrary
CodeBuild Actions.

## Definining the pipeline

Expand Down Expand Up @@ -551,4 +728,4 @@ const stage = pipeline.addApplicationStage(new MyApplication(this, 'PreProd'), {
```

**Note**: Manual Approvals notifications only apply when an application has security
check enabled.
check enabled.
72 changes: 65 additions & 7 deletions packages/@aws-cdk/pipelines/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ to the new version if possible.
> allows more control of CodeBuild project generation; supports deployment
> engines other than CodePipeline.
>
> The README for the original API can be found in [our GitHub repository](https://github.com/aws/aws-cdk/blob/master/packages/@aws-cdk/pipelines/ORIGINAL_API.md).
> The README for the original API, as well as a migration guide, can be found in [our GitHub repository](https://github.com/aws/aws-cdk/blob/master/packages/@aws-cdk/pipelines/ORIGINAL_API.md).
## At a glance

Expand Down Expand Up @@ -198,10 +198,10 @@ expected to produce the CDK Cloud Assembly as its single output (the contents of
the `cdk.out` directory after running `cdk synth`). "Steps" are arbitrary
actions in the pipeline, typically used to run scripts or commands.

For the synth, use a `ShellStep` and specify the commands necessary to build
your project and run `cdk synth`; the specific commands required will depend on
the programming language you are using. For a typical NPM-based project, the synth
will look like this:
For the synth, use a `ShellStep` and specify the commands necessary to install
dependencies, the CDK CLI, build your project and run `cdk synth`; the specific
commands required will depend on the programming language you are using. For a
typical NPM-based project, the synth will look like this:

```ts
const source = /* the repository source */;
Expand Down Expand Up @@ -244,6 +244,63 @@ earlier by calling `pipeline.buildPipeline()`. After you've called
that method, you can inspect the constructs that were produced by
accessing the properties of the `pipeline` object.

#### Commands for other languages and package managers

The commands you pass to `new ShellStep` will be very similar to the commands
you run on your own workstation to install dependencies and synth your CDK
project. Here are some (non-exhaustive) examples for what those commands might
look like in a number of different situations.

For Yarn, the install commands are different:

```ts
const pipeline = new CodePipeline(this, 'Pipeline', {
synth: new ShellStep('Synth', {
input: source,
commands: [
'yarn install --frozen-lockfile',
'yarn build',
'npx cdk synth',
],
})
});
```

For Python projects, remember to install the CDK CLI globally (as
there is no `package.json` to automatically install it for you):

```ts
const pipeline = new CodePipeline(this, 'Pipeline', {
synth: new ShellStep('Synth', {
input: source,
commands: [
'pip install -r requirements.txt',
'npm install -g aws-cdk',
'cdk synth',
],
})
});
```

For Java projects, remember to install the CDK CLI globally (as
there is no `package.json` to automatically install it for you),
and the Maven compilation step is automatically executed for you
as you run `cdk synth`:

```ts
const pipeline = new CodePipeline(this, 'Pipeline', {
synth: new ShellStep('Synth', {
input: source,
commands: [
'npm install -g aws-cdk',
'cdk synth',
],
})
});
```

You can adapt these examples to your own situation.

#### CodePipeline Sources

In CodePipeline, *Sources* define where the source of your application lives.
Expand Down Expand Up @@ -399,7 +456,8 @@ const pipeline = new CodePipeline(this, 'Pipeline', {
Every `addStage()` and `addWave()` command takes additional options. As part of these options,
you can specify `pre` and `post` steps, which are arbitrary steps that run before or after
the contents of the stage or wave, respectively. You can use these to add validations like
manual or automated gates to your pipeline.
manual or automated gates to your pipeline. We recommend putting manual approval gates in the set of `pre` steps, and automated approval gates in
the set of `post` steps.

The following example shows both an automated approval in the form of a `ShellStep`, and
a manual approvel in the form of a `ManualApprovalStep` added to the pipeline. Both must
Expand Down Expand Up @@ -566,7 +624,7 @@ If you want to add a type of CodePipeline action to the CDK Pipeline that
doesn't have a matching class yet, you can define your own step class that extends
`Step` and implements `ICodePipelineActionFactory`.

Here's a simple example that adds a Jenkins step:
Here's an example that adds a Jenkins step:

```ts
class MyJenkinsStep extends Step implements ICodePipelineActionFactory {
Expand Down

0 comments on commit 9022d6f

Please sign in to comment.