diff --git a/README.md b/README.md index 086c4c08..42308185 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,12 @@ You need the following permissions to run this module. - **Resource Group** \ - `Viewer` resource group access +To attach access management tags to resources in this module, you need the following permissions. + +- IAM Services + - **Tagging** service + - `Administrator` platform access + ## Examples @@ -114,6 +120,7 @@ You need the following permissions to run this module. | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| +| [access\_tags](#input\_access\_tags) | A list of access tags to apply to the VPC resources created by the module. For more information, see https://cloud.ibm.com/docs/account?topic=account-access-tags-tutorial. | `list(string)` | `[]` | no | | [address\_prefixes](#input\_address\_prefixes) | OPTIONAL - IP range that will be defined for the VPC for a certain location. Use only with manual address prefixes |
object({
zone-1 = optional(list(string))
zone-2 = optional(list(string))
zone-3 = optional(list(string))
})
|
{
"zone-1": null,
"zone-2": null,
"zone-3": null
}
| no | | [classic\_access](#input\_classic\_access) | OPTIONAL - Classic Access to the VPC | `bool` | `false` | no | | [clean\_default\_acl](#input\_clean\_default\_acl) | Remove all rules from the default VPC ACL (less permissive) | `bool` | `false` | no | diff --git a/examples/default/main.tf b/examples/default/main.tf index 74699444..9e983d60 100644 --- a/examples/default/main.tf +++ b/examples/default/main.tf @@ -48,6 +48,7 @@ module "slz_vpc" { name = var.name prefix = var.prefix tags = var.resource_tags + access_tags = var.access_tags enable_vpc_flow_logs = var.enable_vpc_flow_logs create_authorization_policy_vpc_to_cos = var.create_authorization_policy_vpc_to_cos existing_cos_instance_guid = ibm_resource_instance.cos_instance[0].guid diff --git a/examples/default/variables.tf b/examples/default/variables.tf index 7ed05151..b347d595 100644 --- a/examples/default/variables.tf +++ b/examples/default/variables.tf @@ -34,6 +34,12 @@ variable "resource_tags" { default = null } +variable "access_tags" { + type = list(string) + description = "Optional list of access tags to add to the VPC resources that are created" + default = [] +} + variable "enable_vpc_flow_logs" { type = bool description = "Enable VPC Flow Logs, it will create Flow logs collector if set to true" diff --git a/examples/landing_zone/main.tf b/examples/landing_zone/main.tf index e81a0161..e33f33e4 100644 --- a/examples/landing_zone/main.tf +++ b/examples/landing_zone/main.tf @@ -36,6 +36,7 @@ module "workload_vpc" { region = var.region prefix = var.prefix tags = var.resource_tags + access_tags = var.access_tags enable_vpc_flow_logs = var.enable_vpc_flow_logs create_authorization_policy_vpc_to_cos = var.create_authorization_policy_vpc_to_cos existing_cos_instance_guid = module.cos_bucket[0].cos_instance_guid diff --git a/examples/landing_zone/variables.tf b/examples/landing_zone/variables.tf index ebd6d41e..d895c8b5 100644 --- a/examples/landing_zone/variables.tf +++ b/examples/landing_zone/variables.tf @@ -28,6 +28,11 @@ variable "resource_tags" { default = null } +variable "access_tags" { + type = list(string) + description = "Optional list of access tags to add to the VPC resources that are created" + default = [] +} ############################################################################## # VPC flow logs variables diff --git a/landing-zone-submodule/management-vpc/README.md b/landing-zone-submodule/management-vpc/README.md index ea4b089a..dd8fb75f 100644 --- a/landing-zone-submodule/management-vpc/README.md +++ b/landing-zone-submodule/management-vpc/README.md @@ -27,6 +27,7 @@ No resources. | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| +| [access\_tags](#input\_access\_tags) | Optional list of access tags to add to the VPC resources that are created | `list(string)` | `[]` | no | | [address\_prefixes](#input\_address\_prefixes) | Use `address_prefixes` only if `use_manual_address_prefixes` is true otherwise prefixes will not be created. Use only if you need to manage prefixes manually. |
object({
zone-1 = optional(list(string))
zone-2 = optional(list(string))
zone-3 = optional(list(string))
})
| `null` | no | | [classic\_access](#input\_classic\_access) | Optionally allow VPC to access classic infrastructure network | `bool` | `null` | no | | [clean\_default\_acl](#input\_clean\_default\_acl) | Remove all rules from the default VPC ACL (less permissive) | `bool` | `false` | no | diff --git a/landing-zone-submodule/management-vpc/main.tf b/landing-zone-submodule/management-vpc/main.tf index 1bf6f08d..3af3aadc 100644 --- a/landing-zone-submodule/management-vpc/main.tf +++ b/landing-zone-submodule/management-vpc/main.tf @@ -6,6 +6,7 @@ module "management_vpc" { source = "../../" name = "management" tags = var.tags + access_tags = var.access_tags resource_group_id = var.resource_group_id region = var.region prefix = var.prefix diff --git a/landing-zone-submodule/management-vpc/variables.tf b/landing-zone-submodule/management-vpc/variables.tf index 5df0ffb7..55d39ecb 100644 --- a/landing-zone-submodule/management-vpc/variables.tf +++ b/landing-zone-submodule/management-vpc/variables.tf @@ -21,6 +21,11 @@ variable "tags" { default = [] } +variable "access_tags" { + type = list(string) + description = "Optional list of access tags to add to the VPC resources that are created" + default = [] +} ############################################################################# # VPC variables diff --git a/landing-zone-submodule/workload-vpc/README.md b/landing-zone-submodule/workload-vpc/README.md index 757b7265..143ab086 100644 --- a/landing-zone-submodule/workload-vpc/README.md +++ b/landing-zone-submodule/workload-vpc/README.md @@ -28,6 +28,7 @@ No resources. | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| +| [access\_tags](#input\_access\_tags) | Optional list of access tags to add to the VPC resources that are created | `list(string)` | `[]` | no | | [address\_prefixes](#input\_address\_prefixes) | Use `address_prefixes` only if `use_manual_address_prefixes` is true otherwise prefixes will not be created. Use only if you need to manage prefixes manually. |
object({
zone-1 = optional(list(string))
zone-2 = optional(list(string))
zone-3 = optional(list(string))
})
| `null` | no | | [classic\_access](#input\_classic\_access) | Optionally allow VPC to access classic infrastructure network | `bool` | `null` | no | | [clean\_default\_acl](#input\_clean\_default\_acl) | Remove all rules from the default VPC ACL (less permissive) | `bool` | `false` | no | diff --git a/landing-zone-submodule/workload-vpc/main.tf b/landing-zone-submodule/workload-vpc/main.tf index 721dba29..bcb53c02 100644 --- a/landing-zone-submodule/workload-vpc/main.tf +++ b/landing-zone-submodule/workload-vpc/main.tf @@ -6,6 +6,7 @@ module "workload_vpc" { source = "../../" name = "workload" tags = var.tags + access_tags = var.access_tags resource_group_id = var.resource_group_id region = var.region prefix = var.prefix diff --git a/landing-zone-submodule/workload-vpc/variables.tf b/landing-zone-submodule/workload-vpc/variables.tf index d8748c35..175c9bde 100644 --- a/landing-zone-submodule/workload-vpc/variables.tf +++ b/landing-zone-submodule/workload-vpc/variables.tf @@ -21,6 +21,12 @@ variable "tags" { default = [] } +variable "access_tags" { + type = list(string) + description = "Optional list of access tags to add to the VPC resources that are created" + default = [] +} + ############################################################################# # VPC variables ############################################################################# diff --git a/main.tf b/main.tf index 12f762ba..36734ec2 100644 --- a/main.tf +++ b/main.tf @@ -11,6 +11,7 @@ resource "ibm_is_vpc" "vpc" { default_security_group_name = var.default_security_group_name default_routing_table_name = var.default_routing_table_name tags = var.tags + access_tags = var.access_tags } ############################################################################## @@ -89,6 +90,7 @@ resource "ibm_is_public_gateway" "gateway" { resource_group = var.resource_group_id zone = each.value tags = var.tags + access_tags = var.access_tags } ############################################################################## @@ -123,6 +125,7 @@ resource "ibm_is_flow_log" "flow_logs" { storage_bucket = var.existing_storage_bucket_name resource_group = var.resource_group_id tags = var.tags + access_tags = var.access_tags } ############################################################################## diff --git a/module-metadata.json b/module-metadata.json index ef36028c..caa901f6 100644 --- a/module-metadata.json +++ b/module-metadata.json @@ -1,6 +1,30 @@ { "path": ".", "variables": { + "access_tags": { + "name": "access_tags", + "type": "list(string)", + "description": "A list of access tags to apply to the VPC resources created by the module. For more information, see https://cloud.ibm.com/docs/account?topic=account-access-tags-tutorial.", + "default": [], + "source": [ + "ibm_is_flow_log.flow_logs.access_tags", + "ibm_is_network_acl.network_acl.access_tags", + "ibm_is_public_gateway.gateway.access_tags", + "ibm_is_subnet.subnet.access_tags", + "ibm_is_vpc.vpc.access_tags" + ], + "pos": { + "filename": "variables.tf", + "line": 31 + }, + "min_length": 1, + "max_length": 128, + "matches": "^([A-Za-z0-9_.-]|[A-Za-z0-9_.-][A-Za-z0-9_ .-]*[A-Za-z0-9_.-]):([A-Za-z0-9_.-]|[A-Za-z0-9_.-][A-Za-z0-9_ .-]*[A-Za-z0-9_.-])$", + "computed": true, + "elem": { + "type": "TypeString" + } + }, "address_prefixes": { "name": "address_prefixes", "type": "object({\n zone-1 = optional(list(string))\n zone-2 = optional(list(string))\n zone-3 = optional(list(string))\n })", @@ -16,7 +40,7 @@ ], "pos": { "filename": "variables.tf", - "line": 67 + "line": 80 } }, "classic_access": { @@ -29,7 +53,7 @@ ], "pos": { "filename": "variables.tf", - "line": 43 + "line": 56 }, "immutable": true }, @@ -43,7 +67,7 @@ ], "pos": { "filename": "variables.tf", - "line": 372 + "line": 385 } }, "clean_default_security_group": { @@ -56,7 +80,7 @@ ], "pos": { "filename": "variables.tf", - "line": 366 + "line": 379 } }, "create_authorization_policy_vpc_to_cos": { @@ -66,7 +90,7 @@ "default": false, "pos": { "filename": "variables.tf", - "line": 437 + "line": 450 } }, "default_network_acl_name": { @@ -78,7 +102,7 @@ ], "pos": { "filename": "variables.tf", - "line": 49 + "line": 62 }, "min_length": 1, "max_length": 63, @@ -94,7 +118,7 @@ ], "pos": { "filename": "variables.tf", - "line": 61 + "line": 74 }, "min_length": 1, "max_length": 63, @@ -110,7 +134,7 @@ ], "pos": { "filename": "variables.tf", - "line": 55 + "line": 68 }, "min_length": 1, "max_length": 63, @@ -128,7 +152,7 @@ ], "pos": { "filename": "variables.tf", - "line": 431 + "line": 444 } }, "existing_cos_instance_guid": { @@ -140,7 +164,7 @@ ], "pos": { "filename": "variables.tf", - "line": 443 + "line": 456 }, "immutable": true, "computed": true @@ -155,7 +179,7 @@ ], "pos": { "filename": "variables.tf", - "line": 449 + "line": 462 }, "immutable": true }, @@ -166,7 +190,7 @@ "sensitive": true, "pos": { "filename": "variables.tf", - "line": 389 + "line": 402 } }, "ibmcloud_api_visibility": { @@ -176,7 +200,7 @@ "default": "public", "pos": { "filename": "variables.tf", - "line": 378 + "line": 391 } }, "is_flow_log_collector_active": { @@ -189,7 +213,7 @@ ], "pos": { "filename": "variables.tf", - "line": 455 + "line": 468 } }, "name": { @@ -220,7 +244,7 @@ ], "pos": { "filename": "variables.tf", - "line": 92 + "line": 105 } }, "network_cidr": { @@ -233,7 +257,7 @@ ], "pos": { "filename": "variables.tf", - "line": 37 + "line": 50 } }, "prefix": { @@ -303,7 +327,7 @@ ], "pos": { "filename": "variables.tf", - "line": 403 + "line": 416 } }, "security_group_rules": { @@ -322,7 +346,7 @@ ], "pos": { "filename": "variables.tf", - "line": 308 + "line": 321 } }, "subnets": { @@ -360,7 +384,7 @@ ], "pos": { "filename": "variables.tf", - "line": 245 + "line": 258 } }, "tags": { @@ -399,7 +423,7 @@ ], "pos": { "filename": "variables.tf", - "line": 219 + "line": 232 } } }, @@ -536,7 +560,7 @@ }, "pos": { "filename": "main.tf", - "line": 106 + "line": 108 } }, "ibm_is_flow_log.flow_logs": { @@ -544,6 +568,7 @@ "type": "ibm_is_flow_log", "name": "flow_logs", "attributes": { + "access_tags": "access_tags", "active": "is_flow_log_collector_active", "count": "enable_vpc_flow_logs", "name": "prefix", @@ -556,7 +581,7 @@ }, "pos": { "filename": "main.tf", - "line": 117 + "line": 119 } }, "ibm_is_network_acl.network_acl": { @@ -564,6 +589,7 @@ "type": "ibm_is_network_acl", "name": "network_acl", "attributes": { + "access_tags": "access_tags", "name": "prefix", "resource_group": "resource_group_id" }, @@ -580,6 +606,7 @@ "type": "ibm_is_public_gateway", "name": "gateway", "attributes": { + "access_tags": "access_tags", "name": "prefix", "resource_group": "resource_group_id", "tags": "tags" @@ -589,7 +616,7 @@ }, "pos": { "filename": "main.tf", - "line": 85 + "line": 86 } }, "ibm_is_security_group_rule.default_vpc_rule": { @@ -609,6 +636,7 @@ "type": "ibm_is_subnet", "name": "subnet", "attributes": { + "access_tags": "access_tags", "resource_group": "resource_group_id", "tags": "tags" }, @@ -625,6 +653,7 @@ "type": "ibm_is_vpc", "name": "vpc", "attributes": { + "access_tags": "access_tags", "address_prefix_management": "address_prefixes", "classic_access": "classic_access", "default_network_acl_name": "default_network_acl_name", @@ -651,7 +680,7 @@ }, "pos": { "filename": "main.tf", - "line": 31 + "line": 32 } }, "ibm_is_vpc_address_prefix.subnet_prefix": { @@ -678,7 +707,7 @@ }, "pos": { "filename": "main.tf", - "line": 50 + "line": 51 } }, "ibm_is_vpc_routing_table_route.routing_table_routes": { @@ -693,7 +722,7 @@ }, "pos": { "filename": "main.tf", - "line": 59 + "line": 60 } }, "null_resource.clean_default_acl": { @@ -708,7 +737,7 @@ }, "pos": { "filename": "main.tf", - "line": 150 + "line": 153 } }, "null_resource.clean_default_security_group": { @@ -723,7 +752,7 @@ }, "pos": { "filename": "main.tf", - "line": 134 + "line": 137 } } }, @@ -737,7 +766,7 @@ }, "pos": { "filename": "main.tf", - "line": 39 + "line": 40 } } }, diff --git a/network_acls.tf b/network_acls.tf index 979c03f3..c30d0ef3 100644 --- a/network_acls.tf +++ b/network_acls.tf @@ -139,6 +139,7 @@ resource "ibm_is_network_acl" "network_acl" { name = "${var.prefix}-${each.key}" #already has name of vpc in each.key vpc = ibm_is_vpc.vpc.id resource_group = var.resource_group_id + access_tags = var.access_tags # Create ACL rules dynamic "rules" { diff --git a/subnet.tf b/subnet.tf index 6cd67f74..15e7be96 100644 --- a/subnet.tf +++ b/subnet.tf @@ -39,6 +39,7 @@ resource "ibm_is_subnet" "subnet" { network_acl = ibm_is_network_acl.network_acl[each.value.acl].id public_gateway = each.value.public_gateway tags = var.tags + access_tags = var.access_tags depends_on = [ibm_is_vpc_address_prefix.address_prefixes] } diff --git a/tests/pr_test.go b/tests/pr_test.go index fdac1d8f..1d7de464 100644 --- a/tests/pr_test.go +++ b/tests/pr_test.go @@ -1,9 +1,12 @@ package test import ( + "log" + "os" "testing" "github.com/stretchr/testify/assert" + "github.com/terraform-ibm-modules/ibmcloud-terratest-wrapper/common" "github.com/terraform-ibm-modules/ibmcloud-terratest-wrapper/testhelper" ) @@ -11,12 +14,31 @@ const defaultExampleTerraformDir = "examples/default" const landingZoneExampleTerraformDir = "examples/landing_zone" const resourceGroup = "geretain-test-resources" +// Define a struct with fields that match the structure of the YAML data +const yamlLocation = "../common-dev-assets/common-go-assets/common-permanent-resources.yaml" + +var permanentResources map[string]interface{} + +func TestMain(m *testing.M) { + // Read the YAML file contents + var err error + permanentResources, err = common.LoadMapFromYaml(yamlLocation) + if err != nil { + log.Fatal(err) + } + + os.Exit(m.Run()) +} + func setupOptions(t *testing.T, prefix string, terraformDir string) *testhelper.TestOptions { options := testhelper.TestOptionsDefaultWithVars(&testhelper.TestOptions{ Testing: t, TerraformDir: terraformDir, Prefix: prefix, ResourceGroup: resourceGroup, + TerraformVars: map[string]interface{}{ + "access_tags": permanentResources["accessTags"], + }, }) return options diff --git a/variables.tf b/variables.tf index 43242aca..4f2065c1 100644 --- a/variables.tf +++ b/variables.tf @@ -28,6 +28,19 @@ variable "tags" { default = null } +variable "access_tags" { + type = list(string) + description = "A list of access tags to apply to the VPC resources created by the module. For more information, see https://cloud.ibm.com/docs/account?topic=account-access-tags-tutorial." + default = [] + + validation { + condition = alltrue([ + for tag in var.access_tags : can(regex("[\\w\\-_\\.]+:[\\w\\-_\\.]+", tag)) && length(tag) <= 128 + ]) + error_message = "Tags must match the regular expression \"[\\w\\-_\\.]+:[\\w\\-_\\.]+\". For more information, see https://cloud.ibm.com/docs/account?topic=account-tag&interface=ui#limits." + } +} + ############################################################################## ##############################################################################