Skip to content

Commit 01cc8a2

Browse files
skinny85RomainMuller
authored andcommitted
feat(aws-ecr): add an ECR Repository source CodePipeline Action. (#1255)
1 parent 3208457 commit 01cc8a2

File tree

9 files changed

+464
-4
lines changed

9 files changed

+464
-4
lines changed

packages/@aws-cdk/aws-codepipeline/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
"@aws-cdk/aws-codebuild": "^0.18.1",
6464
"@aws-cdk/aws-codecommit": "^0.18.1",
6565
"@aws-cdk/aws-codedeploy": "^0.18.1",
66+
"@aws-cdk/aws-ecr": "^0.18.1",
6667
"@aws-cdk/aws-lambda": "^0.18.1",
6768
"@aws-cdk/aws-sns": "^0.18.1",
6869
"cdk-build-tools": "^0.18.1",
@@ -85,4 +86,4 @@
8586
"@aws-cdk/aws-s3": "^0.18.1",
8687
"@aws-cdk/cdk": "^0.18.1"
8788
}
88-
}
89+
}
Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
{
2+
"Resources": {
3+
"MyBucketF68F3FF0": {
4+
"Type": "AWS::S3::Bucket"
5+
},
6+
"MyPipelineRoleC0D47CA4": {
7+
"Type": "AWS::IAM::Role",
8+
"Properties": {
9+
"AssumeRolePolicyDocument": {
10+
"Statement": [
11+
{
12+
"Action": "sts:AssumeRole",
13+
"Effect": "Allow",
14+
"Principal": {
15+
"Service": "codepipeline.amazonaws.com"
16+
}
17+
}
18+
],
19+
"Version": "2012-10-17"
20+
}
21+
}
22+
},
23+
"MyPipelineRoleDefaultPolicy34F09EFA": {
24+
"Type": "AWS::IAM::Policy",
25+
"Properties": {
26+
"PolicyDocument": {
27+
"Statement": [
28+
{
29+
"Action": [
30+
"s3:GetObject*",
31+
"s3:GetBucket*",
32+
"s3:List*",
33+
"s3:DeleteObject*",
34+
"s3:PutObject*",
35+
"s3:Abort*"
36+
],
37+
"Effect": "Allow",
38+
"Resource": [
39+
{
40+
"Fn::GetAtt": [
41+
"MyBucketF68F3FF0",
42+
"Arn"
43+
]
44+
},
45+
{
46+
"Fn::Join": [
47+
"",
48+
[
49+
{
50+
"Fn::GetAtt": [
51+
"MyBucketF68F3FF0",
52+
"Arn"
53+
]
54+
},
55+
"/*"
56+
]
57+
]
58+
}
59+
]
60+
},
61+
{
62+
"Action": "ecr:DescribeImages",
63+
"Effect": "Allow",
64+
"Resource": {
65+
"Fn::GetAtt": [
66+
"MyEcrRepo767466D0",
67+
"Arn"
68+
]
69+
}
70+
}
71+
],
72+
"Version": "2012-10-17"
73+
},
74+
"PolicyName": "MyPipelineRoleDefaultPolicy34F09EFA",
75+
"Roles": [
76+
{
77+
"Ref": "MyPipelineRoleC0D47CA4"
78+
}
79+
]
80+
}
81+
},
82+
"MyPipelineAED38ECF": {
83+
"Type": "AWS::CodePipeline::Pipeline",
84+
"Properties": {
85+
"RoleArn": {
86+
"Fn::GetAtt": [
87+
"MyPipelineRoleC0D47CA4",
88+
"Arn"
89+
]
90+
},
91+
"Stages": [
92+
{
93+
"Actions": [
94+
{
95+
"ActionTypeId": {
96+
"Category": "Source",
97+
"Owner": "AWS",
98+
"Provider": "ECR",
99+
"Version": "1"
100+
},
101+
"Configuration": {
102+
"RepositoryName": {
103+
"Ref": "MyEcrRepo767466D0"
104+
}
105+
},
106+
"InputArtifacts": [],
107+
"Name": "ECR_Source",
108+
"OutputArtifacts": [
109+
{
110+
"Name": "Artifact_awscdkcodepipelineecrsourceMyEcrRepoECRSource8525F033"
111+
}
112+
],
113+
"RunOrder": 1
114+
}
115+
],
116+
"Name": "Source"
117+
},
118+
{
119+
"Actions": [
120+
{
121+
"ActionTypeId": {
122+
"Category": "Approval",
123+
"Owner": "AWS",
124+
"Provider": "Manual",
125+
"Version": "1"
126+
},
127+
"InputArtifacts": [],
128+
"Name": "ManualApproval",
129+
"OutputArtifacts": [],
130+
"RunOrder": 1
131+
}
132+
],
133+
"Name": "Approve"
134+
}
135+
],
136+
"ArtifactStore": {
137+
"Location": {
138+
"Ref": "MyBucketF68F3FF0"
139+
},
140+
"Type": "S3"
141+
}
142+
},
143+
"DependsOn": [
144+
"MyPipelineRoleC0D47CA4",
145+
"MyPipelineRoleDefaultPolicy34F09EFA"
146+
]
147+
},
148+
"MyPipelineEventsRoleFAB99F32": {
149+
"Type": "AWS::IAM::Role",
150+
"Properties": {
151+
"AssumeRolePolicyDocument": {
152+
"Statement": [
153+
{
154+
"Action": "sts:AssumeRole",
155+
"Effect": "Allow",
156+
"Principal": {
157+
"Service": "events.amazonaws.com"
158+
}
159+
}
160+
],
161+
"Version": "2012-10-17"
162+
}
163+
}
164+
},
165+
"MyPipelineEventsRoleDefaultPolicyF045F033": {
166+
"Type": "AWS::IAM::Policy",
167+
"Properties": {
168+
"PolicyDocument": {
169+
"Statement": [
170+
{
171+
"Action": "codepipeline:StartPipelineExecution",
172+
"Effect": "Allow",
173+
"Resource": {
174+
"Fn::Join": [
175+
"",
176+
[
177+
"arn:",
178+
{
179+
"Ref": "AWS::Partition"
180+
},
181+
":codepipeline:",
182+
{
183+
"Ref": "AWS::Region"
184+
},
185+
":",
186+
{
187+
"Ref": "AWS::AccountId"
188+
},
189+
":",
190+
{
191+
"Ref": "MyPipelineAED38ECF"
192+
}
193+
]
194+
]
195+
}
196+
}
197+
],
198+
"Version": "2012-10-17"
199+
},
200+
"PolicyName": "MyPipelineEventsRoleDefaultPolicyF045F033",
201+
"Roles": [
202+
{
203+
"Ref": "MyPipelineEventsRoleFAB99F32"
204+
}
205+
]
206+
}
207+
},
208+
"MyEcrRepo767466D0": {
209+
"Type": "AWS::ECR::Repository"
210+
},
211+
"MyEcrRepoawscdkcodepipelineecrsourceMyPipeline63CF3194SourceEventRule911FDB6D": {
212+
"Type": "AWS::Events::Rule",
213+
"Properties": {
214+
"EventPattern": {
215+
"source": [
216+
"aws.ecr"
217+
],
218+
"detail": {
219+
"eventName": [
220+
"PutImage"
221+
],
222+
"requestParameters": {
223+
"repositoryName": [
224+
{
225+
"Ref": "MyEcrRepo767466D0"
226+
}
227+
]
228+
}
229+
}
230+
},
231+
"State": "ENABLED",
232+
"Targets": [
233+
{
234+
"Arn": {
235+
"Fn::Join": [
236+
"",
237+
[
238+
"arn:",
239+
{
240+
"Ref": "AWS::Partition"
241+
},
242+
":codepipeline:",
243+
{
244+
"Ref": "AWS::Region"
245+
},
246+
":",
247+
{
248+
"Ref": "AWS::AccountId"
249+
},
250+
":",
251+
{
252+
"Ref": "MyPipelineAED38ECF"
253+
}
254+
]
255+
]
256+
},
257+
"Id": "MyPipeline",
258+
"RoleArn": {
259+
"Fn::GetAtt": [
260+
"MyPipelineEventsRoleFAB99F32",
261+
"Arn"
262+
]
263+
}
264+
}
265+
]
266+
}
267+
}
268+
}
269+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import ecr = require('@aws-cdk/aws-ecr');
2+
import s3 = require('@aws-cdk/aws-s3');
3+
import cdk = require('@aws-cdk/cdk');
4+
import codepipeline = require('../lib');
5+
6+
const app = new cdk.App();
7+
8+
const stack = new cdk.Stack(app, 'aws-cdk-codepipeline-ecr-source');
9+
10+
const bucket = new s3.Bucket(stack, 'MyBucket');
11+
const pipeline = new codepipeline.Pipeline(stack, 'MyPipeline', {
12+
artifactBucket: bucket,
13+
});
14+
15+
const repository = new ecr.Repository(stack, 'MyEcrRepo');
16+
const sourceStage = pipeline.addStage('Source');
17+
repository.addToPipeline(sourceStage, 'ECR_Source');
18+
19+
const approveStage = pipeline.addStage('Approve');
20+
new codepipeline.ManualApprovalAction(stack, 'ManualApproval', {
21+
stage: approveStage,
22+
});
23+
24+
app.run();

packages/@aws-cdk/aws-ecr/README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,28 @@ is important here):
2323
repository.addLifecycleRule({ tagPrefixList: ['prod'], maxImageCount: 9999 });
2424
repository.addLifecycleRule({ maxImageAgeDays: 30 });
2525
```
26+
27+
### Using with CodePipeline
28+
29+
This package also contains a source Action that allows you to use an ECR Repository as a source for CodePipeline.
30+
Example:
31+
32+
```ts
33+
import codepipeline = require('@aws-cdk/aws-codepipeline');
34+
35+
const pipeline = new codepipeline.Pipeline(this, 'MyPipeline');
36+
const sourceStage = pipeline.addStage('Source');
37+
const sourceAction = new ecr.PipelineSourceAction(this, 'ECR', {
38+
stage: sourceStage,
39+
repository: ecrRepository,
40+
imageTag: 'some-tag', // optional, default: 'latest'
41+
outputArtifactName: 'SomeName', // optional
42+
});
43+
```
44+
45+
You can also add the Repository to the Pipeline directly:
46+
47+
```ts
48+
// equivalent to the code above:
49+
const sourceAction = ecrRepository.addToPipeline(sourceStage, 'ECR');
50+
```
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// AWS::ECR CloudFormation Resources:
22
export * from './ecr.generated';
33

4+
export * from './pipeline-action';
45
export * from './repository';
56
export * from './repository-ref';
67
export * from './lifecycle';

0 commit comments

Comments
 (0)