From 0d0d690eb37c54a8cc00e8bf8560da39d73e2bb0 Mon Sep 17 00:00:00 2001 From: jaysiyani Date: Thu, 13 Aug 2020 18:16:07 +0100 Subject: [PATCH 1/6] added metadata_options for aws_launch_config --- aws/resource_aws_launch_configuration.go | 77 +++++++++++++++++++ aws/resource_aws_launch_configuration_test.go | 43 +++++++++++ 2 files changed, 120 insertions(+) diff --git a/aws/resource_aws_launch_configuration.go b/aws/resource_aws_launch_configuration.go index 3cd99e88a93..241b215f011 100644 --- a/aws/resource_aws_launch_configuration.go +++ b/aws/resource_aws_launch_configuration.go @@ -247,6 +247,35 @@ func resourceAwsLaunchConfiguration() *schema.Resource { }, }, + "metadata_options": { + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "http_endpoint": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{autoscaling.InstanceMetadataEndpointStateEnabled, autoscaling.InstanceMetadataEndpointStateDisabled}, false), + }, + "http_tokens": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{autoscaling.InstanceMetadataHttpTokensStateOptional, autoscaling.InstanceMetadataHttpTokensStateRequired}, false), + }, + "http_put_response_hop_limit": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + ValidateFunc: validation.IntBetween(1, 64), + }, + }, + }, + }, + "root_block_device": { Type: schema.TypeList, Optional: true, @@ -349,6 +378,10 @@ func resourceAwsLaunchConfigurationCreate(d *schema.ResourceData, meta interface createLaunchConfigurationOpts.ClassicLinkVPCId = aws.String(v.(string)) } + if v, ok := d.GetOk("metadata_options"); ok { + createLaunchConfigurationOpts.MetadataOptions = expandLaunchConfigInstanceMetadataOptions(v.([]interface{})) + } + if v, ok := d.GetOk("vpc_classic_link_security_groups"); ok { createLaunchConfigurationOpts.ClassicLinkVPCSecurityGroups = expandStringList( v.(*schema.Set).List(), @@ -564,6 +597,10 @@ func resourceAwsLaunchConfigurationRead(d *schema.ResourceData, meta interface{} return fmt.Errorf("error setting vpc_classic_link_security_groups: %s", err) } + if err := d.Set("metadata_options", flattenLaunchConfigInstanceMetadataOptions(lc.MetadataOptions)); err != nil { + return fmt.Errorf("error setting metadata_options: %s", err) + } + if err := readLCBlockDevices(d, lc, ec2conn); err != nil { return err } @@ -631,6 +668,46 @@ func readLCBlockDevices(d *schema.ResourceData, lc *autoscaling.LaunchConfigurat return nil } +func expandLaunchConfigInstanceMetadataOptions(l []interface{}) *autoscaling.InstanceMetadataOptions { + if len(l) == 0 || l[0] == nil { + return nil + } + + m := l[0].(map[string]interface{}) + + opts := &autoscaling.InstanceMetadataOptions{ + HttpEndpoint: aws.String(m["http_endpoint"].(string)), + } + + if m["http_endpoint"].(string) == autoscaling.InstanceMetadataEndpointStateEnabled { + // These parameters are not allowed unless HttpEndpoint is enabled + + if v, ok := m["http_tokens"].(string); ok && v != "" { + opts.HttpTokens = aws.String(v) + } + + if v, ok := m["http_put_response_hop_limit"].(int); ok && v != 0 { + opts.HttpPutResponseHopLimit = aws.Int64(int64(v)) + } + } + + return opts +} + +func flattenLaunchConfigInstanceMetadataOptions(opts *autoscaling.InstanceMetadataOptions) []interface{} { + if opts == nil { + return nil + } + + m := map[string]interface{}{ + "http_endpoint": aws.StringValue(opts.HttpEndpoint), + "http_put_response_hop_limit": aws.Int64Value(opts.HttpPutResponseHopLimit), + "http_tokens": aws.StringValue(opts.HttpTokens), + } + + return []interface{}{m} +} + func readBlockDevicesFromLaunchConfiguration(d *schema.ResourceData, lc *autoscaling.LaunchConfiguration, ec2conn *ec2.EC2) ( map[string]interface{}, error) { blockDevices := make(map[string]interface{}) diff --git a/aws/resource_aws_launch_configuration_test.go b/aws/resource_aws_launch_configuration_test.go index d043cfd1f78..af15557ab5a 100644 --- a/aws/resource_aws_launch_configuration_test.go +++ b/aws/resource_aws_launch_configuration_test.go @@ -389,6 +389,35 @@ func TestAccAWSLaunchConfiguration_updateEbsBlockDevices(t *testing.T) { }) } +func TestAccAWSLaunchConfiguration_metadataOptions(t *testing.T) { + var conf autoscaling.LaunchConfiguration + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_launch_configuration.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSLaunchConfigurationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSLaunchConfigurationConfigMetadataOptions(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSLaunchConfigurationExists(resourceName, &conf), + resource.TestCheckResourceAttr(resourceName, "metadata_options.#", "1"), + resource.TestCheckResourceAttr(resourceName, "metadata_options.0.http_endpoint", "enabled"), + resource.TestCheckResourceAttr(resourceName, "metadata_options.0.http_tokens", "required"), + resource.TestCheckResourceAttr(resourceName, "metadata_options.0.http_put_response_hop_limit", "2"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccAWSLaunchConfiguration_ebs_noDevice(t *testing.T) { var conf autoscaling.LaunchConfiguration rInt := acctest.RandInt() @@ -685,6 +714,20 @@ resource "aws_launch_configuration" "test" { `, rInt)) } +func testAccAWSLaunchConfigurationConfigMetadataOptions(rName string) string { + return fmt.Sprintf(` +resource "aws_launch_configuration" "test" { + name = %[1]q + + metadata_options { + http_endpoint = "enabled" + http_tokens = "required" + http_put_response_hop_limit = 2 + } +} +`, rName) +} + func testAccAWSLaunchConfigurationConfig() string { return composeConfig(testAccLatestAmazonLinuxHvmEbsAmiConfig(), fmt.Sprintf(` resource "aws_launch_configuration" "test" { From 72859fa20866d74916d3bbbe4dbcb646646c125c Mon Sep 17 00:00:00 2001 From: jaysiyani Date: Fri, 14 Aug 2020 10:52:40 +0100 Subject: [PATCH 2/6] added metadata_options to data_source_aws_launch_configuration --- aws/data_source_aws_launch_configuration.go | 25 +++++++++++ ...ta_source_aws_launch_configuration_test.go | 41 +++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/aws/data_source_aws_launch_configuration.go b/aws/data_source_aws_launch_configuration.go index 932cba6db92..b6b0c290085 100644 --- a/aws/data_source_aws_launch_configuration.go +++ b/aws/data_source_aws_launch_configuration.go @@ -156,6 +156,27 @@ func dataSourceAwsLaunchConfiguration() *schema.Resource { }, }, + "metadata_options": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "http_endpoint": { + Type: schema.TypeString, + Computed: true, + }, + "http_tokens": { + Type: schema.TypeString, + Computed: true, + }, + "http_put_response_hop_limit": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "root_block_device": { Type: schema.TypeList, Computed: true, @@ -245,6 +266,10 @@ func dataSourceAwsLaunchConfigurationRead(d *schema.ResourceData, meta interface return fmt.Errorf("error setting security_groups: %s", err) } + if err := d.Set("metadata_options", flattenLaunchConfigInstanceMetadataOptions(lc.MetadataOptions)); err != nil { + return fmt.Errorf("error setting metadata_options: %s", err) + } + classicSGs := make([]string, 0, len(lc.ClassicLinkVPCSecurityGroups)) for _, sg := range lc.ClassicLinkVPCSecurityGroups { classicSGs = append(classicSGs, *sg) diff --git a/aws/data_source_aws_launch_configuration_test.go b/aws/data_source_aws_launch_configuration_test.go index 05fa7b1415a..6b19ce4aa87 100644 --- a/aws/data_source_aws_launch_configuration_test.go +++ b/aws/data_source_aws_launch_configuration_test.go @@ -77,6 +77,29 @@ func TestAccAWSLaunchConfigurationDataSource_ebsNoDevice(t *testing.T) { }) } +func testAccLaunchConfigurationDataSource_metadataOptions(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + dataSourceName := "data.aws_launch_configuration.test" + resourceName := "aws_launch_configuration.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSLaunchTemplateDestroy, + Steps: []resource.TestStep{ + { + Config: testAccLaunchConfigurationDataSourceConfig_metadataOptions(rName), + 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_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"), + ), + }, + }, + }) +} + func testAccLaunchConfigurationDataSourceConfig_basic(rName string) string { return composeConfig(testAccLatestAmazonLinuxHvmEbsAmiConfig(), fmt.Sprintf(` resource "aws_launch_configuration" "test" { @@ -139,6 +162,24 @@ data "aws_launch_configuration" "foo" { `, rInt, rInt) } +func testAccLaunchConfigurationDataSourceConfig_metadataOptions(rName string) string { + return fmt.Sprintf(` +resource "aws_launch_configuration" "test" { + name = %[1]q + + metadata_options { + http_endpoint = "enabled" + http_tokens = "required" + http_put_response_hop_limit = 2 + } +} + +data "aws_launch_configuration" "test" { + name = aws_launch_configuration.test.name +} +`, rName) +} + func testAccLaunchConfigurationDataSourceConfigEbsNoDevice(rName string) string { return composeConfig( testAccLatestAmazonLinuxHvmEbsAmiConfig(), From bdc93ba2e81a4a004201f494c81e70024c033053 Mon Sep 17 00:00:00 2001 From: jaysiyani Date: Fri, 14 Aug 2020 11:19:18 +0100 Subject: [PATCH 3/6] fix golangci-lint error --- aws/data_source_aws_launch_configuration_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aws/data_source_aws_launch_configuration_test.go b/aws/data_source_aws_launch_configuration_test.go index 6b19ce4aa87..ba3b9348d0d 100644 --- a/aws/data_source_aws_launch_configuration_test.go +++ b/aws/data_source_aws_launch_configuration_test.go @@ -77,7 +77,7 @@ func TestAccAWSLaunchConfigurationDataSource_ebsNoDevice(t *testing.T) { }) } -func testAccLaunchConfigurationDataSource_metadataOptions(t *testing.T) { +func TestAccLaunchConfigurationDataSource_metadataOptions(t *testing.T) { rName := acctest.RandomWithPrefix("tf-acc-test") dataSourceName := "data.aws_launch_configuration.test" resourceName := "aws_launch_configuration.test" @@ -85,7 +85,7 @@ func testAccLaunchConfigurationDataSource_metadataOptions(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, - CheckDestroy: testAccCheckAWSLaunchTemplateDestroy, + CheckDestroy: testAccCheckAWSLaunchConfigurationDestroy, Steps: []resource.TestStep{ { Config: testAccLaunchConfigurationDataSourceConfig_metadataOptions(rName), From ef3ff7e7de6cd07055135cbf232951dcd5335e0c Mon Sep 17 00:00:00 2001 From: jaysiyani Date: Tue, 18 Aug 2020 07:53:37 +0100 Subject: [PATCH 4/6] forces new resource for launch config metadata option --- aws/resource_aws_launch_configuration.go | 4 ++++ aws/resource_aws_launch_configuration_test.go | 2 ++ 2 files changed, 6 insertions(+) diff --git a/aws/resource_aws_launch_configuration.go b/aws/resource_aws_launch_configuration.go index 241b215f011..f9e4f2789c0 100644 --- a/aws/resource_aws_launch_configuration.go +++ b/aws/resource_aws_launch_configuration.go @@ -251,6 +251,7 @@ func resourceAwsLaunchConfiguration() *schema.Resource { Type: schema.TypeList, Optional: true, Computed: true, + ForceNew: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -258,18 +259,21 @@ func resourceAwsLaunchConfiguration() *schema.Resource { Type: schema.TypeString, Optional: true, Computed: true, + ForceNew: true, ValidateFunc: validation.StringInSlice([]string{autoscaling.InstanceMetadataEndpointStateEnabled, autoscaling.InstanceMetadataEndpointStateDisabled}, false), }, "http_tokens": { Type: schema.TypeString, Optional: true, Computed: true, + ForceNew: true, ValidateFunc: validation.StringInSlice([]string{autoscaling.InstanceMetadataHttpTokensStateOptional, autoscaling.InstanceMetadataHttpTokensStateRequired}, false), }, "http_put_response_hop_limit": { Type: schema.TypeInt, Optional: true, Computed: true, + ForceNew: true, ValidateFunc: validation.IntBetween(1, 64), }, }, diff --git a/aws/resource_aws_launch_configuration_test.go b/aws/resource_aws_launch_configuration_test.go index af15557ab5a..c2876868656 100644 --- a/aws/resource_aws_launch_configuration_test.go +++ b/aws/resource_aws_launch_configuration_test.go @@ -718,6 +718,8 @@ func testAccAWSLaunchConfigurationConfigMetadataOptions(rName string) string { return fmt.Sprintf(` resource "aws_launch_configuration" "test" { name = %[1]q + image_id = "${data.aws_ami.ubuntu.id}" + instance_type = "t3.nano" metadata_options { http_endpoint = "enabled" From bccbb1f01a5dcdaf83aea59f407a9c5807c30277 Mon Sep 17 00:00:00 2001 From: jaysiyani Date: Thu, 3 Sep 2020 14:37:32 +0100 Subject: [PATCH 5/6] added aws_launch_configuration to website md --- website/docs/d/launch_configuration.html.markdown | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/website/docs/d/launch_configuration.html.markdown b/website/docs/d/launch_configuration.html.markdown index 7b1169294f5..68702126a22 100644 --- a/website/docs/d/launch_configuration.html.markdown +++ b/website/docs/d/launch_configuration.html.markdown @@ -35,6 +35,10 @@ In addition to all arguments above, the following attributes are exported: * `instance_type` - The Instance Type of the instance to launch. * `iam_instance_profile` - The IAM Instance Profile to associate with launched instances. * `key_name` - The Key Name that should be used for the instance. +* `metadata_options` - The metadata options for the instance. + * `http_endpoint` - The state of the metadata service: `enabled`, `disabled`. + * `http_tokens` - If session tokens are required: `optional`, `required`. + * `http_put_response_hop_limit` - The desired HTTP PUT response hop limit for instance metadata requests. * `security_groups` - A list of associated Security Group IDS. * `associate_public_ip_address` - Whether a Public IP address is associated with the instance. * `vpc_classic_link_id` - The ID of a ClassicLink-enabled VPC. From 1991d269eb3a9b08c6e9f478c4e8fc55e65fb1e9 Mon Sep 17 00:00:00 2001 From: jaysiyani Date: Mon, 14 Dec 2020 10:45:45 +0000 Subject: [PATCH 6/6] update test configuration and add metadata_options to resource launch config md --- aws/data_source_aws_launch_configuration_test.go | 11 +++++++---- aws/resource_aws_launch_configuration_test.go | 11 ++++++----- website/docs/r/launch_configuration.html.markdown | 4 ++++ 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/aws/data_source_aws_launch_configuration_test.go b/aws/data_source_aws_launch_configuration_test.go index ba3b9348d0d..5c7d826acff 100644 --- a/aws/data_source_aws_launch_configuration_test.go +++ b/aws/data_source_aws_launch_configuration_test.go @@ -163,10 +163,13 @@ data "aws_launch_configuration" "foo" { } func testAccLaunchConfigurationDataSourceConfig_metadataOptions(rName string) string { - return fmt.Sprintf(` + return composeConfig( + testAccLatestAmazonLinuxHvmEbsAmiConfig(), + fmt.Sprintf(` resource "aws_launch_configuration" "test" { - name = %[1]q - + image_id = data.aws_ami.amzn-ami-minimal-hvm-ebs.id + instance_type = "t3.nano" + name = %[1]q metadata_options { http_endpoint = "enabled" http_tokens = "required" @@ -177,7 +180,7 @@ resource "aws_launch_configuration" "test" { data "aws_launch_configuration" "test" { name = aws_launch_configuration.test.name } -`, rName) +`, rName)) } func testAccLaunchConfigurationDataSourceConfigEbsNoDevice(rName string) string { diff --git a/aws/resource_aws_launch_configuration_test.go b/aws/resource_aws_launch_configuration_test.go index c2876868656..28a699e3791 100644 --- a/aws/resource_aws_launch_configuration_test.go +++ b/aws/resource_aws_launch_configuration_test.go @@ -715,19 +715,20 @@ resource "aws_launch_configuration" "test" { } func testAccAWSLaunchConfigurationConfigMetadataOptions(rName string) string { - return fmt.Sprintf(` + return composeConfig( + testAccLatestAmazonLinuxHvmEbsAmiConfig(), + fmt.Sprintf(` resource "aws_launch_configuration" "test" { - name = %[1]q - image_id = "${data.aws_ami.ubuntu.id}" + image_id = data.aws_ami.amzn-ami-minimal-hvm-ebs.id instance_type = "t3.nano" - + name = %[1]q metadata_options { http_endpoint = "enabled" http_tokens = "required" http_put_response_hop_limit = 2 } } -`, rName) +`, rName)) } func testAccAWSLaunchConfigurationConfig() string { diff --git a/website/docs/r/launch_configuration.html.markdown b/website/docs/r/launch_configuration.html.markdown index d96ee73ea45..ddd47210a35 100644 --- a/website/docs/r/launch_configuration.html.markdown +++ b/website/docs/r/launch_configuration.html.markdown @@ -144,6 +144,10 @@ The following arguments are supported: * `iam_instance_profile` - (Optional) The name attribute of the IAM instance profile to associate with launched instances. * `key_name` - (Optional) The key name that should be used for the instance. +* `metadata_options` - The metadata options for the instance. + * `http_endpoint` - The state of the metadata service: `enabled`, `disabled`. + * `http_tokens` - If session tokens are required: `optional`, `required`. + * `http_put_response_hop_limit` - The desired HTTP PUT response hop limit for instance metadata requests. * `security_groups` - (Optional) A list of associated security group IDS. * `associate_public_ip_address` - (Optional) Associate a public ip address with an instance in a VPC. * `vpc_classic_link_id` - (Optional) The ID of a ClassicLink-enabled VPC. Only applies to EC2-Classic instances. (eg. `vpc-2730681a`)