cloudposse/terraform-aws-rds-cluster

How to migrate from the inline Security Group rules to SG rules as separate resources

aknysh opened this issue · 1 comments

This PR #80 changed the Security Group rules from inline to resource-based.

This is a good move since using inline SG rules is a "bad practice". Inline rules have many issues (one of them is that you can't add new rules to the security group since it's not possible to mix the inline rules and rules as separate resources).

At the same time, this introduced a breaking change: if you want to update the module to the latest version, Terraform will try to add the new resource-based rules to the security group and will fail since the same rules already exist and we can't mix inline rules with resource-based rules.

Note that it's not possible to taint and destroy the security group since it has a dependent object (an Elastic Network Interface), which in turn has its own dependencies.

One possible solution would be to destroy the Aurora RDS cluster completely and recreate it. While possible in some cases (e.g. in dev environments), it could not be feasible in other environments (e.g. a production database has data, and it's not possible to have a long outage).

A better way would be to just destroy the inline security group rules without destroying the security group itself (and any other Aurora resources), and then add the resource-based security group rules.

Here are the steps to do that:

  1. Create a new branch of terraform-aws-rds-cluster module, e.g. strip-inline-sg-rules

  2. In the new branch, comment out all the aws_security_group_rule resources for resource "aws_security_group" "default"

  3. Add empty ingress and egress lists to the security group. NOTE: you can't skip the ingress and egress completely since terraform will not detect any changes to the inline rules (this is a bug/feature of TF):

resource "aws_security_group" "default" {
  name        = ...
  vpc_id      = var.vpc_id

  ingress = []
  egress  = []
}

NOTE: Branch strip-inline-sg-rules has been already created in this repository and steps 1-3 already performed.
The branch strip-inline-sg-rules can be used to perform the next steps.

  1. Update the Aurora cluster project to use the strip-inline-sg-rules branch of the terraform-aws-rds-cluster module
module "aurora_postgres_cluster" {
  source = "git::https://github.com/cloudposse/terraform-aws-rds-cluster.git?ref=strip-inline-sg-rules"

  1. Apply the project. Terraform will just remove the inline rules from the security group without destroying the SG itself and any of the Aurora resources

  2. Update the Aurora cluster project to use the latest release of the terraform-aws-rds-cluster module

module "aurora_postgres_cluster" {
  source = "git::https://github.com/cloudposse/terraform-aws-rds-cluster.git?ref=tags/0.34.0"

  1. Apply the project. Terraform will add the external resource-based SG rules

It takes a few minutes to go through all the steps, so the disruption to the production database will be minimal.

It is worth noting that migration without downtime can be achieved through state manipulation:

  1. remove the security group from state terraform state rm ...
  2. import the individual rules to the state terraform import ...
  3. import the security group to the state again terraform import ...