summaryrefslogtreecommitdiff
path: root/stacks/blog.tpl
blob: 1ee89c1e5cf65aca1e9b606b00faf8d792a4cce6 (plain)
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
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
[+ autogen5 template -*- mode: json -*- +]
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "Blog of kennyballou.com",
    "Parameters": {
        "DomainName": {
            "Description": "Domain name of site",
            "Type": "String",
            "Default": "kennyballou.com"
        },
        "BlogBucketName": {
            "Description": "Name of S3 Bucket",
            "Type": "String",
            "Default": "blog.kennyballou.com"
        },
        "CloudFrontHostedZone": {
            "Description": "CloudFront Hosted Zone ID",
            "Type": "String",
            "Default": "Z2FDTNDATAQYW2"
        }
    },
    "Resources": {
        "HostedZone": {
            "Type": "AWS::Route53::HostedZone",
            "Properties": {
                "Name": {"Ref": "DomainName"}
            }
        },
        "BlogContentBucket": {
            "Type": "AWS::S3::Bucket",
            "Properties": {
                "AccessControl": "Private",
                "BucketName": {"Ref": "BlogBucketName"},
                "LifecycleConfiguration": {
                    "Rules": [
                        {
                            "NoncurrentVersionExpirationInDays": 90,
                            "Status": "Enabled"
                        }
                    ]
                },
                "VersioningConfiguration": {
                    "Status": "Enabled"
                },
                "WebsiteConfiguration": {
                    "IndexDocument": "index.html",
                    "ErrorDocument": "404.html"
                }
            }
        },
        "BlogContentBucketPolicy": {
            "Type": "AWS::S3::BucketPolicy",
            "Properties": {
                "Bucket": {"Ref": "BlogContentBucket"},
                "PolicyDocument": {
                    "Statement": [
                        {
                            "Action": ["s3:GetObject"],
                            "Effect": "Allow",
                            "Resource": [
                                {"Fn::Join": ["/", [
                                    {"Fn::GetAtt": [
                                        "BlogContentBucket", "Arn"]},
                                    "*"
                                ]]}
                            ],
                            "Principal": {
                                "CanonicalUser": {"Fn::GetAtt": [
                                    "OriginAccessId",
                                    "S3CanonicalUserId"]}
                            }
                        }
                    ]
                }
            }
        },
        "SSLCertificate": {
            "Type": "AWS::CertificateManager::Certificate",
            "Properties": {
                "DomainName": {"Ref": "DomainName"}
            }
        },
        "OriginAccessId": {
            "Type": "AWS::CloudFront::CloudFrontOriginAccessIdentity",
            "Properties": {
                "CloudFrontOriginAccessIdentityConfig": {
                    "Comment": "S3 Bucket Access"
                }
            }
        },
        "CFDistribution": {
            "Type": "AWS::CloudFront::Distribution",
            "Properties": {
                "DistributionConfig": {
                    "Aliases": [
                        {"Ref": "DomainName"}
                    ],
                    "DefaultRootObject": "index.html",
                    "Enabled": true,
                    "IPV6Enabled": true,
                    "HttpVersion": "http2",
                    "DefaultCacheBehavior": {
                        "TargetOriginId": {"Fn::Join": [".", [
                            "s3",
                            {"Ref": "BlogBucketName"}]]},
                        "ViewerProtocolPolicy": "redirect-to-https",
                        "MinTTL": 0,
                        "DefaultTTL": 3600,
                        "AllowedMethods": ["HEAD", "GET"],
                        "CachedMethods": ["HEAD", "GET"],
                        "ForwardedValues": {
                            "QueryString": true,
                            "Cookies": {
                                "Forward": "none"
                            }
                        },
                        "LambdaFunctionAssociations": [
                            {
                                "EventType": "origin-request",
                                "LambdaFunctionARN": {
                                    "Ref": "URIRewriteLambdaVersion"
                                }
                            }
                        ]
                    },
                    "Origins": [
                        {
                            "S3OriginConfig": {
                                "OriginAccessIdentity": {"Fn::Join": ["/", [
                                    "origin-access-identity/cloudfront",
                                    {"Ref": "OriginAccessId"}
                                ]]}
                            },
                            "DomainName": {"Fn::Join": [".", [
                                {"Ref": "BlogBucketName"},
                                "s3.amazonaws.com"]]},
                            "Id": {"Fn::Join": [".", [
                                "s3",
                                {"Ref": "BlogBucketName"}]]}
                        }
                    ],
                    "PriceClass": "PriceClass_100",
                    "Restrictions": {
                        "GeoRestriction": {
                            "RestrictionType": "none",
                            "Locations": []
                        }
                    },
                    "ViewerCertificate": {
                        "SslSupportMethod": "sni-only",
                        "MinimumProtocolVersion": "TLSv1.2_2018",
                        "AcmCertificateArn": {"Ref": "SSLCertificate"}
                    }
                }
            }
        },
        "BlogAliasRecord": {
            "Type": "AWS::Route53::RecordSet",
            "Properties": {
                "AliasTarget": {
                    "DNSName": {"Fn::GetAtt": ["CFDistribution", "DomainName"]},
                    "HostedZoneId": {"Ref": "CloudFrontHostedZone"}
                },
                "HostedZoneId": {"Ref": "HostedZone"},
                "Name": {"Ref": "DomainName"},
                "Type": "A"
            }
        },
        "URIRewriteLambdaLogGroup": {
            "Type": "AWS::Logs::LogGroup",
            "Properties": {
                "LogGroupName": "/aws/lambda/us-east-1.blog-kennyballou-URIRewriteLambdaFunction-5MXFF1KIA87D",
                "RetentionInDays": 90
            }
        },
        "URIRewriteLambdaFunction": {
            "Type": "AWS::Lambda::Function",
            "Properties": {
                "Description": "Lambda Function performing URI rewriting",
                "Code": {
                    "ZipFile": [+ INCLUDE "uri-rewrite.in" +]
                },
                "Handler": "index.handler",
                "MemorySize": 128,
                "Role": {"Fn::GetAtt": ["URIRewriteLambdaRole", "Arn"]},
                "Runtime": "python3.7",
                "Tags": [
                    {"Key": "Domain", "Value": {"Ref": "DomainName"}}
                ]
            }
        },
        "URIRewriteLambdaRole": {
            "Type": "AWS::IAM::Role",
            "Properties": {
                "AssumeRolePolicyDocument": {
                    "Version": "2012-10-17",
                    "Statement": [
                        {
                            "Effect": "Allow",
                            "Action": "sts:AssumeRole",
                            "Principal": {
                                "Service": [
                                    "edgelambda.amazonaws.com",
                                    "lambda.amazonaws.com"
                                ]
                            }
                        }
                    ]
                },
                "Policies": [
                    {
                        "PolicyName": "GrantCloudwatchLogAccess",
                        "PolicyDocument": {
                            "Version": "2012-10-17",
                            "Statement": [
                                {
                                    "Effect": "Allow",
                                    "Action": [
                                        "logs:CreateLogStream",
                                        "logs:PutLogEvents"
                                    ],
                                    "Resource": [
                                        {"Fn::GetAtt": ["URIRewriteLambdaLogGroup", "Arn"]},
                                        {"Fn::Join": ["", [
                                            {"Fn::GetAtt": ["URIRewriteLambdaLogGroup", "Arn"]},
                                            "/*"]]}
                                    ]
                                }
                            ]
                        }
                    }
                ]
            }
        },
        "URIRewriteLambdaVersion": {
            "Type": "AWS::Lambda::Version",
            "Properties": {
                "FunctionName": {"Fn::GetAtt": [
                    "URIRewriteLambdaFunction", "Arn"]},
                "Description": "Lambda Function performing URI rewriting"
            }
        },
        "BlogContentRepository": {
            "Type": "AWS::CodeCommit::Repository",
            "Properties": {
                "RepositoryDescription": "Blog Content Repository",
                "RepositoryName": {"Ref": "BlogBucketName"},
                "Triggers": [
                    {
                        "Name": "Build and Deploy",
                        "Branches": ["master"],
                        "DestinationArn": {"Ref": "CodeCommitEventsSnsTopic"},
                        "Events": ["all"]
                    }
                ]
            }
        },
        "BlogCodeBuildLogGroup": {
            "Type": "AWS::Logs::LogGroup",
            "Properties": {
                "LogGroupName": {"Fn::Join": ["-", [
                    "/aws/codebuild/CodeBuild",
                    {"Ref": "BlogBucketName"}]]},
                "RetentionInDays": 14
            }
        },
        "BlogCodeBuild": {
            "Type": "AWS::CodeBuild::Project",
            "Properties": {
                "Name": "BlogCI",
                "Description": "Blog Build Project",
                "Artifacts": {
                    "Type": "NO_ARTIFACTS"
                },
                "Environment": {
                    "ComputeType": "BUILD_GENERAL1_SMALL",
                    "Image": "kennyballou/debian-pandoc:latest",
                    "Type": "LINUX_CONTAINER"
                },
                "LogsConfig": {
                    "CloudWatchLogs": {
                        "GroupName": {"Fn::Join": ["-", [
                            "/aws/codebuild/CodeBuild",
                            {"Ref": "BlogBucketName"}
                        ]]},
                        "Status": "ENABLED"
                    }
                },
                "ServiceRole": {"Ref": "CodeBuildIamServiceRole"},
                "Source": {
                    "Type": "CODECOMMIT",
                    "Location": {"Fn::GetAtt": ["BlogContentRepository",
                                                "CloneUrlHttp"]}
                }
            }
        },
        "CodeCommitEventsSnsTopic": {
            "Type": "AWS::SNS::Topic",
            "Properties": {
                "DisplayName": "CodeCommit Events",
                "TopicName": "codecommit-events"
            }
        },
        "CodeBuildIamManagedPolicy": {
            "Type": "AWS::IAM::ManagedPolicy",
            "Properties": {
                "Description": "CodeBuild Service Policy",
                "PolicyDocument": [+ INCLUDE "codebuild-service-role.json.in" +]
            }
        },
        "CodeBuildIamServiceRole": {
            "Type": "AWS::IAM::Role",
            "Properties": {
                "AssumeRolePolicyDocument": {
                    "Version": "2012-10-17",
                    "Statement": [
                        {
                            "Action": "sts:AssumeRole",
                            "Principal": {
                                "Service": "codebuild.amazonaws.com"
                            },
                            "Effect": "Allow"
                        }
                    ]
                },
                "ManagedPolicyArns": [
                    {"Ref": "CodeBuildIamManagedPolicy"}
                ]
            }
        },
        "LambdaCodeCommitBuildIamManagedPolicy": {
            "Type": "AWS::IAM::ManagedPolicy",
            "Properties": {
                "Description": "Lambda CodeCommit-Build Execution Policy",
                "PolicyDocument": [+ INCLUDE "codecommit-build-policy.json.in" +]
            }
        },
        "LambdaCodeCommitBuildIamServiceRole": {
            "Type": "AWS::IAM::Role",
            "Properties": {
                "AssumeRolePolicyDocument": {
                    "Version": "2012-10-17",
                    "Statement": [
                        {
                            "Action": "sts:AssumeRole",
                            "Principal": {
                                "Service": "lambda.amazonaws.com"
                            },
                            "Effect": "Allow"
                        }
                    ]
                },
                "ManagedPolicyArns": [
                    {"Ref": "LambdaCodeCommitBuildIamManagedPolicy"}
                ]
            }
        },
        "CodeCommitBuildLambdaPermission": {
            "Type": "AWS::Lambda::Permission",
            "Properties": {
                "FunctionName": {"Fn::GetAtt": [
                    "CodeCommitBuildLambdaFunction", "Arn"]},
                "Action": "lambda:InvokeFunction",
                "Principal": "sns.amazonaws.com",
                "SourceArn": {"Ref": "CodeCommitEventsSnsTopic"}
            }
        },
        "CodeCommitBuildLambdaFunction": {
            "Type": "AWS::Lambda::Function",
            "Properties": {
                "FunctionName": "codecommit-build-bae089e8-3871-4067-9a3d-bac114f08438",
                "Code": {
                    "ZipFile": [+ INCLUDE "codecommit-build.py.in" +]
                },
                "Description": "Start builds on commit events",
                "Handler": "index.handler",
                "MemorySize": 128,
                "Timeout": 3,
                "Role": {"Fn::GetAtt": [
                    "LambdaCodeCommitBuildIamServiceRole", "Arn"]},
                "Runtime": "python3.7"
            }
        },
        "CodeCommitBuildSnsSubscription": {
            "Type": "AWS::SNS::Subscription",
            "Properties": {
                "Protocol": "lambda",
                "Endpoint": {"Fn::GetAtt": [
                    "CodeCommitBuildLambdaFunction", "Arn"]},
                "TopicArn": {"Ref": "CodeCommitEventsSnsTopic"}
            }
        }
    }
}