From 57494b5c3d93977d8b1ecb9ace00fd2791c70591 Mon Sep 17 00:00:00 2001 From: Yurii Rochniak Date: Mon, 4 Nov 2024 20:01:35 +0100 Subject: [PATCH] Fix broken name tag (#119) * Fix broken name tag * Do not set name for default * use Localstack action --- .github/workflows/terratest.yml | 4 +- examples/custom-name-tag/README.md | 45 +++++++++++++++++++++++ examples/custom-name-tag/main.tf | 23 ++++++++++++ examples/custom-name-tag/outputs.tf | 8 ++++ examples/custom-name-tag/provider.tf | 15 ++++++++ examples/custom-name-tag/variables.tf | 15 ++++++++ locals.tf | 31 ++++++++++++++++ main.tf | 4 +- test/peering-active_test.go | 53 +++++++++++++++++++++++++++ 9 files changed, 195 insertions(+), 3 deletions(-) create mode 100644 examples/custom-name-tag/README.md create mode 100644 examples/custom-name-tag/main.tf create mode 100644 examples/custom-name-tag/outputs.tf create mode 100644 examples/custom-name-tag/provider.tf create mode 100644 examples/custom-name-tag/variables.tf diff --git a/.github/workflows/terratest.yml b/.github/workflows/terratest.yml index 9d7860e..dad9073 100644 --- a/.github/workflows/terratest.yml +++ b/.github/workflows/terratest.yml @@ -66,7 +66,9 @@ jobs: sudo mv /tmp/terraform /usr/local/bin/ - name: Start Localstack - run: docker-compose up -d + uses: LocalStack/setup-localstack@v0.2.3 + with: + image-tag: "latest" - name: Terratest env: diff --git a/examples/custom-name-tag/README.md b/examples/custom-name-tag/README.md new file mode 100644 index 0000000..0636e1e --- /dev/null +++ b/examples/custom-name-tag/README.md @@ -0,0 +1,45 @@ +# Setting a Custom Name Tag for the Peering Connection + +This is a basic configuration example, which creates a peering connection between VPCs in a single region within the same AWS account. + +However, here we set a custom name tag for the peering connection using the `name` variable. + +**Notice**: You need to declare both providers even with single region peering. + +## Code Sample + +```hcl +provider "aws" { + region = "eu-west-1" +} + +module "single_account_single_region" { + source = "../../" + + providers = { + aws.this = aws + aws.peer = aws + } + + name = "prod-external" + + this_vpc_id = var.this_vpc_id + peer_vpc_id = var.peer_vpc_id + + auto_accept_peering = true + + tags = { + Environment = "Test" + } +} +``` + +## Usage + +Change the variables to fit your purposes and run: + +```bash +terraform init +terraform plan +terraform apply +``` diff --git a/examples/custom-name-tag/main.tf b/examples/custom-name-tag/main.tf new file mode 100644 index 0000000..cabd074 --- /dev/null +++ b/examples/custom-name-tag/main.tf @@ -0,0 +1,23 @@ +// Basic Module Example +// Creates a peering between VPCs in the same account in the same region +module "custiom_name" { + source = "../../" + + providers = { + aws.this = aws + aws.peer = aws + } + + // Required for tests + name = var.name + + this_vpc_id = var.this_vpc_id + peer_vpc_id = var.peer_vpc_id + + auto_accept_peering = true + + tags = { + Name = "tf-single-account-single-region" + Environment = "Test" + } +} diff --git a/examples/custom-name-tag/outputs.tf b/examples/custom-name-tag/outputs.tf new file mode 100644 index 0000000..712781d --- /dev/null +++ b/examples/custom-name-tag/outputs.tf @@ -0,0 +1,8 @@ +// Required for tests +output "vpc_peering_accept_status" { + value = module.custiom_name.vpc_peering_accept_status +} + +output "vpc_peering_connection" { + value = module.custiom_name.aws_vpc_peering_connection +} diff --git a/examples/custom-name-tag/provider.tf b/examples/custom-name-tag/provider.tf new file mode 100644 index 0000000..b162943 --- /dev/null +++ b/examples/custom-name-tag/provider.tf @@ -0,0 +1,15 @@ +// This provider example is designed to work with Localstack. +// You need to have a real AWS provider configuration for the production usage. +provider "aws" { + endpoints { + ec2 = "http://localhost:4566" + s3 = "http://localhost:4566" + sts = "http://localhost:4566" + } + region = "eu-west-1" + access_key = "null" + secret_key = "null" + skip_credentials_validation = true + skip_metadata_api_check = true + skip_requesting_account_id = true +} diff --git a/examples/custom-name-tag/variables.tf b/examples/custom-name-tag/variables.tf new file mode 100644 index 0000000..34749f7 --- /dev/null +++ b/examples/custom-name-tag/variables.tf @@ -0,0 +1,15 @@ +// Variables are required to pass them via Terratest +// on fixtures creation +variable "this_vpc_id" { + type = string +} + +variable "peer_vpc_id" { + type = string +} + +variable "name" { + description = "Name of the VPC Peering Connection" + default = "" + type = string +} diff --git a/locals.tf b/locals.tf index c3d08ca..852515e 100644 --- a/locals.tf +++ b/locals.tf @@ -95,4 +95,35 @@ locals { create_associated_routes_peer = var.from_peer && var.from_peer_associated create_routes_this = var.from_this && !local.create_associated_routes_this create_routes_peer = var.from_peer && !local.create_associated_routes_peer + + # Build tags + requester_tags = var.name == "" ? merge( + var.tags, + tomap( + { "Side" = local.same_account_and_region ? "Both" : "Requester" } + ) + ) : merge( + var.tags, + tomap( + { "Name" = var.name } + ), + tomap( + { "Side" = local.same_account_and_region ? "Both" : "Requester" } + ) + ) + + accepter_tags = var.name == "" ? merge( + var.tags, + tomap( + { "Side" = local.same_account_and_region ? "Both" : "Accepter" } + ) + ) : merge( + var.tags, + tomap( + { "Name" = var.name } + ), + tomap( + { "Side" = local.same_account_and_region ? "Both" : "Accepter" } + ) + ) } diff --git a/main.tf b/main.tf index ba931ea..9bce2e1 100644 --- a/main.tf +++ b/main.tf @@ -7,7 +7,7 @@ resource "aws_vpc_peering_connection" "this" { peer_vpc_id = var.peer_vpc_id vpc_id = var.this_vpc_id peer_region = data.aws_region.peer.name - tags = merge(var.tags, { "Name" = var.name }, tomap({ "Side" = local.same_account_and_region ? "Both" : "Requester" })) + tags = local.requester_tags # hardcoded timeouts { create = "15m" @@ -22,7 +22,7 @@ resource "aws_vpc_peering_connection_accepter" "peer_accepter" { provider = aws.peer vpc_peering_connection_id = aws_vpc_peering_connection.this.id auto_accept = var.auto_accept_peering - tags = merge(var.tags, { "Name" = var.name }, tomap({ "Side" = local.same_account_and_region ? "Both" : "Accepter" })) + tags = local.accepter_tags } ####################### diff --git a/test/peering-active_test.go b/test/peering-active_test.go index 5477fe4..5499abc 100644 --- a/test/peering-active_test.go +++ b/test/peering-active_test.go @@ -1,6 +1,7 @@ package test import ( + "strings" "testing" "github.com/gruntwork-io/terratest/modules/terraform" @@ -35,6 +36,58 @@ func TestPeeringActive(t *testing.T) { } } +func TestConnectionName(t *testing.T) { + var testCases = []struct { + name string + expected string + }{ + {"DefaultName", "tf-single-account-single-region"}, + {"CustomName", "tf-custom-name"}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + var tfVars = make(map[string]interface{}) + // Apply the fixtures + fixturesTerraformOptions := &terraform.Options{ + TerraformDir: "./fixtures/single-account-single-region", // hardcoded + } + + // Remove the fixtures resources in the end of the test + defer terraform.Destroy(t, fixturesTerraformOptions) + + // Install Prerequisites + terraform.InitAndApply(t, fixturesTerraformOptions) + + // Get the outputs from fixtures + thisVpcID := terraform.Output(t, fixturesTerraformOptions, "this_vpc_id") + peerVpcID := terraform.Output(t, fixturesTerraformOptions, "peer_vpc_id") + + tfVars["this_vpc_id"] = thisVpcID + tfVars["peer_vpc_id"] = peerVpcID + // This is a hack, but I'm too tired to figure out something better + if strings.EqualFold(tc.name, "CustomName") { + tfVars["name"] = tc.expected + } + + // Terraform Options for module + moduleTerraformOptions := &terraform.Options{ + TerraformDir: "../examples/custom-name-tag", // hardcoded + Vars: tfVars, + } + + // Remove the module resources in the end of the test + defer terraform.Destroy(t, moduleTerraformOptions) + // Create module resources + terraform.InitAndApply(t, moduleTerraformOptions) + var conn any + terraform.OutputStruct(t, moduleTerraformOptions, "vpc_peering_connection", &conn) + actualName := conn.(map[string]any)["tags_all"].(map[string]any)["Name"].(string) + assert.Equal(t, tc.expected, actualName) + }) + } +} + func terratestRun(tc TestCase, t *testing.T) { var tfVars = make(map[string]interface{}) // Assertions