Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added metadata_options for aws_launch_config #14637

Merged
merged 6 commits into from
Dec 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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": {
jaysiyani marked this conversation as resolved.
Show resolved Hide resolved
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