@flit/cdk-pipeline 1.4.4 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.jsii +176 -37
- package/dist/artifact.js +1 -1
- package/dist/code-commit-source-segment.js +2 -2
- package/dist/code-star-source-segment.js +2 -2
- package/dist/git-hub-source-segment.js +2 -2
- package/dist/pipeline-segment.js +2 -2
- package/dist/pipeline.js +3 -3
- package/dist/publish-assets-action.js +1 -1
- package/dist/s3-source-segment.js +2 -2
- package/dist/segment.js +2 -2
- package/dist/source-segment.js +1 -1
- package/dist/stack-segment.js +47 -17
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +105 -99
- package/src/pipeline.ts +103 -103
- package/src/stack-segment.ts +204 -173
package/src/stack-segment.ts
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import { Stack } from "aws-cdk-lib";
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
BuildEnvironmentVariable,
|
|
4
|
+
BuildEnvironmentVariableType,
|
|
5
|
+
BuildSpec,
|
|
6
|
+
mergeBuildSpecs,
|
|
7
|
+
Project,
|
|
8
|
+
ProjectProps,
|
|
8
9
|
} from "aws-cdk-lib/aws-codebuild";
|
|
9
10
|
import { IAction } from "aws-cdk-lib/aws-codepipeline";
|
|
10
11
|
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
CloudFormationCreateReplaceChangeSetAction,
|
|
13
|
+
CloudFormationExecuteChangeSetAction,
|
|
14
|
+
CodeBuildAction,
|
|
15
|
+
ManualApprovalAction,
|
|
15
16
|
} from "aws-cdk-lib/aws-codepipeline-actions";
|
|
16
|
-
import { IRole } from "aws-cdk-lib/aws-iam";
|
|
17
|
+
import { IRole, PolicyStatement } from "aws-cdk-lib/aws-iam";
|
|
17
18
|
import * as path from "path";
|
|
18
19
|
|
|
19
20
|
import { Artifact } from "./artifact";
|
|
@@ -22,185 +23,215 @@ import { Pipeline } from "./pipeline";
|
|
|
22
23
|
import { PublishAssetsAction } from "./publish-assets-action";
|
|
23
24
|
|
|
24
25
|
export interface StackSegmentProps {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
26
|
+
/**
|
|
27
|
+
* The stack to be deployed in this segment.
|
|
28
|
+
*/
|
|
29
|
+
readonly stack: Stack;
|
|
30
|
+
/**
|
|
31
|
+
* The input arfifact for the build stage.
|
|
32
|
+
*/
|
|
33
|
+
readonly input: Artifact | Artifact[];
|
|
34
|
+
/**
|
|
35
|
+
* The command(s) to build the stack.
|
|
36
|
+
* @example "cdk synth StackName --strict --exclusively"
|
|
37
|
+
*/
|
|
38
|
+
readonly project?: ProjectProps;
|
|
39
|
+
/**
|
|
40
|
+
* The role for the build stage.
|
|
41
|
+
*/
|
|
42
|
+
readonly role?: IRole;
|
|
43
|
+
/**
|
|
44
|
+
* The environmental variables for the build stage.
|
|
45
|
+
*/
|
|
46
|
+
readonly environmentVariables?: { [key: string]: BuildEnvironmentVariable };
|
|
47
|
+
/**
|
|
48
|
+
* The name of the stack to deploy the changes to.
|
|
49
|
+
* @default The name of the given stack.
|
|
50
|
+
*/
|
|
51
|
+
readonly stackName?: string;
|
|
52
|
+
/**
|
|
53
|
+
* The artifact to hold the output of the build if this stack includes a build.
|
|
54
|
+
*/
|
|
55
|
+
readonly buildOutput?: Artifact;
|
|
56
|
+
/**
|
|
57
|
+
* The artifact to hold the stack deployment output file.
|
|
58
|
+
*/
|
|
59
|
+
readonly stackOutput?: Artifact;
|
|
60
|
+
/**
|
|
61
|
+
* The filename for the file in the output artifact
|
|
62
|
+
* @default "artifact.json"
|
|
63
|
+
*/
|
|
64
|
+
readonly outputFileName?: string;
|
|
65
|
+
/**
|
|
66
|
+
* Does this stage require manual approval of the change set?
|
|
67
|
+
* @default false
|
|
68
|
+
*/
|
|
69
|
+
readonly manualApproval?: Boolean;
|
|
69
70
|
}
|
|
70
71
|
|
|
71
72
|
/**
|
|
72
73
|
* @category Segments
|
|
73
74
|
*/
|
|
74
75
|
export class StackSegment extends Segment {
|
|
75
|
-
|
|
76
|
+
readonly props: StackSegmentProps;
|
|
76
77
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
78
|
+
constructor(props: StackSegmentProps) {
|
|
79
|
+
super({
|
|
80
|
+
...props,
|
|
81
|
+
output: [props.buildOutput, props.stackOutput].filter((a) => !!a),
|
|
82
|
+
});
|
|
83
|
+
this.props = props;
|
|
84
|
+
}
|
|
84
85
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
86
|
+
construct(scope: Pipeline): SegmentConstructed {
|
|
87
|
+
return new StackSegmentConstructed(
|
|
88
|
+
scope,
|
|
89
|
+
`Deploy${this.props.stack.stackName}`,
|
|
90
|
+
{
|
|
91
|
+
...this.props,
|
|
92
|
+
input: this.inputs[0],
|
|
93
|
+
extraInputs: this.inputs.slice(1),
|
|
94
|
+
},
|
|
95
|
+
);
|
|
96
|
+
}
|
|
96
97
|
}
|
|
97
98
|
|
|
98
99
|
export interface StackSegmentConstructedProps {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
100
|
+
readonly stack: Stack;
|
|
101
|
+
readonly project?: ProjectProps;
|
|
102
|
+
readonly environmentVariables?: { [key: string]: BuildEnvironmentVariable };
|
|
103
|
+
readonly stackName?: string;
|
|
104
|
+
readonly input: Artifact;
|
|
105
|
+
readonly extraInputs?: Artifact[];
|
|
106
|
+
readonly buildOutput?: Artifact;
|
|
107
|
+
readonly stackOutput?: Artifact;
|
|
108
|
+
readonly outputFileName?: string;
|
|
109
|
+
readonly manualApproval?: Boolean;
|
|
109
110
|
}
|
|
110
111
|
|
|
111
112
|
export class StackSegmentConstructed extends SegmentConstructed {
|
|
112
|
-
|
|
113
|
-
|
|
113
|
+
readonly name: string;
|
|
114
|
+
readonly actions: IAction[];
|
|
114
115
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
116
|
+
constructor(
|
|
117
|
+
scope: Pipeline,
|
|
118
|
+
id: string,
|
|
119
|
+
props: StackSegmentConstructedProps,
|
|
120
|
+
) {
|
|
121
|
+
super(scope, id);
|
|
121
122
|
|
|
122
|
-
|
|
123
|
+
this.name = props.stack.stackName;
|
|
123
124
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
125
|
+
const buildArtifact = props.project
|
|
126
|
+
? props.buildOutput || new Artifact()
|
|
127
|
+
: undefined;
|
|
127
128
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
129
|
+
const codeBuildProject = new Project(this, "UpdateCodeBuild", {
|
|
130
|
+
...props.project,
|
|
131
|
+
buildSpec: props.project?.buildSpec
|
|
132
|
+
? mergeBuildSpecs(
|
|
133
|
+
props.project.buildSpec,
|
|
134
|
+
BuildSpec.fromObject({
|
|
135
|
+
artifacts: {
|
|
136
|
+
files: [path.join(scope.buildDir, "**/*")],
|
|
137
|
+
},
|
|
138
|
+
}),
|
|
139
|
+
)
|
|
140
|
+
: BuildSpec.fromObject({
|
|
141
|
+
artifacts: {
|
|
142
|
+
files: [path.join(scope.buildDir, "**/*")],
|
|
143
|
+
},
|
|
144
|
+
}),
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
Object.entries(props.project?.environment?.environmentVariables || []).forEach(([, v]) => {
|
|
148
|
+
switch (v.type) {
|
|
149
|
+
case BuildEnvironmentVariableType.PARAMETER_STORE:
|
|
150
|
+
codeBuildProject.addToRolePolicy(new PolicyStatement({
|
|
151
|
+
actions: [
|
|
152
|
+
"ssm:GetParameter",
|
|
153
|
+
"ssm:GetParameters",
|
|
154
|
+
"ssm:GetParametersByPath",
|
|
155
|
+
],
|
|
156
|
+
resources: [
|
|
157
|
+
`arn:aws:ssm:*:${Stack.of(this).account}:parameter/${v.value}`
|
|
158
|
+
],
|
|
159
|
+
}));
|
|
160
|
+
break;
|
|
161
|
+
case BuildEnvironmentVariableType.SECRETS_MANAGER:
|
|
162
|
+
codeBuildProject.addToRolePolicy(new PolicyStatement({
|
|
163
|
+
actions: [
|
|
164
|
+
"secretsmanager:GetSecretValue",
|
|
165
|
+
"secretsmanager:DescribeSecret",
|
|
166
|
+
],
|
|
167
|
+
resources: [(v.value as string).startsWith("arn:") ?
|
|
168
|
+
v.value.split(":").slice(0, 7).join(":") :
|
|
169
|
+
`arn:aws:secretsmanager:*:${Stack.of(this).account}:secret:${v.value}-*`],
|
|
170
|
+
}));
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
this.actions = [
|
|
176
|
+
...(buildArtifact
|
|
177
|
+
? [
|
|
178
|
+
new CodeBuildAction({
|
|
179
|
+
actionName: `${this.name}Build`,
|
|
180
|
+
runOrder: 1,
|
|
181
|
+
input: props.input,
|
|
182
|
+
extraInputs: props.extraInputs,
|
|
183
|
+
outputs: [buildArtifact],
|
|
184
|
+
environmentVariables: props.environmentVariables,
|
|
185
|
+
project: codeBuildProject,
|
|
186
|
+
}),
|
|
187
|
+
new PublishAssetsAction(this, "PublishAssets", {
|
|
188
|
+
actionName: `${this.name}PublishAssets`,
|
|
189
|
+
runOrder: 2,
|
|
190
|
+
input: buildArtifact,
|
|
191
|
+
manifestPath: scope.buildDir,
|
|
192
|
+
}),
|
|
193
|
+
]
|
|
194
|
+
: []),
|
|
195
|
+
new CloudFormationCreateReplaceChangeSetAction({
|
|
196
|
+
actionName: `${this.name}PrepareChanges`,
|
|
197
|
+
runOrder: buildArtifact ? 3 : 1,
|
|
198
|
+
stackName: props.stackName ? props.stackName : props.stack.stackName,
|
|
199
|
+
account: props.stack.account,
|
|
200
|
+
region: props.stack.region,
|
|
201
|
+
changeSetName: `${props.stack.stackName}Changes`,
|
|
202
|
+
adminPermissions: true,
|
|
203
|
+
templatePath: (buildArtifact ? buildArtifact : props.input).atPath(
|
|
204
|
+
path.join(scope.buildDir, props.stack.templateFile),
|
|
205
|
+
),
|
|
206
|
+
}),
|
|
207
|
+
...(props.manualApproval
|
|
208
|
+
? [
|
|
209
|
+
new ManualApprovalAction({
|
|
210
|
+
actionName: `${this.name}ApproveChanges`,
|
|
211
|
+
runOrder: buildArtifact ? 4 : 2,
|
|
212
|
+
}),
|
|
213
|
+
]
|
|
214
|
+
: []),
|
|
215
|
+
new CloudFormationExecuteChangeSetAction({
|
|
216
|
+
actionName: `${this.name}ExecuteChanges`,
|
|
217
|
+
runOrder: props.manualApproval
|
|
218
|
+
? buildArtifact
|
|
219
|
+
? 5
|
|
220
|
+
: 3
|
|
221
|
+
: buildArtifact
|
|
222
|
+
? 4
|
|
223
|
+
: 2,
|
|
224
|
+
stackName: props.stackName ? props.stackName : props.stack.stackName,
|
|
225
|
+
account: props.stack.account,
|
|
226
|
+
region: props.stack.region,
|
|
227
|
+
changeSetName: `${props.stack.stackName}Changes`,
|
|
228
|
+
output: props.stackOutput,
|
|
229
|
+
outputFileName: props.outputFileName
|
|
230
|
+
? props.outputFileName
|
|
231
|
+
: props.stackOutput
|
|
232
|
+
? "artifact.json"
|
|
233
|
+
: undefined,
|
|
234
|
+
}),
|
|
235
|
+
];
|
|
236
|
+
}
|
|
206
237
|
}
|