-
Notifications
You must be signed in to change notification settings - Fork 4
/
template.yaml
239 lines (237 loc) · 8.18 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
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: MIT-0
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
Deploys an IAM password policy via CloudFormation StackSets
Parameters:
ResourceNamePrefix:
Type: String
Description: String prefix for resource names
Default: cfn-custom-resource-deployer
OrganizationID:
Type: String
Description: The AWS organization ID. This parameter will be used to allow other accounts in the organization to communicate with the central account.
Environment:
Type: String
Default: dev
TargetOU:
Type: String
Description: The AWS Organizations OU to which the stack set template will be deployed
Resources:
PasswordPolicyProviderFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: !Sub ${ResourceNamePrefix}-function-${Environment}
Timeout: 20
CodeUri: functions/password_policy/
Handler: app.lambda_handler
Runtime: python3.8
Role: !GetAtt CustomResourceExecutionRole.Arn
Environment:
Variables:
AWS_PARTITION: !Sub ${AWS::Partition}
AWS_ACCOUNT: !Sub ${AWS::AccountId}
TARGET_ROLE: !Sub ${ResourceNamePrefix}-role-${Environment}
SNSTopicEncryptionKey:
Type: AWS::KMS::Key
Properties:
Description: SNS topic encryption key
EnableKeyRotation: true
PendingWindowInDays: 20
KeyPolicy:
Version: '2012-10-17'
Id: Main
Statement:
- Sid: Enable IAM User Permissions
Effect: Allow
Principal:
AWS: !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:root
Action: kms:*
Resource: "*"
- Sid: Allow an external account to use this CMK
Effect: Allow
Principal:
AWS: "*"
Action:
- kms:Encrypt
- kms:Decrypt
- kms:ReEncrypt*
- kms:GenerateDataKey*
- kms:DescribeKey
Resource: "*"
Condition:
StringEquals:
aws:PrincipalOrgID: !Ref OrganizationID
SNSTopicEncryptionKeyAlias:
Type: AWS::KMS::Alias
Properties:
AliasName: alias/SNSTopicEncryption
TargetKeyId: !Ref SNSTopicEncryptionKey
PasswordPolicyTopic:
Type: AWS::SNS::Topic
Properties:
DisplayName: !Sub ${ResourceNamePrefix}-topic-${Environment}
TopicName: !Sub ${ResourceNamePrefix}-topic-${Environment}
KmsMasterKeyId: !Ref SNSTopicEncryptionKeyAlias
PasswordPolicyTopicPolicy:
Type: AWS::SNS::TopicPolicy
Properties:
PolicyDocument:
Version: 2008-10-17
Id: CrossAccountPublishAccess
Statement:
- Sid: allow-publish-from-organization-accounts
Effect: Allow
Principal:
AWS: "*"
Action:
- sns:Publish
Resource:
- !Ref PasswordPolicyTopic
Condition:
StringEquals:
aws:PrincipalOrgID: !Ref OrganizationID
Topics:
- !Ref PasswordPolicyTopic
PasswordPolicyLambdaSubscription:
Type: AWS::SNS::Subscription
Properties:
Endpoint: !GetAtt PasswordPolicyProviderFunction.Arn
Protocol: lambda
TopicArn: !Ref PasswordPolicyTopic
PasswordPolicyLambdaPermission:
Type: AWS::Lambda::Permission
Properties:
FunctionName: !Ref PasswordPolicyProviderFunction
Action: lambda:InvokeFunction
Principal: sns.amazonaws.com
SourceArn: !Ref PasswordPolicyTopic
CustomResourceExecutionRole:
Type: "AWS::IAM::Role"
Properties:
RoleName: !Sub ${ResourceNamePrefix}-role-${Environment}
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: 'lambda.amazonaws.com'
Action: sts:AssumeRole
Path: /
Policies:
- PolicyName: IAMPermissions
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- sts:AssumeRole
Resource:
- !Sub 'arn:${AWS::Partition}:iam::*:role/${ResourceNamePrefix}-role-${Environment}'
- Effect: Allow
Action:
- 'logs:CreateLogGroup'
- 'logs:CreateLogStream'
- 'logs:PutLogEvents'
Resource: "*"
CFCustomResourceStackSet:
Type: AWS::CloudFormation::StackSet
DependsOn:
- PasswordPolicyProviderFunction
- PasswordPolicyTopic
- PasswordPolicyTopicPolicy
- PasswordPolicyLambdaPermission
- PasswordPolicyLambdaSubscription
- SNSTopicEncryptionKey
- SNSTopicEncryptionKeyAlias
Properties:
AutoDeployment:
Enabled: true
RetainStacksOnAccountRemoval: false
Capabilities:
- CAPABILITY_NAMED_IAM
Description: Custom resource deployer
StackInstancesGroup:
- DeploymentTargets:
OrganizationalUnitIds:
- !Ref TargetOU
Regions:
- !Sub ${AWS::Region}
Parameters:
- ParameterKey: ResourceNamePrefix
ParameterValue: !Ref ResourceNamePrefix
- ParameterKey: TrustedRoleForCustomResources
ParameterValue: !GetAtt CustomResourceExecutionRole.Arn
- ParameterKey: PasswordPolicyTopicArn
ParameterValue: !Ref PasswordPolicyTopic
- ParameterKey: Environment
ParameterValue: !Ref Environment
Tags:
- Key: Environment
Value: !Ref Environment
PermissionModel: SERVICE_MANAGED
StackSetName: !Sub ${ResourceNamePrefix}-${Environment}
TemplateBody: |
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
ResourceNamePrefix:
Type: String
Description: String prefix for resource names
TrustedRoleForCustomResources:
Type: String
Description: The ARN of the trusted IAM role
PasswordPolicyTopicArn:
Type: String
Description: The ARN of the SNS topic for the custom password policy
Environment:
Type: String
Resources:
CFCustomResourceProviderRoleSpoke:
Type: "AWS::IAM::Role"
Properties:
RoleName: !Sub ${ResourceNamePrefix}-role-${Environment}
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
AWS: !Ref TrustedRoleForCustomResources
Action: sts:AssumeRole
Path: /
Policies:
- PolicyName: IAMPermissions
PolicyDocument:
Version: 2012-10-17
Statement:
- # PasswordPolicyPermissions
Effect: Allow
Action:
- iam:DeleteAccountPasswordPolicy
- iam:UpdateAccountPasswordPolicy
Resource: '*'
PasswordPolicy:
Type: Custom::PasswordPolicy
DependsOn:
- CFCustomResourceProviderRoleSpoke
Properties:
MinimumPasswordLength: 10
RequireSymbols: true
RequireNumbers: false
RequireUppercaseCharacters: true
RequireLowercaseCharacters: true
AllowUsersToChangePassword: true
MaxPasswordAge: 10
PasswordReusePrevention: 1
HardExpiry: true
ServiceToken: !Ref PasswordPolicyTopicArn
Outputs:
ResourceNamePrefix:
Description: Input value for stack set parameter ResourceNamePrefix
Value: !Ref ResourceNamePrefix
TrustedRoleForCustomResources:
Description: Input value for stack set parameter TrustedRoleForCustomResources
Value: !GetAtt CustomResourceExecutionRole.Arn
PasswordPolicyTopicArn:
Description: Input value for stack set parameter PasswordPolicyTopicArn
Value: !Ref PasswordPolicyTopic