-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathtemplate.yaml
305 lines (289 loc) · 9.2 KB
/
template.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
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Security Hub Updater
Parameters:
Path:
Type: String
Default: "/"
Description: Path for IAM Role
MemberIAMRoleName:
Type: String
Default: "securityhub-UpdateControl-role"
Description: Name of IAM Role in member account
MemberIAMRolePath:
Type: String
Default: "/"
Description: Path of IAM Role in member account
Schedule:
Type: String
Default: "rate(1 day)"
Description: The scheduling expression that determines when and how often the SecurityHubUpdater runs.
EventTriggerState:
Type: String
Default: "DISABLED"
AllowedValues: ["ENABLED", "DISABLED"]
Description: The state of the SecurityHubUpdateEvent rule monitoring Security Hub control updates and triggering the state machine
# TODO - Subscriptions: If you need more e-mail subscriptions, add another parameter. Also, add another condition in the "Conditions" section and adapt the list of subscriptions in the StateMachineFailureSNSTopic resource accordingly.
NotificationEmail1:
Type: String
Default: ""
Description: Optional - E-mail address to receive notification if the state machine fails.
NotificationEmail2:
Type: String
Default: ""
Description: Optional - E-mail address to receive notification if the state machine fails.
NotificationEmail3:
Type: String
Default: ""
Description: Optional - E-mail address to receive notification if the state machine fails.
Conditions:
# TODO - Subscriptions: Add another "!Not [!Equals [...]]" Condition into the list for each additional email parameter added.
NotificationEmail1Exists: !Not [!Equals [!Ref NotificationEmail1, ""]]
NotificationEmail2Exists: !Not [!Equals [!Ref NotificationEmail2, ""]]
NotificationEmail3Exists: !Not [!Equals [!Ref NotificationEmail3, ""]]
Resources:
AccountExceptions:
Type: AWS::DynamoDB::Table
Properties:
AttributeDefinitions:
-
AttributeName: "ControlId"
AttributeType: "S"
# -
# AttributeName: "Disabled"
# AttributeType: "S"
# -
# AttributeName: "Eisabled"
# AttributeType: "S"
BillingMode: "PAY_PER_REQUEST"
KeySchema:
-
AttributeName: "ControlId"
KeyType: "HASH"
# ProvisionedThroughput:
# ReadCapacityUnits: 5
# WriteCapacityUnits: 5
LambdaExecutionRole:
Type: AWS::IAM::Role
Properties:
Path: !Ref Path
AssumeRolePolicyDocument:
Statement:
- Action:
- sts:AssumeRole
Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Version: '2012-10-17'
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Policies:
- PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action: sts:AssumeRole
Resource:
- !Sub "arn:aws:iam::*:role${MemberIAMRolePath}${MemberIAMRoleName}"
- Effect: Allow
Action:
- securityhub:Get*
- securityhub:List*
- securityhub:Describe*
- organizations:ListAccounts
Resource: "*"
- Effect: Allow
Action:
- dynamodb:Query
- dynamodb:Scan
Resource: !GetAtt AccountExceptions.Arn
PolicyName: SecurityHubUpdateStandardsControlPolicyForLambda
CheckResult:
Type: AWS::Serverless::Function
Properties:
CodeUri: ./src/CheckResult
Description: Checks results of UpdateMember executions
Handler: index.lambda_handler
Role:
Fn::GetAtt:
- LambdaExecutionRole
- Arn
Runtime: python3.8
Timeout: 300
GetMembers:
Type: AWS::Serverless::Function
Properties:
CodeUri: ./src/GetMembers
Description: Get list of member accounts from SecurityHub
Handler: index.lambda_handler
Role:
Fn::GetAtt:
- LambdaExecutionRole
- Arn
Runtime: python3.8
Timeout: 300
Environment:
Variables:
Schedule: !Ref Schedule
DynamoDB: !Ref AccountExceptions
UpdateMember:
Type: AWS::Serverless::Function
Properties:
CodeUri: ./src/UpdateMember
Description: Update the state of SecurityHub findings in all member accounts
Handler: index.lambda_handler
Role:
Fn::GetAtt:
- LambdaExecutionRole
- Arn
Runtime: python3.8
Timeout: 900
Environment:
Variables:
MemberRole: !Sub "arn:aws:iam::<accountId>:role${MemberIAMRolePath}${MemberIAMRoleName}"
SecurityHubMemberUpdateStateMachineRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action:
- sts:AssumeRole
Effect: Allow
Principal:
Service:
- states.amazonaws.com
Version: "2012-10-17"
Policies:
- PolicyName: InvokeLambdaPolicyForStateMachines
PolicyDocument:
Version: 2012-10-17
Statement:
- Sid: InvokeLambdas
Effect: Allow
Action:
- "lambda:InvokeFunction"
- "lambda:Get*"
- "lambda:List*"
Resource:
- !GetAtt UpdateMember.Arn
- !GetAtt GetMembers.Arn
- !GetAtt CheckResult.Arn
- Sid: PublishSNS
Effect: Allow
Action:
- "sns:Publish"
Resource: !Ref StateMachineFailureSNSTopic
SecurityHubMemberUpdate:
Type: AWS::Serverless::StateMachine
Properties:
Role: !GetAtt SecurityHubMemberUpdateStateMachineRole.Arn
DefinitionUri: ./stateMachine.json
DefinitionSubstitutions:
UpdateMember: !GetAtt UpdateMember.Arn
GetMembers: !GetAtt GetMembers.Arn
CheckResult: !GetAtt CheckResult.Arn
StateMachineFailureSNSTopic: !Ref StateMachineFailureSNSTopic
Events:
Scheduled:
Type: Schedule
Properties:
Input: '{"scheduled": "True"}'
Schedule: !Ref Schedule
SecurityHubUpdatedEvent:
Type: AWS::Events::Rule
Properties:
Description: This rule monitors Security Hub and executes the state machine if a Security Hub control was updated
State: !Ref EventTriggerState
RoleArn: !GetAtt SecurityHubUpdatedEventRole.Arn
Targets:
- Arn: !Ref SecurityHubMemberUpdate
Id: SecurityHubUpdaterStateMachine
RoleArn: !GetAtt SecurityHubUpdatedEventRole.Arn
EventPattern:
source:
- aws.securityhub
detail-type:
- AWS API Call via CloudTrail
detail:
eventSource:
- securityhub.amazonaws.com
eventName:
- UpdateStandardsControl
- BatchDisableStandards
- BatchEnableStandards
SecurityHubUpdatedEventRole:
Type: AWS::IAM::Role
Properties:
Path: !Ref Path
AssumeRolePolicyDocument:
Statement:
- Action:
- sts:AssumeRole
Effect: Allow
Principal:
Service:
- events.amazonaws.com
Version: '2012-10-17'
Policies:
- PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- states:StartExecution
Resource: !Ref SecurityHubMemberUpdate
PolicyName: StartStateMachine
StateMachineFailureSNSTopic:
Type: AWS::SNS::Topic
Properties:
Subscription:
# TODO - Subscriptions: Add another "!If" statement into the list for each additional email parameter added.
- !If
- NotificationEmail1Exists
-
Endpoint: !Ref NotificationEmail1
Protocol: email
- !Ref AWS::NoValue
- !If
- NotificationEmail2Exists
-
Endpoint: !Ref NotificationEmail2
Protocol: email
- !Ref AWS::NoValue
- !If
- NotificationEmail3Exists
-
Endpoint: !Ref NotificationEmail3
Protocol: email
- !Ref AWS::NoValue
StateMachineFailureSNSTopicPolicyEventRule:
Type: "AWS::SNS::TopicPolicy"
Properties:
PolicyDocument:
Statement:
- Sid: PublishMessage
Effect: "Allow"
Principal:
AWS: "*"
Action:
- "sns:Publish"
Resource: !Ref StateMachineFailureSNSTopic
Condition:
StringEquals:
AWS:PrincipalArn: !GetAtt SecurityHubMemberUpdateStateMachineRole.Arn
Topics:
- !Ref StateMachineFailureSNSTopic
Outputs:
StateMachineArn:
Value: !Ref SecurityHubMemberUpdate
CheckResultLambda:
Value: !Ref CheckResult
GetMembersLambda:
Value: !Ref GetMembers
UpdateMemberLambda:
Value: !Ref UpdateMember
SNSTopic:
Value: !Ref StateMachineFailureSNSTopic
AccountExceptionsDynamoDBTableName:
Value: !Ref AccountExceptions