-
Notifications
You must be signed in to change notification settings - Fork 8
/
rds_iam.yml
182 lines (148 loc) · 6.98 KB
/
rds_iam.yml
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
##
## Template to create a pre-provisioned RDS Postgres instance with IAM authentication.
##
## Notes:
##
## - The Postgres engine version is hardcoded at 11.7. If you want to change
## the major version, note that you'll also have to change ParameterGroup.
## - The database master user and default database are retrieved from stack
## parameters, both with default values of "postgres".
## - The master user password is generated as a Secrets Manager secret that
## is also created by this template.
## - By default, SSL is enabled.
## - The database is publicly accessible, with a security group to control
## access. This group has a single ingres rule, allowing access from an
## IP address (in CIDR format) passed as a parameter.
##
AWSTemplateFormatVersion: "2010-09-09"
Description: "Example RDS instance"
Parameters:
ServerName:
Description: "The name of the database server (also used for related resources)"
Type: "String"
InstanceClass:
Description: "Database compute engine"
Type: String
Default: "db.t3.medium"
StorageSize:
Description: "Database storage size, in gigabytes"
Type: String
Default: "50"
VpcId:
Description: "VPC where the database will be deployed"
Type: "AWS::EC2::VPC::Id"
SubnetIds:
Description: "Allowed subnets for database deployment (typically private)"
Type: "List<AWS::EC2::Subnet::Id>"
AllowedIP:
Description: "An IP address allowed to connect to the database (in CIDR format)"
Type: "String"
MasterUserName:
Description: "The name of the database master user"
Type: "String"
Default: "postgres"
DefaultDatabaseName:
Description: "The name of the default database for the instance"
Type: "String"
Default: "postgres"
Resources:
##
## Networking
##
SecurityGroup:
Type: "AWS::EC2::SecurityGroup"
Properties:
GroupName: !Sub "DatabaseSecurityGroup-${ServerName}"
GroupDescription: "Allows access to the database (nominally from application)"
VpcId: !Ref VpcId
SecurityGroupIngress:
- Description: "Access from user network"
IpProtocol: "tcp"
FromPort: 5432
ToPort: 5432
CidrIp: !Ref AllowedIP
SubnetGroup:
Type: "AWS::RDS::DBSubnetGroup"
Properties:
DBSubnetGroupName: !Ref ServerName
DBSubnetGroupDescription: !Sub "Managed by CloudFormation: ${AWS::StackName}"
SubnetIds: !Ref SubnetIds
##
## Secrets Manager
##
## Note: while this template is used for a database server that supports IAM authentication,
## Secrets Manager remains the best way to configure that server's master user.
##
MasterUser:
Type: "AWS::SecretsManager::Secret"
Properties:
Name: !Sub "${ServerName}-MasterUser"
Description: !Sub "RDS master username and password"
GenerateSecretString:
SecretStringTemplate: !Sub |
{
"username": "${MasterUserName}",
"database": "${DefaultDatabaseName}"
}
GenerateStringKey: "password"
ExcludePunctuation: true # easier to select for those times that you need to copy/paste
PasswordLength: 64 # double the default length to compensate for limited characters
DatabaseAttachment:
Type: "AWS::SecretsManager::SecretTargetAttachment"
Properties:
SecretId: !Ref MasterUser
TargetId: !Ref Instance
TargetType: "AWS::RDS::DBInstance"
##
## Database
##
ParameterGroup:
Type: "AWS::RDS::DBParameterGroup"
Properties:
Description: !Sub "managed by CloudFormation: ${AWS::StackName}"
Family: "postgres11"
Parameters:
ssl: "1"
Instance:
Type: "AWS::RDS::DBInstance"
Properties:
DBInstanceIdentifier: !Ref ServerName
Engine: "postgres"
EngineVersion: "11.7"
DBParameterGroupName: !Ref ParameterGroup
DBInstanceClass: !Ref InstanceClass
AllocatedStorage: !Ref StorageSize
StorageType: "gp2"
StorageEncrypted: true
MasterUsername: !Sub "{{resolve:secretsmanager:${MasterUser}:SecretString:username}}"
MasterUserPassword: !Sub "{{resolve:secretsmanager:${MasterUser}:SecretString:password}}"
DBName: !Sub "{{resolve:secretsmanager:${MasterUser}:SecretString:database}}"
EnableIAMDatabaseAuthentication: true
DBSubnetGroupName: !Ref SubnetGroup
PubliclyAccessible: true
VPCSecurityGroups: [ !Ref SecurityGroup ]
PreferredMaintenanceWindow: "Sun:06:00-Sun:06:59"
AllowMajorVersionUpgrade: false
AutoMinorVersionUpgrade: true
PreferredBackupWindow: "05:00-05:30"
BackupRetentionPeriod: 7
CopyTagsToSnapshot: true
##
## Outputs
##
Outputs:
MasterUserSecretArn:
Description: "The ARN of the secret containing database user and password"
Value: !Ref MasterUser
PGHOST:
Description: "The database instance hostname"
Value: !GetAtt Instance.Endpoint.Address
PGPORT:
Description: "The database instance port"
Value: !GetAtt Instance.Endpoint.Port
PGUSER:
Description: "The database instance master user"
Value: !Ref MasterUserName
PGDATABASE:
Description: "The database instance default database"
Value: !Ref DefaultDatabaseName