forked from cjdev2/aws-acm-certificate-request-approver
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cf-validation-approver.yaml
122 lines (113 loc) · 3.86 KB
/
cf-validation-approver.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
AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Description: ACM certificate request approver
Parameters:
DomainName:
Description: The domain name to automatically approve certificates for
Type: String
MinLength: 1
Resources:
# SES is not currently supported by CloudFormation, so we need to use a custom
# resource to manage SES resources, instead. This allows us to create an SES
# receipt rule below.
SESCustomResourceFunction:
Type: AWS::Serverless::Function
Properties:
Runtime: nodejs4.3
Handler: ses-cloudformation.handler
Timeout: 30
Role: !GetAtt SESCustomResourceFunctionRole.Arn
CodeUri: ./lambda
SESCustomResourceFunctionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: 'sts:AssumeRole'
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'
- 'arn:aws:iam::aws:policy/AmazonSESFullAccess'
# This function will actually handle emails delivered to SES asking for
# certificate ownership validation.
Function:
Type: AWS::Serverless::Function
Properties:
Runtime: nodejs4.3
Handler: index.handler
Timeout: 10
Role: !GetAtt FunctionRole.Arn
Environment:
Variables:
S3_BUCKET: !Ref EmailBucket
CodeUri: ./lambda
# Our function needs access to S3, since that’s where the emails are stored.
FunctionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: 'sts:AssumeRole'
ManagedPolicyArns: ['arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole']
Policies:
- PolicyName: access-to-email-bucket
PolicyDocument:
Statement:
Effect: Allow
Action: 's3:GetObject'
Resource: !Sub arn:aws:s3:::${EmailBucket}/*
# Additionally, SES needs permission to call our function.
FunctionSESPermission:
Type: AWS::Lambda::Permission
Properties:
FunctionName: !GetAtt Function.Arn
Principal: ses.amazonaws.com
SourceAccount: !Ref AWS::AccountId
Action: 'lambda:InvokeFunction'
# We need a bucket where SES will store inbound emails that our Lambda
# function can fetch and process.
EmailBucket:
Type: AWS::S3::Bucket
# The bucket must be accessible by SES.
EmailBucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref EmailBucket
PolicyDocument:
Statement:
Effect: Allow
Principal:
Service: ses.amazonaws.com
Action: 's3:PutObject'
Resource: !Sub arn:aws:s3:::${EmailBucket}/*
# This custom resource creates an SES receipt rule to process inbound emails.
# It stores the email in an S3 bucket, then triggers our Lambda function.
ReceiptRule:
Type: Custom::ReceiptRule
DependsOn: FunctionSESPermission # necessary because SES complains if it can’t call the lambda on creation
Properties:
ServiceToken: !GetAtt SESCustomResourceFunction.Arn
RuleSetName: default-rule-set
Rule:
Recipients: [!Sub 'hostmaster@${DomainName}']
Actions:
- S3Action:
BucketName: !Ref EmailBucket
- LambdaAction:
FunctionArn: !GetAtt Function.Arn
InvocationType: Event
# Finally, we need to create an MX record for our hosted zone that will
# actually direct emails to SES’s SMTP servers.
MXRecord:
Type: AWS::Route53::RecordSet
Properties:
HostedZoneName: !Sub ${DomainName}.
Name: !Ref DomainName
Type: MX
TTL: 300
ResourceRecords: [!Sub '10 inbound-smtp.${AWS::Region}.amazonaws.com']