Skip to content

Commit

Permalink
Add optional network_interface_id variable (#124)
Browse files Browse the repository at this point in the history
* Add optional network_interface_id variable

* Update var.associate_public_ip_address description

* Remove var.availability_zones, use data.aws_subnet

* Update README

* Remove var.subnet_ids default value

* Coalesce locals blocks in main.tf

* Update README

* Allow for var.subnet_ids to be an empty list in data.aws_subnet.this

* Change tomap() to map comprehension

* Fix idx ref in map expression

---------

Co-authored-by: Max Lobur <max_lobur@outlook.com>
  • Loading branch information
gbarna-bd and max-lobur committed Nov 2, 2023
1 parent ba1e6ce commit aa3840e
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 9 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
|------|-------------|------|---------|:--------:|
| <a name="input_additional_tag_map"></a> [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`.<br>This is for some rare cases where resources want additional configuration of tags<br>and therefore take a list of maps with tag key, value, and additional configuration. | `map(string)` | `{}` | no |
| <a name="input_associate_public_ip_address"></a> [associate\_public\_ip\_address](#input\_associate\_public\_ip\_address) | Associate a public IP address with an instance in a VPC | `bool` | `false` | no |
| <a name="input_associate_public_ip_address"></a> [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 |
| <a name="input_attributes"></a> [attributes](#input\_attributes) | ID element. Additional attributes (e.g. `workers` or `cluster`) to add to `id`,<br>in the order they appear in the list. New attributes are appended to the<br>end of the list. The elements of the list are joined by the `delimiter`<br>and treated as a single ID element. | `list(string)` | `[]` | no |
| <a name="input_autoscaling_policies_enabled"></a> [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 |
| <a name="input_block_device_mappings"></a> [block\_device\_mappings](#input\_block\_device\_mappings) | Specify volumes to attach to the instance besides the volumes specified by the AMI | <pre>list(object({<br> device_name = optional(string)<br> no_device = optional(bool)<br> virtual_name = optional(string)<br> ebs = object({<br> delete_on_termination = optional(bool)<br> encrypted = optional(bool)<br> iops = optional(number)<br> throughput = optional(number)<br> kms_key_id = optional(string)<br> snapshot_id = optional(string)<br> volume_size = optional(number)<br> volume_type = optional(string)<br> })<br> }))</pre> | `[]` | no |
Expand Down Expand Up @@ -289,6 +290,7 @@ Available targets:
| <a name="input_mixed_instances_policy"></a> [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 | <pre>object({<br> instances_distribution = object({<br> on_demand_allocation_strategy = string<br> on_demand_base_capacity = number<br> on_demand_percentage_above_base_capacity = number<br> spot_allocation_strategy = string<br> spot_instance_pools = number<br> spot_max_price = string<br> })<br> override = list(object({<br> instance_type = string<br> weighted_capacity = number<br> }))<br> })</pre> | `null` | no |
| <a name="input_name"></a> [name](#input\_name) | ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.<br>This is the only ID element not also included as a `tag`.<br>The "name" tag is set to the full `id` string. There is no tag with the value of the `name` input. | `string` | `null` | no |
| <a name="input_namespace"></a> [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 |
| <a name="input_network_interface_id"></a> [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 |
| <a name="input_placement"></a> [placement](#input\_placement) | The placement specifications of the instances | <pre>object({<br> affinity = string<br> availability_zone = string<br> group_name = string<br> host_id = string<br> tenancy = string<br> })</pre> | `null` | no |
| <a name="input_placement_group"></a> [placement\_group](#input\_placement\_group) | The name of the placement group into which you'll launch your instances, if any | `string` | `""` | no |
| <a name="input_protect_from_scale_in"></a> [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 |
Expand Down
4 changes: 3 additions & 1 deletion docs/terraform.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
|------|-------------|------|---------|:--------:|
| <a name="input_additional_tag_map"></a> [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`.<br>This is for some rare cases where resources want additional configuration of tags<br>and therefore take a list of maps with tag key, value, and additional configuration. | `map(string)` | `{}` | no |
| <a name="input_associate_public_ip_address"></a> [associate\_public\_ip\_address](#input\_associate\_public\_ip\_address) | Associate a public IP address with an instance in a VPC | `bool` | `false` | no |
| <a name="input_associate_public_ip_address"></a> [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 |
| <a name="input_attributes"></a> [attributes](#input\_attributes) | ID element. Additional attributes (e.g. `workers` or `cluster`) to add to `id`,<br>in the order they appear in the list. New attributes are appended to the<br>end of the list. The elements of the list are joined by the `delimiter`<br>and treated as a single ID element. | `list(string)` | `[]` | no |
| <a name="input_autoscaling_policies_enabled"></a> [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 |
| <a name="input_block_device_mappings"></a> [block\_device\_mappings](#input\_block\_device\_mappings) | Specify volumes to attach to the instance besides the volumes specified by the AMI | <pre>list(object({<br> device_name = optional(string)<br> no_device = optional(bool)<br> virtual_name = optional(string)<br> ebs = object({<br> delete_on_termination = optional(bool)<br> encrypted = optional(bool)<br> iops = optional(number)<br> throughput = optional(number)<br> kms_key_id = optional(string)<br> snapshot_id = optional(string)<br> volume_size = optional(number)<br> volume_type = optional(string)<br> })<br> }))</pre> | `[]` | no |
Expand Down Expand Up @@ -92,6 +93,7 @@
| <a name="input_mixed_instances_policy"></a> [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 | <pre>object({<br> instances_distribution = object({<br> on_demand_allocation_strategy = string<br> on_demand_base_capacity = number<br> on_demand_percentage_above_base_capacity = number<br> spot_allocation_strategy = string<br> spot_instance_pools = number<br> spot_max_price = string<br> })<br> override = list(object({<br> instance_type = string<br> weighted_capacity = number<br> }))<br> })</pre> | `null` | no |
| <a name="input_name"></a> [name](#input\_name) | ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.<br>This is the only ID element not also included as a `tag`.<br>The "name" tag is set to the full `id` string. There is no tag with the value of the `name` input. | `string` | `null` | no |
| <a name="input_namespace"></a> [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 |
| <a name="input_network_interface_id"></a> [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 |
| <a name="input_placement"></a> [placement](#input\_placement) | The placement specifications of the instances | <pre>object({<br> affinity = string<br> availability_zone = string<br> group_name = string<br> host_id = string<br> tenancy = string<br> })</pre> | `null` | no |
| <a name="input_placement_group"></a> [placement\_group](#input\_placement\_group) | The name of the placement group into which you'll launch your instances, if any | `string` | `""` | no |
| <a name="input_protect_from_scale_in"></a> [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 |
Expand Down
18 changes: 13 additions & 5 deletions main.tf
Original file line number Diff line number Diff line change
@@ -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

Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
10 changes: 8 additions & 2 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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" {
Expand Down

0 comments on commit aa3840e

Please sign in to comment.