@@ -84,6 +84,111 @@ resource "aws_dynamodb_table" "deployments" {
84
84
projection_type = " INCLUDE"
85
85
non_key_attributes = [" CreateDate" , " DeploymentAlias" , " DeploymentId" , " Status" ]
86
86
}
87
+
88
+ tags = var. tags
89
+ }
90
+
91
+ # ####################
92
+ # CloudFormation Role
93
+ # ####################
94
+
95
+ # Policy that controls which actions can be performed when CloudFormation
96
+ # creates a substack (from CDK)
97
+ data "aws_iam_policy_document" "cloudformation_permission" {
98
+ # Allow CloudFormation to publish status changes to the SNS queue
99
+ statement {
100
+ effect = " Allow"
101
+ actions = [
102
+ " sns:Publish"
103
+ ]
104
+ resources = [module . deploy_controller . sns_topic_arn ]
105
+ }
106
+
107
+ # Allow CloudFormation to access the lambda content
108
+ statement {
109
+ effect = " Allow"
110
+ actions = [
111
+ " s3:GetObject"
112
+ ]
113
+ resources = [
114
+ module . statics_deploy . static_bucket_arn ,
115
+ " ${ module . statics_deploy . static_bucket_arn } /*"
116
+ ]
117
+ }
118
+
119
+ # Stack creation
120
+ statement {
121
+ effect = " Allow"
122
+ actions = [
123
+ # TODO: Restrict the API Gateway action more
124
+ " apigateway:*" ,
125
+ " iam:CreateRole" ,
126
+ " iam:GetRole" ,
127
+ " iam:GetRolePolicy" ,
128
+ " iam:PassRole" ,
129
+ " iam:PutRolePolicy" ,
130
+ " iam:TagRole" ,
131
+ " lambda:AddPermission" ,
132
+ " lambda:CreateFunction" ,
133
+ " lambda:CreateFunctionUrlConfig" ,
134
+ " lambda:GetFunctionUrlConfig" ,
135
+ " lambda:GetFunction" ,
136
+ " lambda:TagResource" ,
137
+ " logs:CreateLogGroup" ,
138
+ " logs:PutRetentionPolicy" ,
139
+ " logs:TagLogGroup"
140
+ ]
141
+ resources = [" *" ]
142
+ }
143
+
144
+ # Stack deletion
145
+ statement {
146
+ effect = " Allow"
147
+ actions = [
148
+ " apigateway:*" ,
149
+ " iam:DeleteRole" ,
150
+ " iam:DeleteRolePolicy" ,
151
+ " iam:UntagRole" ,
152
+ " lambda:DeleteFunction" ,
153
+ " lambda:DeleteFunctionUrlConfig" ,
154
+ " lambda:RemovePermission" ,
155
+ " lambda:UntagResource" ,
156
+ " logs:DeleteLogGroup" ,
157
+ " logs:DeleteRetentionPolicy" ,
158
+ " logs:UntagLogGroup"
159
+ ]
160
+ resources = [" *" ]
161
+ }
162
+ }
163
+
164
+ data "aws_iam_policy_document" "cloudformation_permission_assume_role" {
165
+ statement {
166
+ effect = " Allow"
167
+ actions = [" sts:AssumeRole" ]
168
+
169
+ principals {
170
+ type = " Service"
171
+ identifiers = [" cloudformation.amazonaws.com" ]
172
+ }
173
+ }
174
+ }
175
+
176
+ resource "aws_iam_policy" "cloudformation_permission" {
177
+ name = " cloudformation-control"
178
+ path = " /${ var . deployment_name } /"
179
+ description = " Managed by Terraform Next.js"
180
+ policy = data. aws_iam_policy_document . cloudformation_permission . json
181
+
182
+ tags = var. tags
183
+ }
184
+
185
+ resource "aws_iam_role" "cloudformation_permission" {
186
+ name = " cloudformation-control"
187
+ path = " /${ var . deployment_name } /"
188
+ assume_role_policy = data. aws_iam_policy_document . cloudformation_permission_assume_role . json
189
+ managed_policy_arns = [
190
+ aws_iam_policy . cloudformation_permission . arn
191
+ ]
87
192
}
88
193
89
194
# ##################
@@ -125,6 +230,8 @@ module "statics_deploy" {
125
230
dynamodb_table_deployments_arn = aws_dynamodb_table. deployments . arn
126
231
dynamodb_table_deployments_name = aws_dynamodb_table. deployments . id
127
232
233
+ cloudformation_role_arn = aws_iam_role. cloudformation_permission . arn
234
+
128
235
lambda_role_permissions_boundary = var. lambda_role_permissions_boundary
129
236
130
237
deployment_name = var. deployment_name
0 commit comments