Skip to content

Commit e215164

Browse files
Add create_before_destroy for parameter group. Make subnet group optional (#110)
* Update parameter and option groups. Update tests * Update parameter and option groups. Update tests * Update parameter and option groups. Update tests * Auto Format * Update parameter and option groups. Update tests Co-authored-by: cloudpossebot <[email protected]>
1 parent caebe2f commit e215164

File tree

13 files changed

+161
-62
lines changed

13 files changed

+161
-62
lines changed

.github/mergify.yml

+7
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,10 @@ pull_request_rules:
5656
changes_requested: true
5757
approved: true
5858
message: "This Pull Request has been updated, so we're dismissing all reviews."
59+
60+
- name: "close Pull Requests without files changed"
61+
conditions:
62+
- "#files=0"
63+
actions:
64+
close:
65+
message: "This pull request has been automatically closed by Mergify because there are no longer any changes."

.github/workflows/auto-format.yml

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ on:
66
jobs:
77
auto-format:
88
runs-on: ubuntu-latest
9-
container: cloudposse/build-harness:slim-latest
9+
container: cloudposse/build-harness:latest
1010
steps:
1111
# Checkout the pull request branch
1212
# "An action in a workflow run can’t trigger a new workflow run. For example, if an action pushes code using
@@ -29,6 +29,8 @@ jobs:
2929
- name: Auto Format
3030
if: github.event.pull_request.state == 'open'
3131
shell: bash
32+
env:
33+
GITHUB_TOKEN: "${{ secrets.PUBLIC_REPO_ACCESS_TOKEN }}"
3234
run: make BUILD_HARNESS_PATH=/build-harness PACKAGES_PREFER_HOST=true -f /build-harness/templates/Makefile.build-harness pr/auto-format/host
3335

3436
# Commit changes (if any) to the PR branch

.github/workflows/auto-release.yml

+15-9
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,23 @@ name: auto-release
33
on:
44
push:
55
branches:
6-
- master
6+
- master
77

88
jobs:
99
publish:
1010
runs-on: ubuntu-latest
1111
steps:
12-
# Drafts your next Release notes as Pull Requests are merged into "master"
13-
- uses: release-drafter/release-drafter@v5
14-
with:
15-
publish: true
16-
prerelease: false
17-
config-name: auto-release.yml
18-
env:
19-
GITHUB_TOKEN: ${{ secrets.PUBLIC_REPO_ACCESS_TOKEN }}
12+
# Get PR from merged commit to master
13+
- uses: actions-ecosystem/action-get-merged-pull-request@v1
14+
id: get-merged-pull-request
15+
with:
16+
github_token: ${{ secrets.PUBLIC_REPO_ACCESS_TOKEN }}
17+
# Drafts your next Release notes as Pull Requests are merged into "master"
18+
- uses: release-drafter/release-drafter@v5
19+
if: "!contains(steps.get-merged-pull-request.outputs.labels, 'no-release')"
20+
with:
21+
publish: true
22+
prerelease: false
23+
config-name: auto-release.yml
24+
env:
25+
GITHUB_TOKEN: ${{ secrets.PUBLIC_REPO_ACCESS_TOKEN }}

LICENSE

+1-1
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@
186186
same "printed page" as the copyright notice for easier
187187
identification within third-party archives.
188188

189-
Copyright 2017-2019 Cloud Posse, LLC
189+
Copyright 2017-2021 Cloud Posse, LLC
190190

191191
Licensed under the Apache License, Version 2.0 (the "License");
192192
you may not use this file except in compliance with the License.

README.md

+4-2
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ Available targets:
224224
| associate\_security\_group\_ids | The IDs of the existing security groups to associate with the DB instance | `list(string)` | `[]` | no |
225225
| attributes | Additional attributes (e.g. `1`) | `list(string)` | `[]` | no |
226226
| auto\_minor\_version\_upgrade | Allow automated minor version upgrade (e.g. from Postgres 9.5.3 to Postgres 9.5.4) | `bool` | `true` | no |
227+
| availability\_zone | The AZ for the RDS instance. Specify one of `subnet_ids`, `db_subnet_group_name` or `availability_zone`. If `availability_zone` is provided, the instance will be placed into the default VPC or EC2 Classic | `string` | `null` | no |
227228
| backup\_retention\_period | Backup retention period in days. Must be > 0 to enable backups | `number` | `0` | no |
228229
| backup\_window | When AWS can perform DB snapshots, can't overlap with maintenance window | `string` | `"22:00-03:00"` | no |
229230
| ca\_cert\_identifier | The identifier of the CA certificate for the DB instance | `string` | `"rds-ca-2019"` | no |
@@ -236,6 +237,7 @@ Available targets:
236237
| db\_options | A list of DB options to apply with an option group. Depends on DB engine | <pre>list(object({<br> db_security_group_memberships = list(string)<br> option_name = string<br> port = number<br> version = string<br> vpc_security_group_memberships = list(string)<br><br> option_settings = list(object({<br> name = string<br> value = string<br> }))<br> }))</pre> | `[]` | no |
237238
| db\_parameter | A list of DB parameters to apply. Note that parameters may differ from a DB family to another | <pre>list(object({<br> apply_method = string<br> name = string<br> value = string<br> }))</pre> | `[]` | no |
238239
| db\_parameter\_group | The DB parameter group family name. The value depends on DB engine used. See [DBParameterGroupFamily](https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_CreateDBParameterGroup.html#API_CreateDBParameterGroup_RequestParameters) for instructions on how to retrieve applicable value. | `string` | n/a | yes |
240+
| db\_subnet\_group\_name | Name of DB subnet group. DB instance will be created in the VPC associated with the DB subnet group. Specify one of `subnet_ids`, `db_subnet_group_name` or `availability_zone` | `string` | `null` | no |
239241
| deletion\_protection | Set to true to enable deletion protection on the RDS instance | `bool` | `false` | no |
240242
| delimiter | Delimiter to be used between `namespace`, `environment`, `stage`, `name` and `attributes`.<br>Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. | `string` | `null` | no |
241243
| dns\_zone\_id | The ID of the DNS Zone in Route53 where a new DNS record will be created for the DB host name | `string` | `""` | no |
@@ -276,7 +278,7 @@ Available targets:
276278
| stage | Stage, e.g. 'prod', 'staging', 'dev', OR 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no |
277279
| storage\_encrypted | (Optional) Specifies whether the DB instance is encrypted. The default is false if not specified | `bool` | `true` | no |
278280
| storage\_type | One of 'standard' (magnetic), 'gp2' (general purpose SSD), or 'io1' (provisioned IOPS SSD) | `string` | `"standard"` | no |
279-
| subnet\_ids | List of subnets for the DB | `list(string)` | n/a | yes |
281+
| subnet\_ids | List of subnet IDs for the DB. DB instance will be created in the VPC associated with the DB subnet group provisioned using the subnet IDs. Specify one of `subnet_ids`, `db_subnet_group_name` or `availability_zone` | `list(string)` | `[]` | no |
280282
| tags | Additional tags (e.g. `map('BusinessUnit','XYZ')` | `map(string)` | `{}` | no |
281283
| vpc\_id | VPC ID the DB instance will be created in | `string` | n/a | yes |
282284

@@ -292,7 +294,7 @@ Available targets:
292294
| option\_group\_id | ID of the Option Group |
293295
| parameter\_group\_id | ID of the Parameter Group |
294296
| security\_group\_id | ID of the Security Group |
295-
| subnet\_group\_id | ID of the Subnet Group |
297+
| subnet\_group\_id | ID of the created Subnet Group |
296298
<!-- markdownlint-restore -->
297299

298300

docs/terraform.md

+4-2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
| associate\_security\_group\_ids | The IDs of the existing security groups to associate with the DB instance | `list(string)` | `[]` | no |
4646
| attributes | Additional attributes (e.g. `1`) | `list(string)` | `[]` | no |
4747
| auto\_minor\_version\_upgrade | Allow automated minor version upgrade (e.g. from Postgres 9.5.3 to Postgres 9.5.4) | `bool` | `true` | no |
48+
| availability\_zone | The AZ for the RDS instance. Specify one of `subnet_ids`, `db_subnet_group_name` or `availability_zone`. If `availability_zone` is provided, the instance will be placed into the default VPC or EC2 Classic | `string` | `null` | no |
4849
| backup\_retention\_period | Backup retention period in days. Must be > 0 to enable backups | `number` | `0` | no |
4950
| backup\_window | When AWS can perform DB snapshots, can't overlap with maintenance window | `string` | `"22:00-03:00"` | no |
5051
| ca\_cert\_identifier | The identifier of the CA certificate for the DB instance | `string` | `"rds-ca-2019"` | no |
@@ -57,6 +58,7 @@
5758
| db\_options | A list of DB options to apply with an option group. Depends on DB engine | <pre>list(object({<br> db_security_group_memberships = list(string)<br> option_name = string<br> port = number<br> version = string<br> vpc_security_group_memberships = list(string)<br><br> option_settings = list(object({<br> name = string<br> value = string<br> }))<br> }))</pre> | `[]` | no |
5859
| db\_parameter | A list of DB parameters to apply. Note that parameters may differ from a DB family to another | <pre>list(object({<br> apply_method = string<br> name = string<br> value = string<br> }))</pre> | `[]` | no |
5960
| db\_parameter\_group | The DB parameter group family name. The value depends on DB engine used. See [DBParameterGroupFamily](https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_CreateDBParameterGroup.html#API_CreateDBParameterGroup_RequestParameters) for instructions on how to retrieve applicable value. | `string` | n/a | yes |
61+
| db\_subnet\_group\_name | Name of DB subnet group. DB instance will be created in the VPC associated with the DB subnet group. Specify one of `subnet_ids`, `db_subnet_group_name` or `availability_zone` | `string` | `null` | no |
6062
| deletion\_protection | Set to true to enable deletion protection on the RDS instance | `bool` | `false` | no |
6163
| delimiter | Delimiter to be used between `namespace`, `environment`, `stage`, `name` and `attributes`.<br>Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. | `string` | `null` | no |
6264
| dns\_zone\_id | The ID of the DNS Zone in Route53 where a new DNS record will be created for the DB host name | `string` | `""` | no |
@@ -97,7 +99,7 @@
9799
| stage | Stage, e.g. 'prod', 'staging', 'dev', OR 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no |
98100
| storage\_encrypted | (Optional) Specifies whether the DB instance is encrypted. The default is false if not specified | `bool` | `true` | no |
99101
| storage\_type | One of 'standard' (magnetic), 'gp2' (general purpose SSD), or 'io1' (provisioned IOPS SSD) | `string` | `"standard"` | no |
100-
| subnet\_ids | List of subnets for the DB | `list(string)` | n/a | yes |
102+
| subnet\_ids | List of subnet IDs for the DB. DB instance will be created in the VPC associated with the DB subnet group provisioned using the subnet IDs. Specify one of `subnet_ids`, `db_subnet_group_name` or `availability_zone` | `list(string)` | `[]` | no |
101103
| tags | Additional tags (e.g. `map('BusinessUnit','XYZ')` | `map(string)` | `{}` | no |
102104
| vpc\_id | VPC ID the DB instance will be created in | `string` | n/a | yes |
103105

@@ -113,5 +115,5 @@
113115
| option\_group\_id | ID of the Option Group |
114116
| parameter\_group\_id | ID of the Parameter Group |
115117
| security\_group\_id | ID of the Security Group |
116-
| subnet\_group\_id | ID of the Subnet Group |
118+
| subnet\_group\_id | ID of the created Subnet Group |
117119
<!-- markdownlint-restore -->

examples/complete/main.tf

+32-25
Original file line numberDiff line numberDiff line change
@@ -3,44 +3,49 @@ provider "aws" {
33
}
44

55
module "vpc" {
6-
source = "cloudposse/vpc/aws"
7-
version = "0.18.2"
8-
context = module.this.context
6+
source = "cloudposse/vpc/aws"
7+
version = "0.21.1"
8+
99
cidr_block = "172.16.0.0/16"
10+
11+
context = module.this.context
1012
}
1113

1214
module "subnets" {
13-
source = "cloudposse/dynamic-subnets/aws"
14-
version = "0.34.0"
15-
context = module.this.context
15+
source = "cloudposse/dynamic-subnets/aws"
16+
version = "0.38.0"
17+
1618
availability_zones = var.availability_zones
1719
vpc_id = module.vpc.vpc_id
1820
igw_id = module.vpc.igw_id
1921
cidr_block = module.vpc.vpc_cidr_block
2022
nat_gateway_enabled = false
2123
nat_instance_enabled = false
24+
25+
context = module.this.context
2226
}
2327

2428
module "rds_instance" {
25-
source = "../../"
26-
context = module.this.context
27-
database_name = var.database_name
28-
database_user = var.database_user
29-
database_password = var.database_password
30-
database_port = var.database_port
31-
multi_az = var.multi_az
32-
storage_type = var.storage_type
33-
allocated_storage = var.allocated_storage
34-
storage_encrypted = var.storage_encrypted
35-
engine = var.engine
36-
engine_version = var.engine_version
37-
instance_class = var.instance_class
38-
db_parameter_group = var.db_parameter_group
39-
publicly_accessible = var.publicly_accessible
40-
vpc_id = module.vpc.vpc_id
41-
subnet_ids = module.subnets.private_subnet_ids
42-
security_group_ids = [module.vpc.vpc_default_security_group_id]
43-
apply_immediately = var.apply_immediately
29+
source = "../../"
30+
database_name = var.database_name
31+
database_user = var.database_user
32+
database_password = var.database_password
33+
database_port = var.database_port
34+
multi_az = var.multi_az
35+
storage_type = var.storage_type
36+
allocated_storage = var.allocated_storage
37+
storage_encrypted = var.storage_encrypted
38+
engine = var.engine
39+
engine_version = var.engine_version
40+
instance_class = var.instance_class
41+
db_parameter_group = var.db_parameter_group
42+
publicly_accessible = var.publicly_accessible
43+
vpc_id = module.vpc.vpc_id
44+
subnet_ids = module.subnets.private_subnet_ids
45+
security_group_ids = [module.vpc.vpc_default_security_group_id]
46+
apply_immediately = var.apply_immediately
47+
availability_zone = var.availability_zone
48+
db_subnet_group_name = var.db_subnet_group_name
4449

4550
db_parameter = [
4651
{
@@ -54,4 +59,6 @@ module "rds_instance" {
5459
apply_method = "immediate"
5560
}
5661
]
62+
63+
context = module.this.context
5764
}

examples/complete/outputs.tf

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ output "instance_endpoint" {
1515

1616
output "subnet_group_id" {
1717
value = module.rds_instance.subnet_group_id
18-
description = "ID of the Subnet Group"
18+
description = "ID of the created Subnet Group"
1919
}
2020

2121
output "security_group_id" {

examples/complete/variables.tf

+12
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,18 @@ variable "multi_az" {
3737
description = "Set to true if multi AZ deployment must be supported"
3838
}
3939

40+
variable "availability_zone" {
41+
type = string
42+
default = null
43+
description = "The AZ for the RDS instance. Specify one of `subnet_ids`, `db_subnet_group_name` or `availability_zone`. If `availability_zone` is provided, the instance will be placed into the default VPC or EC2 Classic"
44+
}
45+
46+
variable "db_subnet_group_name" {
47+
type = string
48+
default = null
49+
description = "Name of DB subnet group. DB instance will be created in the VPC associated with the DB subnet group. Specify one of `subnet_ids`, `db_subnet_group_name` or `availability_zone`"
50+
}
51+
4052
variable "storage_type" {
4153
type = string
4254
description = "One of 'standard' (magnetic), 'gp2' (general purpose SSD), or 'io1' (provisioned IOPS SSD)"

main.tf

+52-15
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,20 @@ module "final_snapshot_label" {
88
locals {
99
computed_major_engine_version = var.engine == "postgres" ? join(".", slice(split(".", var.engine_version), 0, 1)) : join(".", slice(split(".", var.engine_version), 0, 2))
1010
major_engine_version = var.major_engine_version == "" ? local.computed_major_engine_version : var.major_engine_version
11+
12+
subnet_ids_provided = var.subnet_ids != null && length(var.subnet_ids) > 0
13+
db_subnet_group_name_provided = var.db_subnet_group_name != null && var.db_subnet_group_name != ""
14+
15+
db_subnet_group_name = local.db_subnet_group_name_provided ? var.db_subnet_group_name : (
16+
local.subnet_ids_provided ? join("", aws_db_subnet_group.default.*.name) : null
17+
)
18+
19+
availability_zone = var.multi_az ? null : var.availability_zone
1120
}
1221

1322
resource "aws_db_instance" "default" {
14-
count = module.this.enabled ? 1 : 0
23+
count = module.this.enabled ? 1 : 0
24+
1525
identifier = module.this.id
1626
name = var.database_name
1727
username = var.database_user
@@ -32,8 +42,10 @@ resource "aws_db_instance" "default" {
3242
)
3343
)
3444

45+
db_subnet_group_name = local.db_subnet_group_name
46+
availability_zone = local.availability_zone
47+
3548
ca_cert_identifier = var.ca_cert_identifier
36-
db_subnet_group_name = join("", aws_db_subnet_group.default.*.name)
3749
parameter_group_name = length(var.parameter_group_name) > 0 ? var.parameter_group_name : join("", aws_db_parameter_group.default.*.name)
3850
option_group_name = length(var.option_group_name) > 0 ? var.option_group_name : join("", aws_db_option_group.default.*.name)
3951
license_model = var.license_model
@@ -62,13 +74,27 @@ resource "aws_db_instance" "default" {
6274

6375
monitoring_interval = var.monitoring_interval
6476
monitoring_role_arn = var.monitoring_role_arn
77+
78+
depends_on = [
79+
aws_db_subnet_group.default,
80+
aws_security_group.default,
81+
aws_db_parameter_group.default,
82+
aws_db_option_group.default
83+
]
84+
85+
lifecycle {
86+
ignore_changes = [
87+
snapshot_identifier, # if created from a snapshot, will be non-null at creation, but null afterwards
88+
]
89+
}
6590
}
6691

6792
resource "aws_db_parameter_group" "default" {
68-
count = length(var.parameter_group_name) == 0 && module.this.enabled ? 1 : 0
69-
name = module.this.id
70-
family = var.db_parameter_group
71-
tags = module.this.tags
93+
count = length(var.parameter_group_name) == 0 && module.this.enabled ? 1 : 0
94+
95+
name_prefix = "${module.this.id}${module.this.delimiter}"
96+
family = var.db_parameter_group
97+
tags = module.this.tags
7298

7399
dynamic "parameter" {
74100
for_each = var.db_parameter
@@ -78,11 +104,16 @@ resource "aws_db_parameter_group" "default" {
78104
value = parameter.value.value
79105
}
80106
}
107+
108+
lifecycle {
109+
create_before_destroy = true
110+
}
81111
}
82112

83113
resource "aws_db_option_group" "default" {
84-
count = length(var.option_group_name) == 0 && module.this.enabled ? 1 : 0
85-
name = module.this.id
114+
count = length(var.option_group_name) == 0 && module.this.enabled ? 1 : 0
115+
116+
name_prefix = "${module.this.id}${module.this.delimiter}"
86117
engine_name = var.engine
87118
major_engine_version = local.major_engine_version
88119
tags = module.this.tags
@@ -112,22 +143,25 @@ resource "aws_db_option_group" "default" {
112143
}
113144

114145
resource "aws_db_subnet_group" "default" {
115-
count = module.this.enabled ? 1 : 0
146+
count = module.this.enabled && local.subnet_ids_provided && ! local.db_subnet_group_name_provided ? 1 : 0
147+
116148
name = module.this.id
117149
subnet_ids = var.subnet_ids
118150
tags = module.this.tags
119151
}
120152

121153
resource "aws_security_group" "default" {
122-
count = module.this.enabled ? 1 : 0
154+
count = module.this.enabled ? 1 : 0
155+
123156
name = module.this.id
124157
description = "Allow inbound traffic from the security groups"
125158
vpc_id = var.vpc_id
126159
tags = module.this.tags
127160
}
128161

129162
resource "aws_security_group_rule" "ingress_security_groups" {
130-
count = module.this.enabled ? length(var.security_group_ids) : 0
163+
count = module.this.enabled ? length(var.security_group_ids) : 0
164+
131165
description = "Allow inbound traffic from existing Security Groups"
132166
type = "ingress"
133167
from_port = var.database_port
@@ -138,7 +172,8 @@ resource "aws_security_group_rule" "ingress_security_groups" {
138172
}
139173

140174
resource "aws_security_group_rule" "ingress_cidr_blocks" {
141-
count = module.this.enabled && length(var.allowed_cidr_blocks) > 0 ? 1 : 0
175+
count = module.this.enabled && length(var.allowed_cidr_blocks) > 0 ? 1 : 0
176+
142177
description = "Allow inbound traffic from CIDR blocks"
143178
type = "ingress"
144179
from_port = var.database_port
@@ -160,11 +195,13 @@ resource "aws_security_group_rule" "egress" {
160195
}
161196

162197
module "dns_host_name" {
163-
source = "cloudposse/route53-cluster-hostname/aws"
164-
version = "0.12.0"
198+
source = "cloudposse/route53-cluster-hostname/aws"
199+
version = "0.12.0"
200+
165201
enabled = length(var.dns_zone_id) > 0 && module.this.enabled
166202
dns_name = var.host_name
167203
zone_id = var.dns_zone_id
168204
records = coalescelist(aws_db_instance.default.*.address, [""])
169-
context = module.this.context
205+
206+
context = module.this.context
170207
}

outputs.tf

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ output "instance_endpoint" {
2020

2121
output "subnet_group_id" {
2222
value = join("", aws_db_subnet_group.default.*.id)
23-
description = "ID of the Subnet Group"
23+
description = "ID of the created Subnet Group"
2424
}
2525

2626
output "security_group_id" {

0 commit comments

Comments
 (0)