-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathecr_scan_saver.yaml
210 lines (186 loc) · 6.35 KB
/
ecr_scan_saver.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
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
206
207
208
209
210
AWSTemplateFormatVersion: '2010-09-09'
Description: |
This cloudformation template creates ECR Repository, EventBridge, Lambda function and S3 bucket to save ECR image scan
results to S3 Bucket.
- ECR repository that on-push scan is enabled, you can name your repository using the RepositoryName parameter.
- EventBridge will connect your repository and lambda function to trigger lambda function when image scanning
is completed.
- Lambda function will retrieve the latest scan result and store that on a private S3 bucket that you will name using
BucketName parameter.
For more information regarding ECR container image scanning and this setup, you can check
https://www.sufle.io/blog/xxxxxx
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: "Configuration"
Parameters:
- RepositoryName
- BucketName
Parameters:
RepositoryName:
Description: Name of the ECR repository
Type: String
AllowedPattern: ^[a-z1-9]*$
BucketName:
Description: Name of the S3 bucket that scan results will stored in.
Type: String
AllowedPattern: ^[a-z1-9]*$
Resources:
Repository:
Type: AWS::ECR::Repository
Properties:
RepositoryName: !Ref RepositoryName
RoleForEnableScanLambda:
Type: AWS::IAM::Role
DependsOn: Repository
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: [lambda.amazonaws.com]
Action:
- sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Policies:
- PolicyName: AllowPutImageScanningConfiguration
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: ecr:PutImageScanningConfiguration
Resource: !GetAtt Repository.Arn
EnableScanLambdaFunction:
Type: AWS::Lambda::Function
DependsOn:
- RoleForEnableScanLambda
- Repository
Properties:
FunctionName: EnableScanLambdaFunction
Description: Backup ECR Scan Results to S3 Bucket
Handler: index.lambda_handler
MemorySize: 128
Role: !GetAtt RoleForEnableScanLambda.Arn
Runtime: python3.7
Timeout: 10
Code:
ZipFile: !Sub |
import boto3
import cfnresponse
ECR_REPO = '${RepositoryName}'
def lambda_handler(event, context):
client = boto3.client('ecr')
response = client.put_image_scanning_configuration(
repositoryName=ECR_REPO,
imageScanningConfiguration={
'scanOnPush': True
}
)
cfnresponse.send(event, context, cfnresponse.SUCCESS, {}, "")
EnableScanResource:
Type: "Custom::EnableScanResource"
DependsOn: EnableScanLambdaFunction
Properties:
ServiceToken: !GetAtt EnableScanLambdaFunction.Arn
S3Bucket:
Type: AWS::S3::Bucket
DeletionPolicy: Retain
Properties:
BucketName: !Ref BucketName
RoleForScanSaverLambda:
Type: AWS::IAM::Role
DependsOn: S3Bucket
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: [lambda.amazonaws.com]
Action:
- sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Policies:
- PolicyName: AllowPutObject
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: s3:PutObject
Resource: !Sub "${S3Bucket.Arn}/*"
- PolicyName: AllowDescribeImageScanFindings
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: ecr:DescribeImageScanFindings
Resource: !GetAtt Repository.Arn
ScanSaverLambdaFunction:
Type: AWS::Lambda::Function
DependsOn: RoleForScanSaverLambda
Properties:
FunctionName: ScanSaverLambdaFunction
Description: Backup ECR Scan Results to S3 Bucket
Handler: index.lambda_handler
MemorySize: 1024
Role: !GetAtt RoleForScanSaverLambda.Arn
Runtime: python3.7
Timeout: 10
Code:
ZipFile: !Sub |
import boto3
import datetime
import json
S3_BUCKET = '${BucketName}'
ECR_REPO = '${RepositoryName}'
def lambda_handler(event, context):
client = boto3.client('ecr')
response = client.describe_image_scan_findings(
repositoryName=ECR_REPO,
imageId={
'imageDigest': event['detail']['image-digest']
}
)
response["imageScanFindings"]["imageScanCompletedAt"] = \
response["imageScanFindings"]["imageScanCompletedAt"].strftime("%Y-%m-%d %H:%M:%S")
response["imageScanFindings"]["vulnerabilitySourceUpdatedAt"] = \
response["imageScanFindings"]["vulnerabilitySourceUpdatedAt"].strftime("%Y-%m-%d %H:%M:%S")
result = json.dumps(response).encode('utf8')
s3 = boto3.resource("s3")
now = datetime.datetime.now()
timestamp = now.strftime("%m%d%Y-%H%M%S")
file_name = f"scan-result-{timestamp}.json"
s3.Bucket(S3_BUCKET).put_object(Key=file_name, Body=result)
EventRule:
Type: AWS::Events::Rule
DependsOn:
- Repository
- ScanSaverLambdaFunction
Properties:
Description: "EventRule"
EventPattern:
source:
- "aws.ecr"
detail-type:
- "ECR Image Scan"
detail:
scan-status:
- "COMPLETE"
repository-name:
- !Ref Repository
State: "ENABLED"
Targets:
- Arn: !GetAtt ScanSaverLambdaFunction.Arn
Id: "TargetFunction"
PermissionForEventsToInvokeLambda:
Type: AWS::Lambda::Permission
DependsOn: EventRule
Properties:
FunctionName: !Ref ScanSaverLambdaFunction
Action: "lambda:InvokeFunction"
Principal: "events.amazonaws.com"
SourceArn: !GetAtt EventRule.Arn