Skip to content

Commit

Permalink
resource/aws_launch_configuration: Add metadata_options configuration…
Browse files Browse the repository at this point in the history
… block (#14637)

Output from acceptance testing:

```
--- PASS: TestAccAWSLaunchConfiguration_basic (73.44s)
--- PASS: TestAccAWSLaunchConfiguration_ebs_noDevice (52.92s)
--- PASS: TestAccAWSLaunchConfiguration_encryptedRootBlockDevice (52.90s)
--- PASS: TestAccAWSLaunchConfiguration_metadataOptions (55.79s)
--- PASS: TestAccAWSLaunchConfiguration_RootBlockDevice_AmiDisappears (373.76s)
--- PASS: TestAccAWSLaunchConfiguration_RootBlockDevice_VolumeSize (76.39s)
--- PASS: TestAccAWSLaunchConfiguration_updateEbsBlockDevices (74.31s)
--- PASS: TestAccAWSLaunchConfiguration_userData (75.41s)
--- PASS: TestAccAWSLaunchConfiguration_withBlockDevices (55.41s)
--- PASS: TestAccAWSLaunchConfiguration_withEncryption (55.17s)
--- PASS: TestAccAWSLaunchConfiguration_withIAMProfile (60.63s)
--- PASS: TestAccAWSLaunchConfiguration_withInstanceStoreAMI (57.10s)
--- PASS: TestAccAWSLaunchConfiguration_withSpotPrice (55.55s)

--- PASS: TestAccAWSLaunchConfigurationDataSource_basic (53.40s)
--- PASS: TestAccAWSLaunchConfigurationDataSource_ebsNoDevice (52.04s)
--- PASS: TestAccAWSLaunchConfigurationDataSource_securityGroups (49.80s)
--- PASS: TestAccLaunchConfigurationDataSource_metadataOptions (54.83s)
```
  • Loading branch information
jaysiyani authored Dec 15, 2020
1 parent 3d6f355 commit 57641cd
Show file tree
Hide file tree
Showing 6 changed files with 204 additions and 0 deletions.
25 changes: 25 additions & 0 deletions aws/data_source_aws_launch_configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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)
Expand Down
44 changes: 44 additions & 0 deletions aws/data_source_aws_launch_configuration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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: testAccCheckAWSLaunchConfigurationDestroy,
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" {
Expand Down Expand Up @@ -139,6 +162,27 @@ data "aws_launch_configuration" "foo" {
`, rInt, rInt)
}

func testAccLaunchConfigurationDataSourceConfig_metadataOptions(rName string) string {
return composeConfig(
testAccLatestAmazonLinuxHvmEbsAmiConfig(),
fmt.Sprintf(`
resource "aws_launch_configuration" "test" {
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
}
}
data "aws_launch_configuration" "test" {
name = aws_launch_configuration.test.name
}
`, rName))
}

func testAccLaunchConfigurationDataSourceConfigEbsNoDevice(rName string) string {
return composeConfig(
testAccLatestAmazonLinuxHvmEbsAmiConfig(),
Expand Down
81 changes: 81 additions & 0 deletions aws/resource_aws_launch_configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,39 @@ func resourceAwsLaunchConfiguration() *schema.Resource {
},
},

"metadata_options": {
Type: schema.TypeList,
Optional: true,
Computed: true,
ForceNew: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"http_endpoint": {
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),
},
},
},
},

"root_block_device": {
Type: schema.TypeList,
Optional: true,
Expand Down Expand Up @@ -349,6 +382,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(),
Expand Down Expand Up @@ -564,6 +601,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
}
Expand Down Expand Up @@ -631,6 +672,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{})
Expand Down
46 changes: 46 additions & 0 deletions aws/resource_aws_launch_configuration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -685,6 +714,23 @@ resource "aws_launch_configuration" "test" {
`, rInt))
}

func testAccAWSLaunchConfigurationConfigMetadataOptions(rName string) string {
return composeConfig(
testAccLatestAmazonLinuxHvmEbsAmiConfig(),
fmt.Sprintf(`
resource "aws_launch_configuration" "test" {
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))
}

func testAccAWSLaunchConfigurationConfig() string {
return composeConfig(testAccLatestAmazonLinuxHvmEbsAmiConfig(), fmt.Sprintf(`
resource "aws_launch_configuration" "test" {
Expand Down
4 changes: 4 additions & 0 deletions website/docs/d/launch_configuration.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
4 changes: 4 additions & 0 deletions website/docs/r/launch_configuration.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -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`)
Expand Down

0 comments on commit 57641cd

Please sign in to comment.