In Terraform you might want to replace ingress
/egress
rules directly on an aws_security_group
with individual aws_security_group_rule
s, so that they work properly.
To do this, first make the required *.tf
changes. Great. Now the plan contains only rule additions, and application fails due to the collision with the undeleted old rules.
terraform state rm aws_security_group.the_sg
terraform import aws_security_group.the_sg sg-deadbeef
Great. Now it's imported a bunch of aws_security_group_rule
s called aws_security_group_rule.the_sg
and aws_security_group_rule.the_sg-1
up to -whatever
, rather than the aws_security_group_rule.descriptive_name
you wanted.
At this point the plan will pointlessly wish to delete the numbered ones and recreate them as named ones. This will either fail again, or cause service to be interrupted.
The script in this gist is designed to easily rename the imported rules directly to your intended name in the state so that this doesn't happen.
(for r in aws_security_group_rule.the_sg{,-{1..11}}; do echo "$r"; terraform state show "$r"; echo; done) | tee old-rules
terraform plan -etc -etc | perl -pe 's(\x1b\[[0-9;]*[a-zA-Z])()g' | tee new-rules # The perl is to get rid of the color escape codes from the planning output so it's more easily parseable
./autorename-sg-rules.rb # filenames are hardcoded because boring
Now, it will output the required commands to rename the rules in the state, so the plan will make sense:
terraform state mv aws_security_group_rule.the_sg aws_security_group_rule.let_in_users
terraform state mv aws_security_group_rule.the_sg-1 aws_security_group_rule.let_out_logs
terraform state mv aws_security_group_rule.the_sg-2 aws_security_group_rule.stupid_hack
[...etc etc]