diff --git a/.changelog/32759.txt b/.changelog/32759.txt new file mode 100644 index 00000000000..0b361006143 --- /dev/null +++ b/.changelog/32759.txt @@ -0,0 +1,7 @@ +```release-note:enhancement +resource/aws_instance: Add `http_protocol_ipv6` attribute to `metadata_options` configuration block +``` + +```release-note:enhancement +data-source/aws_instance: Add `metadata_options.http_protocol_ipv6` attribute +``` \ No newline at end of file diff --git a/internal/service/ec2/ec2_instance.go b/internal/service/ec2/ec2_instance.go index 172dda9f050..412283ebf43 100644 --- a/internal/service/ec2/ec2_instance.go +++ b/internal/service/ec2/ec2_instance.go @@ -546,6 +546,12 @@ func ResourceInstance() *schema.Resource { Default: ec2.InstanceMetadataEndpointStateEnabled, ValidateFunc: validation.StringInSlice(ec2.InstanceMetadataEndpointState_Values(), false), }, + "http_protocol_ipv6": { + Type: schema.TypeString, + Optional: true, + Default: ec2.InstanceMetadataProtocolStateDisabled, + ValidateFunc: validation.StringInSlice(ec2.InstanceMetadataProtocolState_Values(), false), + }, "http_put_response_hop_limit": { Type: schema.TypeInt, Optional: true, @@ -1813,6 +1819,7 @@ func resourceInstanceUpdate(ctx context.Context, d *schema.ResourceData, meta in if tfMap["http_endpoint"].(string) == ec2.InstanceMetadataEndpointStateEnabled { // These parameters are not allowed unless HttpEndpoint is enabled. + input.HttpProtocolIpv6 = aws.String(tfMap["http_protocol_ipv6"].(string)) input.HttpPutResponseHopLimit = aws.Int64(int64(tfMap["http_put_response_hop_limit"].(int))) input.HttpTokens = aws.String(tfMap["http_tokens"].(string)) input.InstanceMetadataTags = aws.String(tfMap["instance_metadata_tags"].(string)) @@ -3100,6 +3107,9 @@ func expandInstanceMetadataOptions(l []interface{}) *ec2.InstanceMetadataOptions if m["http_endpoint"].(string) == ec2.InstanceMetadataEndpointStateEnabled { // These parameters are not allowed unless HttpEndpoint is enabled + if v, ok := m["http_protocol_ipv6"].(string); ok && v != "" { + opts.HttpProtocolIpv6 = aws.String(v) + } if v, ok := m["http_tokens"].(string); ok && v != "" { opts.HttpTokens = aws.String(v) @@ -3176,6 +3186,7 @@ func flattenInstanceMetadataOptions(opts *ec2.InstanceMetadataOptionsResponse) [ m := map[string]interface{}{ "http_endpoint": aws.StringValue(opts.HttpEndpoint), + "http_protocol_ipv6": aws.StringValue(opts.HttpProtocolIpv6), "http_put_response_hop_limit": aws.Int64Value(opts.HttpPutResponseHopLimit), "http_tokens": aws.StringValue(opts.HttpTokens), "instance_metadata_tags": aws.StringValue(opts.InstanceMetadataTags), diff --git a/internal/service/ec2/ec2_instance_data_source.go b/internal/service/ec2/ec2_instance_data_source.go index 73e54d824aa..b56374c6163 100644 --- a/internal/service/ec2/ec2_instance_data_source.go +++ b/internal/service/ec2/ec2_instance_data_source.go @@ -228,6 +228,10 @@ func DataSourceInstance() *schema.Resource { Type: schema.TypeString, Computed: true, }, + "http_protocol_ipv6": { + Type: schema.TypeString, + Computed: true, + }, "http_put_response_hop_limit": { Type: schema.TypeInt, Computed: true, diff --git a/internal/service/ec2/ec2_instance_data_source_test.go b/internal/service/ec2/ec2_instance_data_source_test.go index 74b89de3e4c..5fc4aec3915 100644 --- a/internal/service/ec2/ec2_instance_data_source_test.go +++ b/internal/service/ec2/ec2_instance_data_source_test.go @@ -634,6 +634,7 @@ func TestAccEC2InstanceDataSource_metadataOptions(t *testing.T) { Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttrPair(datasourceName, "metadata_options.#", resourceName, "metadata_options.#"), resource.TestCheckResourceAttrPair(datasourceName, "metadata_options.0.http_endpoint", resourceName, "metadata_options.0.http_endpoint"), + resource.TestCheckResourceAttrPair(datasourceName, "metadata_options.0.http_protocol_ipv6", resourceName, "metadata_options.0.http_protocol_ipv6"), resource.TestCheckResourceAttrPair(datasourceName, "metadata_options.0.http_tokens", resourceName, "metadata_options.0.http_tokens"), resource.TestCheckResourceAttrPair(datasourceName, "metadata_options.0.http_put_response_hop_limit", resourceName, "metadata_options.0.http_put_response_hop_limit"), resource.TestCheckResourceAttrPair(datasourceName, "metadata_options.0.instance_metadata_tags", resourceName, "metadata_options.0.instance_metadata_tags"), diff --git a/internal/service/ec2/ec2_instance_test.go b/internal/service/ec2/ec2_instance_test.go index 5c9da246688..059182a97cc 100644 --- a/internal/service/ec2/ec2_instance_test.go +++ b/internal/service/ec2/ec2_instance_test.go @@ -5007,6 +5007,7 @@ func TestAccEC2Instance_metadataOptions(t *testing.T) { testAccCheckInstanceExists(ctx, resourceName, &v), resource.TestCheckResourceAttr(resourceName, "metadata_options.#", "1"), resource.TestCheckResourceAttr(resourceName, "metadata_options.0.http_endpoint", "enabled"), + resource.TestCheckResourceAttr(resourceName, "metadata_options.0.http_protocol_ipv6", "disabled"), resource.TestCheckResourceAttr(resourceName, "metadata_options.0.http_tokens", "optional"), resource.TestCheckResourceAttr(resourceName, "metadata_options.0.http_put_response_hop_limit", "1"), resource.TestCheckResourceAttr(resourceName, "metadata_options.0.instance_metadata_tags", "disabled"), @@ -5018,6 +5019,7 @@ func TestAccEC2Instance_metadataOptions(t *testing.T) { testAccCheckInstanceExists(ctx, resourceName, &v), resource.TestCheckResourceAttr(resourceName, "metadata_options.#", "1"), resource.TestCheckResourceAttr(resourceName, "metadata_options.0.http_endpoint", "disabled"), + resource.TestCheckResourceAttr(resourceName, "metadata_options.0.http_protocol_ipv6", "disabled"), resource.TestCheckResourceAttr(resourceName, "metadata_options.0.http_tokens", "optional"), resource.TestCheckResourceAttr(resourceName, "metadata_options.0.http_put_response_hop_limit", "1"), resource.TestCheckResourceAttr(resourceName, "metadata_options.0.instance_metadata_tags", "disabled"), @@ -5029,6 +5031,7 @@ func TestAccEC2Instance_metadataOptions(t *testing.T) { testAccCheckInstanceExists(ctx, resourceName, &v), resource.TestCheckResourceAttr(resourceName, "metadata_options.#", "1"), resource.TestCheckResourceAttr(resourceName, "metadata_options.0.http_endpoint", "enabled"), + resource.TestCheckResourceAttr(resourceName, "metadata_options.0.http_protocol_ipv6", "enabled"), resource.TestCheckResourceAttr(resourceName, "metadata_options.0.http_tokens", "required"), resource.TestCheckResourceAttr(resourceName, "metadata_options.0.http_put_response_hop_limit", "2"), resource.TestCheckResourceAttr(resourceName, "metadata_options.0.instance_metadata_tags", "enabled"), @@ -5040,6 +5043,7 @@ func TestAccEC2Instance_metadataOptions(t *testing.T) { testAccCheckInstanceExists(ctx, resourceName, &v), resource.TestCheckResourceAttr(resourceName, "metadata_options.#", "1"), resource.TestCheckResourceAttr(resourceName, "metadata_options.0.http_endpoint", "enabled"), + resource.TestCheckResourceAttr(resourceName, "metadata_options.0.http_protocol_ipv6", "disabled"), resource.TestCheckResourceAttr(resourceName, "metadata_options.0.http_tokens", "optional"), resource.TestCheckResourceAttr(resourceName, "metadata_options.0.http_put_response_hop_limit", "1"), resource.TestCheckResourceAttr(resourceName, "metadata_options.0.instance_metadata_tags", "disabled"), @@ -8542,6 +8546,7 @@ resource "aws_instance" "test" { metadata_options { http_endpoint = "enabled" + http_protocol_ipv6 = "enabled" http_tokens = "required" http_put_response_hop_limit = 2 instance_metadata_tags = "enabled" @@ -8567,6 +8572,7 @@ resource "aws_instance" "test" { metadata_options { http_endpoint = "enabled" + http_protocol_ipv6 = "disabled" http_tokens = "optional" http_put_response_hop_limit = 1 instance_metadata_tags = "disabled" diff --git a/website/docs/d/instance.html.markdown b/website/docs/d/instance.html.markdown index 668e3a5e58a..38071202494 100644 --- a/website/docs/d/instance.html.markdown +++ b/website/docs/d/instance.html.markdown @@ -92,6 +92,7 @@ interpolation. * `auto_recovery` - Automatic recovery behavior of the instance. * `metadata_options` - Metadata options of the Instance. * `http_endpoint` - State of the metadata service: `enabled`, `disabled`. + * `http_protocol_ipv6` - Whether the IPv6 endpoint for the instance metadata service is `enabled` or `disabled` * `http_tokens` - If session tokens are required: `optional`, `required`. * `http_put_response_hop_limit` - Desired HTTP PUT response hop limit for instance metadata requests. * `instance_metadata_tags` - If access to instance tags is allowed from the metadata service: `enabled`, `disabled`. diff --git a/website/docs/r/instance.html.markdown b/website/docs/r/instance.html.markdown index 13f420074c5..fba0b71cef8 100644 --- a/website/docs/r/instance.html.markdown +++ b/website/docs/r/instance.html.markdown @@ -355,6 +355,7 @@ Metadata options can be applied/modified to the EC2 Instance at any time. The `metadata_options` block supports the following: * `http_endpoint` - (Optional) Whether the metadata service is available. Valid values include `enabled` or `disabled`. Defaults to `enabled`. +* `http_protocol_ipv6` - (Optional) Whether the IPv6 endpoint for the instance metadata service is enabled. Defaults to `disabled`. * `http_put_response_hop_limit` - (Optional) Desired HTTP PUT response hop limit for instance metadata requests. The larger the number, the further instance metadata requests can travel. Valid values are integer from `1` to `64`. Defaults to `1`. * `http_tokens` - (Optional) Whether or not the metadata service requires session tokens, also referred to as _Instance Metadata Service Version 2 (IMDSv2)_. Valid values include `optional` or `required`. Defaults to `optional`. * `instance_metadata_tags` - (Optional) Enables or disables access to instance tags from the instance metadata service. Valid values include `enabled` or `disabled`. Defaults to `disabled`.