diff --git a/README.md b/README.md index 414a44e..485a805 100644 --- a/README.md +++ b/README.md @@ -224,13 +224,14 @@ Available targets: | [aws_autoscaling_policy.scale_up](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_policy) | resource | | [aws_cloudwatch_metric_alarm.all_alarms](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_metric_alarm) | resource | | [aws_launch_template.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_template) | resource | +| [aws_subnet.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnet) | data source | ## Inputs | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | [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 | -| [associate\_public\_ip\_address](#input\_associate\_public\_ip\_address) | Associate a public IP address with an instance in a VPC | `bool` | `false` | no | +| [associate\_public\_ip\_address](#input\_associate\_public\_ip\_address) | Associate a public IP address with an instance in a VPC. If `network_interface_id` is specified, this can only be `false` (see here for more info: https://stackoverflow.com/a/76808361). | `bool` | `false` | no | | [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 | | [autoscaling\_policies\_enabled](#input\_autoscaling\_policies\_enabled) | Whether to create `aws_autoscaling_policy` and `aws_cloudwatch_metric_alarm` resources to control Auto Scaling | `bool` | `true` | no | | [block\_device\_mappings](#input\_block\_device\_mappings) | Specify volumes to attach to the instance besides the volumes specified by the AMI |
list(object({
device_name = optional(string)
no_device = optional(bool)
virtual_name = optional(string)
ebs = object({
delete_on_termination = optional(bool)
encrypted = optional(bool)
iops = optional(number)
throughput = optional(number)
kms_key_id = optional(string)
snapshot_id = optional(string)
volume_size = optional(number)
volume_type = optional(string)
})
}))
| `[]` | no | @@ -289,6 +290,7 @@ Available targets: | [mixed\_instances\_policy](#input\_mixed\_instances\_policy) | policy to used mixed group of on demand/spot of differing types. Launch template is automatically generated. https://www.terraform.io/docs/providers/aws/r/autoscaling_group.html#mixed_instances_policy-1 |
object({
instances_distribution = object({
on_demand_allocation_strategy = string
on_demand_base_capacity = number
on_demand_percentage_above_base_capacity = number
spot_allocation_strategy = string
spot_instance_pools = number
spot_max_price = string
})
override = list(object({
instance_type = string
weighted_capacity = number
}))
})
| `null` | no | | [name](#input\_name) | ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.
This is the only ID element not also included as a `tag`.
The "name" tag is set to the full `id` string. There is no tag with the value of the `name` input. | `string` | `null` | no | | [namespace](#input\_namespace) | ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique | `string` | `null` | no | +| [network\_interface\_id](#input\_network\_interface\_id) | The ID of the network interface to attach. If specified, all the other network\_interface block arguments are ignored. | `string` | `null` | no | | [placement](#input\_placement) | The placement specifications of the instances |
object({
affinity = string
availability_zone = string
group_name = string
host_id = string
tenancy = string
})
| `null` | no | | [placement\_group](#input\_placement\_group) | The name of the placement group into which you'll launch your instances, if any | `string` | `""` | no | | [protect\_from\_scale\_in](#input\_protect\_from\_scale\_in) | Allows setting instance protection. The autoscaling group will not select instances with this setting for terminination during scale in events | `bool` | `false` | no | diff --git a/docs/terraform.md b/docs/terraform.md index 6f06699..89a819a 100644 --- a/docs/terraform.md +++ b/docs/terraform.md @@ -27,13 +27,14 @@ | [aws_autoscaling_policy.scale_up](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_policy) | resource | | [aws_cloudwatch_metric_alarm.all_alarms](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_metric_alarm) | resource | | [aws_launch_template.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_template) | resource | +| [aws_subnet.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnet) | data source | ## Inputs | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | [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 | -| [associate\_public\_ip\_address](#input\_associate\_public\_ip\_address) | Associate a public IP address with an instance in a VPC | `bool` | `false` | no | +| [associate\_public\_ip\_address](#input\_associate\_public\_ip\_address) | Associate a public IP address with an instance in a VPC. If `network_interface_id` is specified, this can only be `false` (see here for more info: https://stackoverflow.com/a/76808361). | `bool` | `false` | no | | [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 | | [autoscaling\_policies\_enabled](#input\_autoscaling\_policies\_enabled) | Whether to create `aws_autoscaling_policy` and `aws_cloudwatch_metric_alarm` resources to control Auto Scaling | `bool` | `true` | no | | [block\_device\_mappings](#input\_block\_device\_mappings) | Specify volumes to attach to the instance besides the volumes specified by the AMI |
list(object({
device_name = optional(string)
no_device = optional(bool)
virtual_name = optional(string)
ebs = object({
delete_on_termination = optional(bool)
encrypted = optional(bool)
iops = optional(number)
throughput = optional(number)
kms_key_id = optional(string)
snapshot_id = optional(string)
volume_size = optional(number)
volume_type = optional(string)
})
}))
| `[]` | no | @@ -92,6 +93,7 @@ | [mixed\_instances\_policy](#input\_mixed\_instances\_policy) | policy to used mixed group of on demand/spot of differing types. Launch template is automatically generated. https://www.terraform.io/docs/providers/aws/r/autoscaling_group.html#mixed_instances_policy-1 |
object({
instances_distribution = object({
on_demand_allocation_strategy = string
on_demand_base_capacity = number
on_demand_percentage_above_base_capacity = number
spot_allocation_strategy = string
spot_instance_pools = number
spot_max_price = string
})
override = list(object({
instance_type = string
weighted_capacity = number
}))
})
| `null` | no | | [name](#input\_name) | ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.
This is the only ID element not also included as a `tag`.
The "name" tag is set to the full `id` string. There is no tag with the value of the `name` input. | `string` | `null` | no | | [namespace](#input\_namespace) | ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique | `string` | `null` | no | +| [network\_interface\_id](#input\_network\_interface\_id) | The ID of the network interface to attach. If specified, all the other network\_interface block arguments are ignored. | `string` | `null` | no | | [placement](#input\_placement) | The placement specifications of the instances |
object({
affinity = string
availability_zone = string
group_name = string
host_id = string
tenancy = string
})
| `null` | no | | [placement\_group](#input\_placement\_group) | The name of the placement group into which you'll launch your instances, if any | `string` | `""` | no | | [protect\_from\_scale\_in](#input\_protect\_from\_scale\_in) | Allows setting instance protection. The autoscaling group will not select instances with this setting for terminination during scale in events | `bool` | `false` | no | diff --git a/main.tf b/main.tf index 957e979..9538e06 100644 --- a/main.tf +++ b/main.tf @@ -1,3 +1,8 @@ +data "aws_subnet" "this" { + for_each = length(var.subnet_ids) > 0 ? { for idx, subnet in var.subnet_ids : idx => subnet } : {} + id = each.value +} + resource "aws_launch_template" "default" { count = module.this.enabled ? 1 : 0 @@ -95,11 +100,12 @@ resource "aws_launch_template" "default" { # https://github.com/terraform-providers/terraform-provider-aws/issues/4570 network_interfaces { - description = module.this.id + description = var.network_interface_id == null ? module.this.id : null device_index = 0 - associate_public_ip_address = var.associate_public_ip_address - delete_on_termination = true - security_groups = var.security_group_ids + associate_public_ip_address = var.network_interface_id == null ? var.associate_public_ip_address : null + delete_on_termination = var.network_interface_id == null ? true : false + security_groups = var.network_interface_id == null ? var.security_group_ids : null + network_interface_id = var.network_interface_id } metadata_options { @@ -140,6 +146,7 @@ locals { launch_template = local.launch_template_block override = var.mixed_instances_policy.override }) + availability_zones = [for subnet in data.aws_subnet.this : subnet.availability_zone] tags = { for key, value in module.this.tags : key => value if value != "" && value != null @@ -150,7 +157,8 @@ resource "aws_autoscaling_group" "default" { count = module.this.enabled ? 1 : 0 name_prefix = format("%s%s", module.this.id, module.this.delimiter) - vpc_zone_identifier = var.subnet_ids + vpc_zone_identifier = var.network_interface_id == null ? var.subnet_ids : null + availability_zones = var.network_interface_id != null ? local.availability_zones : null max_size = var.max_size min_size = var.min_size load_balancers = var.load_balancers diff --git a/variables.tf b/variables.tf index b4752ed..91c6b22 100644 --- a/variables.tf +++ b/variables.tf @@ -41,10 +41,16 @@ variable "launch_template_version" { variable "associate_public_ip_address" { type = bool - description = "Associate a public IP address with an instance in a VPC" + description = "Associate a public IP address with an instance in a VPC. If `network_interface_id` is specified, this can only be `false` (see here for more info: https://stackoverflow.com/a/76808361)." default = false } +variable "network_interface_id" { + type = string + description = "The ID of the network interface to attach. If specified, all the other network_interface block arguments are ignored." + default = null +} + variable "user_data_base64" { type = string description = "The Base64-encoded user data to provide when launching the instances" @@ -197,8 +203,8 @@ variable "min_size" { } variable "subnet_ids" { - description = "A list of subnet IDs to launch resources in" type = list(string) + description = "A list of subnet IDs to launch resources in" } variable "default_cooldown" {