diff --git a/README.md b/README.md index 4848a6c..e21e5fb 100644 --- a/README.md +++ b/README.md @@ -224,8 +224,15 @@ Available targets: | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | [additional\_routes](#input\_additional\_routes) | A list of additional routes that should be attached to the Client VPN endpoint |
list(object({
destination_cidr_block = string
description = string
target_vpc_subnet_id = string
}))
| `[]` | no | -| [additional\_security\_groups](#input\_additional\_security\_groups) | List of security groups to attach to the client vpn network associations | `list(string)` | `[]` | no | +| [additional\_security\_group\_rules](#input\_additional\_security\_group\_rules) | A list of Security Group rule objects to add to the created security group, in addition to the ones
this module normally creates. (To suppress the module's rules, set `create_security_group` to false
and supply your own security group via `associated_security_group_ids`.)
The keys and values of the objects are fully compatible with the `aws_security_group_rule` resource, except
for `security_group_id` which will be ignored, and the optional "key" which, if provided, must be unique and known at "plan" time.
To get more info see https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule . | `list(any)` | `[]` | no | +| [additional\_security\_groups](#input\_additional\_security\_groups) | DEPRECATED: Use `associated_security_group_ids` instead.
List of security groups to attach to the client vpn network associations | `list(string)` | `[]` | no | | [additional\_tag\_map](#input\_additional\_tag\_map) | Additional key-value pairs to add to each map in `tags_as_list_of_maps`. Not added to `tags` or `id`.
This is for some rare cases where resources want additional configuration of tags
and therefore take a list of maps with tag key, value, and additional configuration. | `map(string)` | `{}` | no | +| [allow\_self\_security\_group](#input\_allow\_self\_security\_group) | Whether the security group itself will be added as a source to this ingress rule. | `bool` | `true` | no | +| [allowed\_cidr\_blocks](#input\_allowed\_cidr\_blocks) | A list of IPv4 CIDRs to allow access to the security group created by this module.
The length of this list must be known at "plan" time. | `list(string)` | `[]` | no | +| [allowed\_ipv6\_cidr\_blocks](#input\_allowed\_ipv6\_cidr\_blocks) | A list of IPv6 CIDRs to allow access to the security group created by this module.
The length of this list must be known at "plan" time. | `list(string)` | `[]` | no | +| [allowed\_ipv6\_prefix\_list\_ids](#input\_allowed\_ipv6\_prefix\_list\_ids) | A list of IPv6 Prefix Lists IDs to allow access to the security group created by this module.
The length of this list must be known at "plan" time. | `list(string)` | `[]` | no | +| [allowed\_security\_group\_ids](#input\_allowed\_security\_group\_ids) | A list of IDs of Security Groups to allow access to the security group created by this module.
The length of this list must be known at "plan" time. | `list(string)` | `[]` | no | +| [associated\_security\_group\_ids](#input\_associated\_security\_group\_ids) | A list of IDs of Security Groups to associate the VPN endpoints with, in addition to the created security group.
These security groups will not be modified and, if `create_security_group` is `false`, must have rules providing the desired access. | `list(string)` | `[]` | no | | [associated\_subnets](#input\_associated\_subnets) | List of subnets to associate with the VPN endpoint | `list(string)` | n/a | yes | | [attributes](#input\_attributes) | ID element. Additional attributes (e.g. `workers` or `cluster`) to add to `id`,
in the order they appear in the list. New attributes are appended to the
end of the list. The elements of the list are joined by the `delimiter`
and treated as a single ID element. | `list(string)` | `[]` | no | | [authentication\_type](#input\_authentication\_type) | One of `certificate-authentication` or `federated-authentication` | `string` | `"certificate-authentication"` | no | @@ -234,6 +241,7 @@ Available targets: | [client\_cidr](#input\_client\_cidr) | Network CIDR to use for clients | `string` | n/a | yes | | [client\_conf\_tmpl\_path](#input\_client\_conf\_tmpl\_path) | Path to template file of vpn client exported configuration. Path is relative to ${path.module} | `string` | `null` | no | | [context](#input\_context) | Single object for setting entire context at once.
See description of individual variables for details.
Leave string and numeric variables as `null` to use default value.
Individual variable settings (non-null) override settings in context object,
except for attributes, tags, and additional\_tag\_map, which are merged. | `any` |
{
"additional_tag_map": {},
"attributes": [],
"delimiter": null,
"descriptor_formats": {},
"enabled": true,
"environment": null,
"id_length_limit": null,
"label_key_case": null,
"label_order": [],
"label_value_case": null,
"labels_as_tags": [
"unset"
],
"name": null,
"namespace": null,
"regex_replace_chars": null,
"stage": null,
"tags": {},
"tenant": null
}
| no | +| [create\_security\_group](#input\_create\_security\_group) | Set `true` to create and configure a new security group. If false, `associated_security_group_ids` must be provided. | `bool` | `true` | no | | [delimiter](#input\_delimiter) | Delimiter to be used between ID elements.
Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. | `string` | `null` | no | | [descriptor\_formats](#input\_descriptor\_formats) | Describe additional descriptors to be output in the `descriptors` output map.
Map of maps. Keys are names of descriptors. Values are maps of the form
`{
format = string
labels = list(string)
}`
(Type is `any` so the map values can later be enhanced to provide additional options.)
`format` is a Terraform format string to be passed to the `format()` function.
`labels` is a list of labels, in order, to pass to `format()` function.
Label values will be normalized before being passed to `format()` so they will be
identical to how they appear in `id`.
Default is `{}` (`descriptors` output will be empty). | `any` | `{}` | no | | [dns\_servers](#input\_dns\_servers) | Information about the DNS servers to be used for DNS resolution. A Client VPN endpoint can have up to two DNS servers. If no DNS server is specified, the DNS address of the VPC that is to be associated with Client VPN endpoint is used as the DNS server. | `list(string)` | `[]` | no | @@ -255,6 +263,11 @@ Available targets: | [root\_common\_name](#input\_root\_common\_name) | Unique Common Name for Root self-signed certificate | `string` | `null` | no | | [saml\_metadata\_document](#input\_saml\_metadata\_document) | Optional SAML metadata document. Must include this or `saml_provider_arn` | `string` | `null` | no | | [saml\_provider\_arn](#input\_saml\_provider\_arn) | Optional SAML provider ARN. Must include this or `saml_metadata_document` | `string` | `null` | no | +| [security\_group\_create\_before\_destroy](#input\_security\_group\_create\_before\_destroy) | Set `true` to enable Terraform `create_before_destroy` behavior on the created security group.
Note that changing this value will always cause the security group to be replaced. | `bool` | `true` | no | +| [security\_group\_create\_timeout](#input\_security\_group\_create\_timeout) | How long to wait for the security group to be created. | `string` | `"10m"` | no | +| [security\_group\_delete\_timeout](#input\_security\_group\_delete\_timeout) | How long to retry on `DependencyViolation` errors during security group deletion from
lingering ENIs left by certain AWS services such as Elastic Load Balancing. | `string` | `"15m"` | no | +| [security\_group\_description](#input\_security\_group\_description) | The description to assign to the created Security Group.
Warning: Changing the description causes the security group to be replaced. | `string` | `null` | no | +| [security\_group\_name](#input\_security\_group\_name) | The name to assign to the created security group. Must be unique within the VPC.
If not provided, will be derived from the `null-label.context` passed in.
If `create_before_destroy` is true, will be used as a name prefix. | `list(string)` | `[]` | no | | [server\_common\_name](#input\_server\_common\_name) | Unique Common Name for Server self-signed certificate | `string` | `null` | no | | [split\_tunnel](#input\_split\_tunnel) | Indicates whether split-tunnel is enabled on VPN endpoint. Default value is false. | `bool` | `false` | no | | [stage](#input\_stage) | ID element. Usually used to indicate role, e.g. 'prod', 'staging', 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no | diff --git a/docs/terraform.md b/docs/terraform.md index 0406e2a..9994f1c 100644 --- a/docs/terraform.md +++ b/docs/terraform.md @@ -43,8 +43,15 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | [additional\_routes](#input\_additional\_routes) | A list of additional routes that should be attached to the Client VPN endpoint |
list(object({
destination_cidr_block = string
description = string
target_vpc_subnet_id = string
}))
| `[]` | no | -| [additional\_security\_groups](#input\_additional\_security\_groups) | List of security groups to attach to the client vpn network associations | `list(string)` | `[]` | no | +| [additional\_security\_group\_rules](#input\_additional\_security\_group\_rules) | A list of Security Group rule objects to add to the created security group, in addition to the ones
this module normally creates. (To suppress the module's rules, set `create_security_group` to false
and supply your own security group via `associated_security_group_ids`.)
The keys and values of the objects are fully compatible with the `aws_security_group_rule` resource, except
for `security_group_id` which will be ignored, and the optional "key" which, if provided, must be unique and known at "plan" time.
To get more info see https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule . | `list(any)` | `[]` | no | +| [additional\_security\_groups](#input\_additional\_security\_groups) | DEPRECATED: Use `associated_security_group_ids` instead.
List of security groups to attach to the client vpn network associations | `list(string)` | `[]` | no | | [additional\_tag\_map](#input\_additional\_tag\_map) | Additional key-value pairs to add to each map in `tags_as_list_of_maps`. Not added to `tags` or `id`.
This is for some rare cases where resources want additional configuration of tags
and therefore take a list of maps with tag key, value, and additional configuration. | `map(string)` | `{}` | no | +| [allow\_self\_security\_group](#input\_allow\_self\_security\_group) | Whether the security group itself will be added as a source to this ingress rule. | `bool` | `true` | no | +| [allowed\_cidr\_blocks](#input\_allowed\_cidr\_blocks) | A list of IPv4 CIDRs to allow access to the security group created by this module.
The length of this list must be known at "plan" time. | `list(string)` | `[]` | no | +| [allowed\_ipv6\_cidr\_blocks](#input\_allowed\_ipv6\_cidr\_blocks) | A list of IPv6 CIDRs to allow access to the security group created by this module.
The length of this list must be known at "plan" time. | `list(string)` | `[]` | no | +| [allowed\_ipv6\_prefix\_list\_ids](#input\_allowed\_ipv6\_prefix\_list\_ids) | A list of IPv6 Prefix Lists IDs to allow access to the security group created by this module.
The length of this list must be known at "plan" time. | `list(string)` | `[]` | no | +| [allowed\_security\_group\_ids](#input\_allowed\_security\_group\_ids) | A list of IDs of Security Groups to allow access to the security group created by this module.
The length of this list must be known at "plan" time. | `list(string)` | `[]` | no | +| [associated\_security\_group\_ids](#input\_associated\_security\_group\_ids) | A list of IDs of Security Groups to associate the VPN endpoints with, in addition to the created security group.
These security groups will not be modified and, if `create_security_group` is `false`, must have rules providing the desired access. | `list(string)` | `[]` | no | | [associated\_subnets](#input\_associated\_subnets) | List of subnets to associate with the VPN endpoint | `list(string)` | n/a | yes | | [attributes](#input\_attributes) | ID element. Additional attributes (e.g. `workers` or `cluster`) to add to `id`,
in the order they appear in the list. New attributes are appended to the
end of the list. The elements of the list are joined by the `delimiter`
and treated as a single ID element. | `list(string)` | `[]` | no | | [authentication\_type](#input\_authentication\_type) | One of `certificate-authentication` or `federated-authentication` | `string` | `"certificate-authentication"` | no | @@ -53,6 +60,7 @@ | [client\_cidr](#input\_client\_cidr) | Network CIDR to use for clients | `string` | n/a | yes | | [client\_conf\_tmpl\_path](#input\_client\_conf\_tmpl\_path) | Path to template file of vpn client exported configuration. Path is relative to ${path.module} | `string` | `null` | no | | [context](#input\_context) | Single object for setting entire context at once.
See description of individual variables for details.
Leave string and numeric variables as `null` to use default value.
Individual variable settings (non-null) override settings in context object,
except for attributes, tags, and additional\_tag\_map, which are merged. | `any` |
{
"additional_tag_map": {},
"attributes": [],
"delimiter": null,
"descriptor_formats": {},
"enabled": true,
"environment": null,
"id_length_limit": null,
"label_key_case": null,
"label_order": [],
"label_value_case": null,
"labels_as_tags": [
"unset"
],
"name": null,
"namespace": null,
"regex_replace_chars": null,
"stage": null,
"tags": {},
"tenant": null
}
| no | +| [create\_security\_group](#input\_create\_security\_group) | Set `true` to create and configure a new security group. If false, `associated_security_group_ids` must be provided. | `bool` | `true` | no | | [delimiter](#input\_delimiter) | Delimiter to be used between ID elements.
Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. | `string` | `null` | no | | [descriptor\_formats](#input\_descriptor\_formats) | Describe additional descriptors to be output in the `descriptors` output map.
Map of maps. Keys are names of descriptors. Values are maps of the form
`{
format = string
labels = list(string)
}`
(Type is `any` so the map values can later be enhanced to provide additional options.)
`format` is a Terraform format string to be passed to the `format()` function.
`labels` is a list of labels, in order, to pass to `format()` function.
Label values will be normalized before being passed to `format()` so they will be
identical to how they appear in `id`.
Default is `{}` (`descriptors` output will be empty). | `any` | `{}` | no | | [dns\_servers](#input\_dns\_servers) | Information about the DNS servers to be used for DNS resolution. A Client VPN endpoint can have up to two DNS servers. If no DNS server is specified, the DNS address of the VPC that is to be associated with Client VPN endpoint is used as the DNS server. | `list(string)` | `[]` | no | @@ -74,6 +82,11 @@ | [root\_common\_name](#input\_root\_common\_name) | Unique Common Name for Root self-signed certificate | `string` | `null` | no | | [saml\_metadata\_document](#input\_saml\_metadata\_document) | Optional SAML metadata document. Must include this or `saml_provider_arn` | `string` | `null` | no | | [saml\_provider\_arn](#input\_saml\_provider\_arn) | Optional SAML provider ARN. Must include this or `saml_metadata_document` | `string` | `null` | no | +| [security\_group\_create\_before\_destroy](#input\_security\_group\_create\_before\_destroy) | Set `true` to enable Terraform `create_before_destroy` behavior on the created security group.
Note that changing this value will always cause the security group to be replaced. | `bool` | `true` | no | +| [security\_group\_create\_timeout](#input\_security\_group\_create\_timeout) | How long to wait for the security group to be created. | `string` | `"10m"` | no | +| [security\_group\_delete\_timeout](#input\_security\_group\_delete\_timeout) | How long to retry on `DependencyViolation` errors during security group deletion from
lingering ENIs left by certain AWS services such as Elastic Load Balancing. | `string` | `"15m"` | no | +| [security\_group\_description](#input\_security\_group\_description) | The description to assign to the created Security Group.
Warning: Changing the description causes the security group to be replaced. | `string` | `null` | no | +| [security\_group\_name](#input\_security\_group\_name) | The name to assign to the created security group. Must be unique within the VPC.
If not provided, will be derived from the `null-label.context` passed in.
If `create_before_destroy` is true, will be used as a name prefix. | `list(string)` | `[]` | no | | [server\_common\_name](#input\_server\_common\_name) | Unique Common Name for Server self-signed certificate | `string` | `null` | no | | [split\_tunnel](#input\_split\_tunnel) | Indicates whether split-tunnel is enabled on VPN endpoint. Default value is false. | `bool` | `false` | no | | [stage](#input\_stage) | ID element. Usually used to indicate role, e.g. 'prod', 'staging', 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no | diff --git a/examples/complete/fixtures.us-east-2.tfvars b/examples/complete/fixtures.us-east-2.tfvars index d1034eb..8db8053 100644 --- a/examples/complete/fixtures.us-east-2.tfvars +++ b/examples/complete/fixtures.us-east-2.tfvars @@ -29,7 +29,7 @@ organization_name = "Cloud Posse" availability_zones = ["us-east-2a", "us-east-2b"] -additional_security_groups = [] +associated_security_group_ids = [] authorization_rules = [ ] diff --git a/examples/complete/main.tf b/examples/complete/main.tf index 9a03c93..395a8f8 100644 --- a/examples/complete/main.tf +++ b/examples/complete/main.tf @@ -25,7 +25,7 @@ module "vpc_target" { module "subnets" { source = "cloudposse/dynamic-subnets/aws" - version = "0.39.3" + version = "0.39.8" availability_zones = var.availability_zones vpc_id = module.vpc_target.vpc_id @@ -43,19 +43,19 @@ module "ec2_client_vpn" { root_common_name = var.root_common_name server_common_name = var.server_common_name - client_cidr = var.client_cidr_block - organization_name = var.organization_name - logging_enabled = var.logging_enabled - logging_stream_name = var.logging_stream_name - retention_in_days = var.retention_in_days - associated_subnets = module.subnets.private_subnet_ids - authorization_rules = var.authorization_rules - additional_routes = local.additional_routes - additional_security_groups = var.additional_security_groups - export_client_certificate = var.export_client_certificate - vpc_id = module.vpc_target.vpc_id - dns_servers = var.dns_servers - split_tunnel = var.split_tunnel + client_cidr = var.client_cidr_block + organization_name = var.organization_name + logging_enabled = var.logging_enabled + logging_stream_name = var.logging_stream_name + retention_in_days = var.retention_in_days + associated_subnets = module.subnets.private_subnet_ids + authorization_rules = var.authorization_rules + additional_routes = local.additional_routes + associated_security_group_ids = var.associated_security_group_ids + export_client_certificate = var.export_client_certificate + vpc_id = module.vpc_target.vpc_id + dns_servers = var.dns_servers + split_tunnel = var.split_tunnel context = module.this.context } diff --git a/examples/complete/variables.tf b/examples/complete/variables.tf index 325cef1..5bda586 100644 --- a/examples/complete/variables.tf +++ b/examples/complete/variables.tf @@ -38,7 +38,7 @@ variable "organization_name" { description = "Name of organization to use in private certificate" } -variable "additional_security_groups" { +variable "associated_security_group_ids" { description = "List of security groups to attach to the client vpn network associations" type = list(string) } diff --git a/main.tf b/main.tf index bfce989..8b9ad11 100644 --- a/main.tf +++ b/main.tf @@ -1,6 +1,7 @@ locals { enabled = module.this.enabled + security_group_enabled = local.enabled && var.create_security_group mutual_enabled = local.enabled && var.authentication_type == "certificate-authentication" federated_enabled = local.enabled && var.authentication_type == "federated-authentication" logging_enabled = local.enabled && var.logging_enabled @@ -174,16 +175,31 @@ module "vpn_security_group" { source = "cloudposse/security-group/aws" version = "0.4.2" - rules = [ + enabled = local.security_group_enabled + security_group_name = var.security_group_name + create_before_destroy = var.security_group_create_before_destroy + security_group_create_timeout = var.security_group_create_timeout + security_group_delete_timeout = var.security_group_delete_timeout + + security_group_description = var.security_group_description + allow_all_egress = true + rules = var.additional_security_group_rules + rule_matrix = [ { - key = "vpn-self" - type = "ingress" - from_port = 0 - to_port = 0 - protocol = "-1" - description = "Allow self access only by default" - self = true - }, + cidr_blocks = var.allowed_cidr_blocks + ipv6_cidr_blocks = var.allowed_ipv6_cidr_blocks + prefix_list_ids = var.allowed_ipv6_prefix_list_ids + source_security_group_ids = var.allowed_security_group_ids + self = var.allow_self_security_group + rules = [{ + key = "vpn-self" + type = "ingress" + from_port = 0 + to_port = 0 + protocol = "-1" + description = "Allow all ingress from designated sources" + }] + } ] vpc_id = var.vpc_id @@ -199,7 +215,7 @@ resource "aws_ec2_client_vpn_network_association" "default" { security_groups = concat( [module.vpn_security_group.id], - var.additional_security_groups + local.associated_security_group_ids ) } diff --git a/security_group_inputs.tf b/security_group_inputs.tf new file mode 100644 index 0000000..ca93367 --- /dev/null +++ b/security_group_inputs.tf @@ -0,0 +1,119 @@ +# security_group_inputs Version: 1 +# + +variable "create_security_group" { + type = bool + default = true + description = "Set `true` to create and configure a new security group. If false, `associated_security_group_ids` must be provided." +} + +variable "associated_security_group_ids" { + type = list(string) + default = [] + description = <<-EOT + A list of IDs of Security Groups to associate the VPN endpoints with, in addition to the created security group. + These security groups will not be modified and, if `create_security_group` is `false`, must have rules providing the desired access. + EOT +} + +locals { + associated_security_group_ids = concat(var.additional_security_groups, var.associated_security_group_ids) +} + +variable "allowed_security_group_ids" { + type = list(string) + default = [] + description = <<-EOT + A list of IDs of Security Groups to allow access to the security group created by this module. + The length of this list must be known at "plan" time. + EOT +} + +variable "allowed_cidr_blocks" { + type = list(string) + default = [] + description = <<-EOT + A list of IPv4 CIDRs to allow access to the security group created by this module. + The length of this list must be known at "plan" time. + EOT +} + +variable "allowed_ipv6_cidr_blocks" { + type = list(string) + default = [] + description = <<-EOT + A list of IPv6 CIDRs to allow access to the security group created by this module. + The length of this list must be known at "plan" time. + EOT +} + +variable "allowed_ipv6_prefix_list_ids" { + type = list(string) + default = [] + description = <<-EOT + A list of IPv6 Prefix Lists IDs to allow access to the security group created by this module. + The length of this list must be known at "plan" time. + EOT +} + +variable "allow_self_security_group" { + type = bool + default = true + description = "Whether the security group itself will be added as a source to this ingress rule." +} + +variable "security_group_name" { + type = list(string) + default = [] + description = <<-EOT + The name to assign to the created security group. Must be unique within the VPC. + If not provided, will be derived from the `null-label.context` passed in. + If `create_before_destroy` is true, will be used as a name prefix. + EOT +} + +variable "security_group_description" { + type = string + default = null + description = <<-EOT + The description to assign to the created Security Group. + Warning: Changing the description causes the security group to be replaced. + EOT +} + +variable "security_group_create_before_destroy" { + type = bool + default = true + description = <<-EOT + Set `true` to enable Terraform `create_before_destroy` behavior on the created security group. + Note that changing this value will always cause the security group to be replaced. + EOT +} + +variable "security_group_create_timeout" { + type = string + default = "10m" + description = "How long to wait for the security group to be created." +} + +variable "security_group_delete_timeout" { + type = string + default = "15m" + description = <<-EOT + How long to retry on `DependencyViolation` errors during security group deletion from + lingering ENIs left by certain AWS services such as Elastic Load Balancing. + EOT +} + +variable "additional_security_group_rules" { + type = list(any) + default = [] + description = <<-EOT + A list of Security Group rule objects to add to the created security group, in addition to the ones + this module normally creates. (To suppress the module's rules, set `create_security_group` to false + and supply your own security group via `associated_security_group_ids`.) + The keys and values of the objects are fully compatible with the `aws_security_group_rule` resource, except + for `security_group_id` which will be ignored, and the optional "key" which, if provided, must be unique and known at "plan" time. + To get more info see https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule . + EOT +} diff --git a/variables-deprecated.tf b/variables-deprecated.tf new file mode 100644 index 0000000..90ca057 --- /dev/null +++ b/variables-deprecated.tf @@ -0,0 +1,8 @@ +variable "additional_security_groups" { + type = list(string) + default = [] + description = <<-EOT + DEPRECATED: Use `associated_security_group_ids` instead. + List of security groups to attach to the client vpn network associations + EOT +} diff --git a/variables.tf b/variables.tf index 718ec06..ec6d82c 100644 --- a/variables.tf +++ b/variables.tf @@ -73,12 +73,6 @@ variable "additional_routes" { })) } -variable "additional_security_groups" { - default = [] - description = "List of security groups to attach to the client vpn network associations" - type = list(string) -} - variable "associated_subnets" { type = list(string) description = "List of subnets to associate with the VPN endpoint"