diff --git a/solutions/security-enforced/README.md b/solutions/security-enforced/README.md new file mode 100644 index 00000000..244d3963 --- /dev/null +++ b/solutions/security-enforced/README.md @@ -0,0 +1,117 @@ +# Cloud automation for VPC (Security-enforced) + +### Prerequisites + +- An existing resource group. +- An existing COS istance if VPC flow logs is enabled. +- An existing KMS instance (or key) if encryption of the flow logs COS bucket is required. + +### Configuration + +This solution supports provisioning and configuring the following infrastructure: + +- A VPC +- A Cloud Object Storage bucket which is required to store flow logs +- KMS key-ring and key if existing key is not passed in +- Configures the following for the created VPC: + - subnets + - network ACLs + - security group rules + - address prefixes + - customized routing table and routes + - public gateway + - VPN gateway + - VPE gateway + - flow logs + + + + +:exclamation: **Important:** This solution is not intended to be called by other modules because it contains a provider configuration and is not compatible with the `for_each`, `count`, and `depends_on` arguments. For more information, see [Providers Within Modules](https://developer.hashicorp.com/terraform/language/modules/develop/providers). + + + +### Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.9.0 | + +### Modules + +| Name | Source | Version | +|------|--------|---------| +| [vpc\_da](#module\_vpc\_da) | ../fully-configurable | n/a | + +### Resources + +No resources. + +### Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [access\_tags](#input\_access\_tags) | The list of access tags to add to the VPC instance. | `list(string)` | `[]` | no | +| [add\_bucket\_name\_suffix](#input\_add\_bucket\_name\_suffix) | Add a randomly generated suffix that is 4 characters in length, to the name of the newly provisioned Cloud Object Storage bucket. Do not use this suffix if you are passing the existing Cloud Object Storage bucket. To manage the name of the Cloud Object Storage bucket manually, use the `flow_logs_cos_bucket_name` variables. | `bool` | `true` | no | +| [address\_prefixes](#input\_address\_prefixes) | The IP range that will be defined for the VPC for a certain location. Use only with manual address prefixes. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/solutions/fully-configurable/DA-types.md#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 |
+| [clean\_default\_security\_group\_acl](#input\_clean\_default\_security\_group\_acl) | Remove all rules from the default VPC security group and VPC ACL (less permissive) | `bool` | `true` | no |
+| [cos\_bucket\_class](#input\_cos\_bucket\_class) | The storage class of the newly provisioned Cloud Object Storage bucket. Specify one of the following values for the storage class: `standard`, `vault`, `cold`, `smart` (default), or `onerate_active`. | `string` | `"standard"` | no |
+| [default\_network\_acl\_name](#input\_default\_network\_acl\_name) | Name of the Default ACL. If null, a name will be automatically generated. | `string` | `null` | no |
+| [default\_routing\_table\_name](#input\_default\_routing\_table\_name) | Name of the Default Routing Table. If null, a name will be automatically generated. | `string` | `null` | no |
+| [default\_security\_group\_name](#input\_default\_security\_group\_name) | Name of the Default Security Group. If null, a name will be automatically generated. | `string` | `null` | no |
+| [enable\_vpc\_flow\_logs](#input\_enable\_vpc\_flow\_logs) | To enable VPC Flow logs, set this to true. | `bool` | `false` | no |
+| [existing\_cos\_instance\_crn](#input\_existing\_cos\_instance\_crn) | CRN of the existing COS instance. It is only required if `enable_vpc_flow_logs` is set to true and will be used to create the flow logs bucket. | `string` | `null` | no |
+| [existing\_flow\_logs\_bucket\_kms\_key\_crn](#input\_existing\_flow\_logs\_bucket\_kms\_key\_crn) | The CRN of the existing root key of key management service (KMS) that is used to encrypt the flow logs Cloud Object Storage bucket. If no value is set for this variable, specify a value for the `existing_kms_instance_crn` variable to create a key ring and key. | `string` | `null` | no |
+| [existing\_kms\_instance\_crn](#input\_existing\_kms\_instance\_crn) | The CRN of the existing key management service (KMS) that is used to create keys for encrypting the flow logs Cloud Object Storage bucket. Used to create a new KMS key unless an existing key is passed using the `existing_flow_logs_bucket_kms_key_crn` input. | `string` | `null` | no |
+| [existing\_resource\_group\_name](#input\_existing\_resource\_group\_name) | The name of an existing resource group to provision the resources. | `string` | `"Default"` | no |
+| [flow\_logs\_cos\_bucket\_archive\_days](#input\_flow\_logs\_cos\_bucket\_archive\_days) | The number of days before the `archive_type` rule action takes effect for the flow logs cloud object storage bucket. | `number` | `90` | no |
+| [flow\_logs\_cos\_bucket\_archive\_type](#input\_flow\_logs\_cos\_bucket\_archive\_type) | The storage class or archive type you want the object to transition to in the flow logs cloud object storage bucket. | `string` | `"Glacier"` | no |
+| [flow\_logs\_cos\_bucket\_default\_retention\_days](#input\_flow\_logs\_cos\_bucket\_default\_retention\_days) | The number of days that an object can remain unmodified in the flow logs cloud object storage bucket. | `number` | `90` | no |
+| [flow\_logs\_cos\_bucket\_enable\_object\_versioning](#input\_flow\_logs\_cos\_bucket\_enable\_object\_versioning) | Set it to true if object versioning is enabled so that multiple versions of an object are retained in the flow logs cloud object storage bucket. Cannot be used if `flow_logs_cos_bucket_enable_retention` is true. | `bool` | `false` | no |
+| [flow\_logs\_cos\_bucket\_enable\_permanent\_retention](#input\_flow\_logs\_cos\_bucket\_enable\_permanent\_retention) | Whether permanent retention status is enabled for the flow logs cloud object storage bucket. [Learn more](https://cloud.ibm.com/docs/cloud-object-storage?topic=cloud-object-storage-immutable). | `bool` | `false` | no |
+| [flow\_logs\_cos\_bucket\_enable\_retention](#input\_flow\_logs\_cos\_bucket\_enable\_retention) | Set to true to enable retention for the flow logs cloud object storage bucket. | `bool` | `false` | no |
+| [flow\_logs\_cos\_bucket\_expire\_days](#input\_flow\_logs\_cos\_bucket\_expire\_days) | The number of days before the expire rule action takes effect for the flow logs cloud object storage bucket. | `number` | `366` | no |
+| [flow\_logs\_cos\_bucket\_maximum\_retention\_days](#input\_flow\_logs\_cos\_bucket\_maximum\_retention\_days) | The maximum number of days that an object can be kept unmodified in the flow logs cloud object storage. | `number` | `350` | no |
+| [flow\_logs\_cos\_bucket\_minimum\_retention\_days](#input\_flow\_logs\_cos\_bucket\_minimum\_retention\_days) | The minimum number of days that an object must be kept unmodified in the flow logs cloud object storage. | `number` | `90` | no |
+| [flow\_logs\_cos\_bucket\_name](#input\_flow\_logs\_cos\_bucket\_name) | Name of the Cloud Object Storage bucket to be created to collect VPC flow logs. | `string` | `"flow-logs-bucket"` | no |
+| [ibmcloud\_api\_key](#input\_ibmcloud\_api\_key) | The IBM Cloud API key to deploy resources. | `string` | n/a | yes |
+| [ibmcloud\_kms\_api\_key](#input\_ibmcloud\_kms\_api\_key) | The IBM Cloud API key that can create a root key and key ring in the key management service (KMS) instance. If not specified, the 'ibmcloud\_api\_key' variable is used. Specify this key if the instance in `existing_kms_instance_crn` is in an account that's different from the Cloud Object Storage instance. Leave this input empty if the same account owns both instances. | `string` | `null` | no |
+| [kms\_key\_name](#input\_kms\_key\_name) | The name of the key to encrypt the flow logs Cloud Object Storage bucket. If an existing key is used, this variable is not required. If the prefix input variable is passed, the name of the key is prefixed to the value in the `list(|
object({
name = string
add_ibm_cloud_internal_rules = optional(bool)
add_vpc_connectivity_rules = optional(bool)
prepend_ibm_rules = optional(bool)
rules = list(
object({
name = string
action = string
destination = string
direction = string
source = string
tcp = optional(
object({
port_max = optional(number)
port_min = optional(number)
source_port_max = optional(number)
source_port_min = optional(number)
})
)
udp = optional(
object({
port_max = optional(number)
port_min = optional(number)
source_port_max = optional(number)
source_port_min = optional(number)
})
)
icmp = optional(
object({
type = optional(number)
code = optional(number)
})
)
})
)
})
)
[| no | +| [prefix](#input\_prefix) | Prefix to add to all the resources created by this solution. To not use any prefix value, you can set this value to `null` or an empty string. | `string` | n/a | yes | +| [region](#input\_region) | Region to deploy the VPC. | `string` | `"us-south"` | no | +| [resource\_tags](#input\_resource\_tags) | The list of tags to add to the VPC instance. | `list(string)` | `[]` | no | +| [routes](#input\_routes) | Allows you to specify the next hop for packets based on their destination address. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/solutions/fully-configurable/DA-types.md#routes-). |
{
"add_ibm_cloud_internal_rules": true,
"add_vpc_connectivity_rules": true,
"name": "vpc-acl",
"prepend_ibm_rules": true,
"rules": [
{
"action": "allow",
"destination": "0.0.0.0/0",
"direction": "inbound",
"name": "allow-all-443-inbound",
"source": "0.0.0.0/0",
"tcp": {
"port_max": 443,
"port_min": 443,
"source_port_max": 443,
"source_port_min": 443
}
},
{
"action": "allow",
"destination": "0.0.0.0/0",
"direction": "inbound",
"name": "allow-all-80-inbound",
"source": "0.0.0.0/0",
"tcp": {
"port_max": 80,
"port_min": 80,
"source_port_max": 80,
"source_port_min": 80
}
},
{
"action": "allow",
"destination": "0.0.0.0/0",
"direction": "inbound",
"name": "allow-all-22-inbound",
"source": "0.0.0.0/0",
"tcp": {
"port_max": 22,
"port_min": 22,
"source_port_max": 22,
"source_port_min": 22
}
},
{
"action": "allow",
"destination": "0.0.0.0/0",
"direction": "outbound",
"name": "allow-all-443-outbound",
"source": "0.0.0.0/0",
"tcp": {
"port_max": 443,
"port_min": 443,
"source_port_max": 443,
"source_port_min": 443
}
},
{
"action": "allow",
"destination": "0.0.0.0/0",
"direction": "outbound",
"name": "allow-all-80-outbound",
"source": "0.0.0.0/0",
"tcp": {
"port_max": 80,
"port_min": 80,
"source_port_max": 80,
"source_port_min": 80
}
},
{
"action": "allow",
"destination": "0.0.0.0/0",
"direction": "outbound",
"name": "allow-all-22-outbound",
"source": "0.0.0.0/0",
"tcp": {
"port_max": 22,
"port_min": 22,
"source_port_max": 22,
"source_port_min": 22
}
}
]
}
]
list(| `[]` | no | +| [security\_group\_rules](#input\_security\_group\_rules) | A list of security group rules to be added to the default vpc security group (default empty). [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/solutions/fully-configurable/DA-types.md#security-group-rules-). |
object({
name = string
route_direct_link_ingress = optional(bool)
route_transit_gateway_ingress = optional(bool)
route_vpc_zone_ingress = optional(bool)
routes = optional(
list(
object({
action = optional(string)
zone = number
destination = string
next_hop = string
})
))
})
)
list(| `[]` | no | +| [skip\_cos\_kms\_iam\_auth\_policy](#input\_skip\_cos\_kms\_iam\_auth\_policy) | To skip creating an IAM authorization policy that allows Cloud Object Storage(COS) to access KMS key. | `bool` | `false` | no | +| [skip\_vpc\_cos\_iam\_auth\_policy](#input\_skip\_vpc\_cos\_iam\_auth\_policy) | To skip creating an IAM authorization policy that allows the VPC to access the Cloud Object Storage, set this variable to `true`. Required only if `enable_vpc_flow_logs` is set to true. | `bool` | `false` | no | +| [subnets](#input\_subnets) | List of subnets for the vpc. For each item in each array, a subnet will be created. Items can be either CIDR blocks or total ipv4 addressess. Public gateways will be enabled only in zones where a gateway has been created. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/solutions/fully-configurable/DA-types.md#subnets-). |
object({
name = string
direction = string
remote = optional(string)
tcp = optional(
object({
port_max = optional(number)
port_min = optional(number)
})
)
udp = optional(
object({
port_max = optional(number)
port_min = optional(number)
})
)
icmp = optional(
object({
type = optional(number)
code = optional(number)
})
)
})
)
object({
zone-1 = list(object({
name = string
cidr = string
public_gateway = optional(bool)
acl_name = string
no_addr_prefix = optional(bool, false) # do not automatically add address prefix for subnet, overrides other conditions if set to true
subnet_tags = optional(list(string), [])
}))
zone-2 = optional(list(object({
name = string
cidr = string
public_gateway = optional(bool)
acl_name = string
no_addr_prefix = optional(bool, false) # do not automatically add address prefix for subnet, overrides other conditions if set to true
subnet_tags = optional(list(string), [])
})))
zone-3 = optional(list(object({
name = string
cidr = string
public_gateway = optional(bool)
acl_name = string
no_addr_prefix = optional(bool, false) # do not automatically add address prefix for subnet, overrides other conditions if set to true
subnet_tags = optional(list(string), [])
})))
}) | {
"zone-1": [
{
"acl_name": "vpc-acl",
"cidr": "10.10.10.0/24",
"name": "subnet-a",
"no_addr_prefix": false,
"public_gateway": true
}
]
} | no |
+| [vpc\_name](#input\_vpc\_name) | Name of the VPC. If a prefix input variable is specified, the prefix is added to the name in the `set(| `[]` | no | +| [vpe\_gateway\_cloud\_services](#input\_vpe\_gateway\_cloud\_services) | The list of cloud services used to create endpoint gateways. If `vpe_name` is not specified in the list, VPE names are created in the format `
object({
crn = string
vpe_name = optional(string) # Full control on the VPE name. If not specified, the VPE name will be computed based on prefix, vpc name and service name.
service_name = optional(string) # Name of the service used to compute the name of the VPE. If not specified, the service name will be obtained from the crn.
allow_dns_resolution_binding = optional(bool, true)
})
)
set(object({
service_name = string
vpe_name = optional(string), # Full control on the VPE name. If not specified, the VPE name will be computed based on prefix, vpc name and service name.
allow_dns_resolution_binding = optional(bool, false)
})) | `[]` | no |
+| [vpe\_gateway\_reserved\_ips](#input\_vpe\_gateway\_reserved\_ips) | Map of existing reserved IP names and values. Leave this value as default if you want to create new reserved ips, this value is used when a user passes their existing reserved ips created here and not attempt to recreate those. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/solutions/fully-configurable/DA-types.md#reserved-ips-). | object({
name = optional(string) # reserved ip name
}) | `{}` | no |
+| [vpe\_gateway\_security\_group\_ids](#input\_vpe\_gateway\_security\_group\_ids) | List of security group ids to attach to each endpoint gateway. | `list(string)` | `null` | no |
+| [vpn\_gateways](#input\_vpn\_gateways) | List of VPN Gateways to create. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/solutions/fully-configurable/DA-types.md#vpn-gateways-). | list(| `[]` | no | + +### Outputs + +| Name | Description | +|------|-------------| +| [network\_acls](#output\_network\_acls) | List of shortnames and IDs of network ACLs | +| [private\_path\_subnet\_id](#output\_private\_path\_subnet\_id) | The IDs of the subnets | +| [public\_gateways](#output\_public\_gateways) | Map of public gateways by zone | +| [security\_group\_details](#output\_security\_group\_details) | Details of security group. | +| [subnet\_detail\_list](#output\_subnet\_detail\_list) | A list of subnets containing names, CIDR blocks, and zones. | +| [subnet\_detail\_map](#output\_subnet\_detail\_map) | A map of subnets containing IDs, CIDR blocks, and zones | +| [subnet\_ids](#output\_subnet\_ids) | The IDs of the subnets | +| [subnet\_zone\_list](#output\_subnet\_zone\_list) | A list containing subnet IDs and subnet zones | +| [vpc\_crn](#output\_vpc\_crn) | CRN of VPC created | +| [vpc\_flow\_logs](#output\_vpc\_flow\_logs) | Details of VPC flow logs collector | +| [vpc\_id](#output\_vpc\_id) | ID of VPC created | +| [vpc\_name](#output\_vpc\_name) | Name of VPC created | +| [vpe\_crn](#output\_vpe\_crn) | The CRN of the endpoint gateway | +| [vpe\_ips](#output\_vpe\_ips) | The reserved IPs for endpoint gateways. | +| [vpn\_gateways\_data](#output\_vpn\_gateways\_data) | Details of VPN gateways data | +| [vpn\_gateways\_name](#output\_vpn\_gateways\_name) | List of names of VPN gateways. | + diff --git a/solutions/security-enforced/main.tf b/solutions/security-enforced/main.tf new file mode 100644 index 00000000..2a82619c --- /dev/null +++ b/solutions/security-enforced/main.tf @@ -0,0 +1,54 @@ +####################################################################################################################### +# Wrapper around fully-configurable variation +####################################################################################################################### + +module "vpc_da" { + source = "../fully-configurable" + ibmcloud_api_key = var.ibmcloud_api_key + existing_resource_group_name = var.existing_resource_group_name + prefix = var.prefix + provider_visibility = "private" + vpc_name = var.vpc_name + region = var.region + resource_tags = var.resource_tags + access_tags = var.access_tags + subnets = var.subnets + network_acls = var.network_acls + security_group_rules = var.security_group_rules + clean_default_security_group_acl = var.clean_default_security_group_acl + address_prefixes = var.address_prefixes + routes = var.routes + enable_vpc_flow_logs = var.enable_vpc_flow_logs + skip_vpc_cos_iam_auth_policy = var.skip_vpc_cos_iam_auth_policy + existing_cos_instance_crn = var.existing_cos_instance_crn + flow_logs_cos_bucket_name = var.flow_logs_cos_bucket_name + kms_encryption_enabled_bucket = true + skip_cos_kms_iam_auth_policy = var.skip_cos_kms_iam_auth_policy + management_endpoint_type_for_bucket = "private" + cos_bucket_class = var.cos_bucket_class + add_bucket_name_suffix = var.add_bucket_name_suffix + flow_logs_cos_bucket_archive_days = var.flow_logs_cos_bucket_archive_days + flow_logs_cos_bucket_archive_type = var.flow_logs_cos_bucket_archive_type + flow_logs_cos_bucket_expire_days = var.flow_logs_cos_bucket_expire_days + flow_logs_cos_bucket_enable_object_versioning = var.flow_logs_cos_bucket_enable_object_versioning + flow_logs_cos_bucket_enable_retention = var.flow_logs_cos_bucket_enable_retention + flow_logs_cos_bucket_default_retention_days = var.flow_logs_cos_bucket_default_retention_days + flow_logs_cos_bucket_maximum_retention_days = var.flow_logs_cos_bucket_maximum_retention_days + flow_logs_cos_bucket_minimum_retention_days = var.flow_logs_cos_bucket_minimum_retention_days + flow_logs_cos_bucket_enable_permanent_retention = var.flow_logs_cos_bucket_enable_permanent_retention + existing_flow_logs_bucket_kms_key_crn = var.existing_flow_logs_bucket_kms_key_crn + existing_kms_instance_crn = var.existing_kms_instance_crn + kms_endpoint_type = "private" + kms_key_ring_name = var.kms_key_ring_name + kms_key_name = var.kms_key_name + ibmcloud_kms_api_key = var.ibmcloud_kms_api_key + default_network_acl_name = var.default_network_acl_name + default_security_group_name = var.default_security_group_name + default_routing_table_name = var.default_routing_table_name + vpn_gateways = var.vpn_gateways + vpe_gateway_cloud_services = var.vpe_gateway_cloud_services + vpe_gateway_cloud_service_by_crn = var.vpe_gateway_cloud_service_by_crn + vpe_gateway_service_endpoints = "private" + vpe_gateway_security_group_ids = var.vpe_gateway_security_group_ids + vpe_gateway_reserved_ips = var.vpe_gateway_reserved_ips +} \ No newline at end of file diff --git a/solutions/security-enforced/outputs.tf b/solutions/security-enforced/outputs.tf new file mode 100644 index 00000000..0a8cfef0 --- /dev/null +++ b/solutions/security-enforced/outputs.tf @@ -0,0 +1,111 @@ +############################################################################## +# VPC +############################################################################## + +output "vpc_name" { + description = "Name of VPC created" + value = module.vpc.vpc_name +} + +output "vpc_id" { + description = "ID of VPC created" + value = module.vpc.vpc_id +} + +output "vpc_crn" { + description = "CRN of VPC created" + value = module.vpc.vpc_crn +} + +############################################################################## +# Public Gateways +############################################################################## + +output "public_gateways" { + description = "Map of public gateways by zone" + value = module.vpc.public_gateways +} + +############################################################################## +# VPC flow logs +############################################################################## + +output "vpc_flow_logs" { + description = "Details of VPC flow logs collector" + value = module.vpc.vpc_flow_logs +} + +############################################################################## +# Network ACLs +############################################################################## + +output "network_acls" { + description = "List of shortnames and IDs of network ACLs" + value = module.vpc.network_acls +} + +############################################################################## +# Subnet Outputs +############################################################################## + +output "subnet_ids" { + description = "The IDs of the subnets" + value = module.vpc.subnet_ids +} + +output "private_path_subnet_id" { + description = "The IDs of the subnets" + value = length(module.vpc.subnet_ids) > 0 ? module.vpc.subnet_ids[0] : null +} + +output "subnet_detail_list" { + description = "A list of subnets containing names, CIDR blocks, and zones." + value = module.vpc.subnet_detail_list +} + +output "subnet_zone_list" { + description = "A list containing subnet IDs and subnet zones" + value = module.vpc.subnet_zone_list +} + +output "subnet_detail_map" { + description = "A map of subnets containing IDs, CIDR blocks, and zones" + value = module.vpc.subnet_detail_map +} + +############################################################################## +# VPN Gateways Outputs +############################################################################## + +output "vpn_gateways_name" { + description = "List of names of VPN gateways." + value = module.vpc.vpn_gateways_name +} + +output "vpn_gateways_data" { + description = "Details of VPN gateways data" + value = module.vpc.vpn_gateways_data +} + +############################################################################## +# VPE Outputs +############################################################################## + +output "vpe_ips" { + description = "The reserved IPs for endpoint gateways." + value = module.vpe_gateway.vpe_ips +} + +output "vpe_crn" { + description = "The CRN of the endpoint gateway" + value = module.vpe_gateway.crn +} + +############################################################################## +# Security Group Details +############################################################################## + +output "security_group_details" { + description = "Details of security group." + value = module.vpc.security_group_details +} diff --git a/solutions/security-enforced/provider.tf b/solutions/security-enforced/provider.tf new file mode 100644 index 00000000..6c7e4a40 --- /dev/null +++ b/solutions/security-enforced/provider.tf @@ -0,0 +1 @@ +# Explicit provider config not required here as provider config in fully-configurable is used \ No newline at end of file diff --git a/solutions/security-enforced/variables.tf b/solutions/security-enforced/variables.tf new file mode 100644 index 00000000..2d7c5754 --- /dev/null +++ b/solutions/security-enforced/variables.tf @@ -0,0 +1,641 @@ +############################################################################## +# Input Variables +############################################################################## + +variable "ibmcloud_api_key" { + type = string + description = "The IBM Cloud API key to deploy resources." + sensitive = true +} + + +variable "existing_resource_group_name" { + type = string + description = "The name of an existing resource group to provision the resources." + default = "Default" +} + +variable "prefix" { + type = string + nullable = true + description = "Prefix to add to all the resources created by this solution. To not use any prefix value, you can set this value to `null` or an empty string." + + validation { + condition = (var.prefix == null ? true : + alltrue([ + can(regex("^[a-z]{0,1}[-a-z0-9]{0,14}[a-z0-9]{0,1}$", var.prefix)), + length(regexall("^.*--.*", var.prefix)) == 0 + ]) + ) + error_message = "Prefix must begin with a lowercase letter, contain only lowercase letters, numbers, and - characters. Prefixes must end with a lowercase letter or number and be 16 or fewer characters." + } +} + +variable "vpc_name" { + default = "vpc" + description = "Name of the VPC. If a prefix input variable is specified, the prefix is added to the name in the `
object({
name = string
subnet_name = string # Do not include prefix, use same name as in `var.subnets`
mode = optional(string)
resource_group = optional(string)
access_tags = optional(list(string), [])
})
)