From c4768014dff9f3df435df7c92d3063376397bdec Mon Sep 17 00:00:00 2001 From: Tomer Heber Date: Wed, 6 Mar 2024 08:30:59 -0600 Subject: [PATCH] Fix: AWS EC2 volume tag errors (#191) * Fix: AWS EC2 volume tag errors * fix to cover more use-cases * minor change * minor change * removed an extra newline * more changes after some discussions --- internal/tagging/aws.go | 53 ++++++++++-- .../aws_instance_volume_tags/expected/main.tf | 80 +++++++++++++++++-- .../aws_instance_volume_tags/input/main.tf | 67 +++++++++++++++- 3 files changed, 185 insertions(+), 15 deletions(-) diff --git a/internal/tagging/aws.go b/internal/tagging/aws.go index db132f4..b3a2753 100644 --- a/internal/tagging/aws.go +++ b/internal/tagging/aws.go @@ -18,13 +18,54 @@ func tagAwsInstance(args TagBlockArgs) (*Result, error) { } swappedTagsStrings = append(swappedTagsStrings, tagBlock) - volumeTagBlockArgs := args - volumeTagBlockArgs.TagId = "volume_tags" - volumeTagBlock, err := TagBlock(volumeTagBlockArgs) - if err != nil { - return nil, err + // Tag 'volume_tags' if it exists. + // Else: + // 1. create 'root_block_device' block (if not exist) and add tags to it. + // 2. add tags to any existing 'ebs_block_device' block. + // See tag guide for additional details: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance#tag-guide + + if args.Block.Body().GetAttribute("volume_tags") != nil { + // Add tags to 'volume_tags' attribute. + volumeTagBlockArgs := args + volumeTagBlockArgs.TagId = "volume_tags" + volumeTagBlock, err := TagBlock(volumeTagBlockArgs) + if err != nil { + return nil, err + } + swappedTagsStrings = append(swappedTagsStrings, volumeTagBlock) + } else { + rootBlockDevice := args.Block.Body().FirstMatchingBlock("root_block_device", nil) + if rootBlockDevice == nil { + // Create 'root_block_device' block. + rootBlockDevice = args.Block.Body().AppendNewBlock("root_block_device", nil) + } + + // Add tags to 'root_block_device' block. + origArgsBlock := args.Block + args.Block = rootBlockDevice + tagBlock, err := TagBlock(args) + if err != nil { + return nil, err + } + swappedTagsStrings = append(swappedTagsStrings, tagBlock) + args.Block = origArgsBlock + + // Add tags to any 'ebs_block_device' blocks (if any exist). + for _, block := range args.Block.Body().Blocks() { + if block.Type() != "ebs_block_device" { + continue + } + + origArgsBlock := args.Block + args.Block = block + tagBlock, err := TagBlock(args) + if err != nil { + return nil, err + } + swappedTagsStrings = append(swappedTagsStrings, tagBlock) + args.Block = origArgsBlock + } } - swappedTagsStrings = append(swappedTagsStrings, volumeTagBlock) return &Result{SwappedTagsStrings: swappedTagsStrings}, nil } diff --git a/test/tests/aws_instance_volume_tags/expected/main.tf b/test/tests/aws_instance_volume_tags/expected/main.tf index 8151ef6..41181e0 100644 --- a/test/tests/aws_instance_volume_tags/expected/main.tf +++ b/test/tests/aws_instance_volume_tags/expected/main.tf @@ -2,7 +2,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = "~> 2.0" + version = "~> 5.0" } } } @@ -11,17 +11,87 @@ provider "aws" { region = "us-east-1" } -resource "aws_instance" "ubuntu" { +resource "aws_instance" "no_volume_tags" { ami = "dasdasD" instance_type = "t3.micro" availability_zone = "us-west-2" + tags = merge({ + "a" = "b" + }, local.terratag_added_main) + root_block_device { + tags = local.terratag_added_main + } +} + +resource "aws_instance" "volume_tags" { + ami = "dasdasD" + instance_type = "t3.micro" + availability_zone = "us-west-2" + + root_block_device { + volume_size = 8 + } + + ebs_block_device { + device_name = "abcdefg" + } + + volume_tags = merge({ + "c" = "d" + }, local.terratag_added_main) tags = merge({ - "Name" = "terratag-test" - "env" = "test" + "a" = "b" }, local.terratag_added_main) - volume_tags = local.terratag_added_main +} + +resource "aws_instance" "root_block_device" { + ami = "dasdasD" + instance_type = "t3.micro" + availability_zone = "us-west-2" + + root_block_device { + volume_size = 8 + tags = merge({ + "a" = "b" + }, local.terratag_added_main) + } + tags = local.terratag_added_main +} + +resource "aws_instance" "root_block_device_does_not_exist" { + ami = "dasdasD" + instance_type = "t3.micro" + availability_zone = "us-west-2" + tags = local.terratag_added_main + root_block_device { + tags = local.terratag_added_main + } +} + +resource "aws_instance" "multiple_tags" { + ami = "dasdasD" + instance_type = "t3.micro" + availability_zone = "us-west-2" + + ebs_block_device { + device_name = "abcdefg" + tags = merge({ + "a" = "b" + }, local.terratag_added_main) + } + + ebs_block_device { + device_name = "abcdefg" + tags = merge({ + "c" = "d" + }, local.terratag_added_main) + } + tags = local.terratag_added_main + root_block_device { + tags = local.terratag_added_main + } } locals { diff --git a/test/tests/aws_instance_volume_tags/input/main.tf b/test/tests/aws_instance_volume_tags/input/main.tf index 1fb4557..f8deafb 100644 --- a/test/tests/aws_instance_volume_tags/input/main.tf +++ b/test/tests/aws_instance_volume_tags/input/main.tf @@ -2,7 +2,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = "~> 2.0" + version = "~> 5.0" } } } @@ -11,14 +11,73 @@ provider "aws" { region = "us-east-1" } -resource "aws_instance" "ubuntu" { +resource "aws_instance" "no_volume_tags" { ami = "dasdasD" instance_type = "t3.micro" availability_zone = "us-west-2" + tags = { + a = "b" + } +} + +resource "aws_instance" "volume_tags" { + ami = "dasdasD" + instance_type = "t3.micro" + availability_zone = "us-west-2" + + root_block_device { + volume_size = 8 + } + + ebs_block_device { + device_name = "abcdefg" + } + + volume_tags = { + c = "d" + } tags = { - Name = "terratag-test" - env = "test" + a = "b" + } +} + +resource "aws_instance" "root_block_device" { + ami = "dasdasD" + instance_type = "t3.micro" + availability_zone = "us-west-2" + + root_block_device { + volume_size = 8 + tags = { + a = "b" + } + } +} + +resource "aws_instance" "root_block_device_does_not_exist" { + ami = "dasdasD" + instance_type = "t3.micro" + availability_zone = "us-west-2" +} + +resource "aws_instance" "multiple_tags" { + ami = "dasdasD" + instance_type = "t3.micro" + availability_zone = "us-west-2" + + ebs_block_device { + device_name = "abcdefg" + tags = { + a = "b" + } + } + + ebs_block_device { + device_name = "abcdefg" + tags = { + c = "d" + } } }