From 4dd88866bd8c0b91534fca7b9b7ad91f3452bf38 Mon Sep 17 00:00:00 2001 From: Kash Date: Fri, 2 Mar 2018 17:59:31 -0500 Subject: [PATCH 1/4] add launch configuration data source --- aws/data_source_aws_launch_configuration.go | 221 ++++++++++++++++++ ...ta_source_aws_launch_configuration_test.go | 68 ++++++ aws/provider.go | 1 + 3 files changed, 290 insertions(+) create mode 100644 aws/data_source_aws_launch_configuration.go create mode 100644 aws/data_source_aws_launch_configuration_test.go diff --git a/aws/data_source_aws_launch_configuration.go b/aws/data_source_aws_launch_configuration.go new file mode 100644 index 00000000000..7f257eca24d --- /dev/null +++ b/aws/data_source_aws_launch_configuration.go @@ -0,0 +1,221 @@ +package aws + +import ( + "fmt" + "log" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/autoscaling" + "github.com/hashicorp/terraform/helper/schema" +) + +func dataSourceAwsLaunchConfiguration() *schema.Resource { + return &schema.Resource{ + Read: dataSourceAwsLaunchConfigurationRead, + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + }, + + "image_id": { + Type: schema.TypeString, + Computed: true, + }, + + "instance_type": { + Type: schema.TypeString, + Computed: true, + }, + + "iam_instance_profile": { + Type: schema.TypeString, + Computed: true, + }, + + "key_name": { + Type: schema.TypeString, + Computed: true, + }, + + "user_data": { + Type: schema.TypeString, + Computed: true, + }, + + "security_groups": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + + "vpc_classic_link_id": { + Type: schema.TypeString, + Computed: true, + }, + + "vpc_classic_link_security_groups": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + + "associate_public_ip_address": { + Type: schema.TypeBool, + Computed: true, + }, + + "spot_price": { + Type: schema.TypeString, + Computed: true, + }, + + "ebs_optimized": { + Type: schema.TypeBool, + Computed: true, + }, + + "placement_tenancy": { + Type: schema.TypeString, + Computed: true, + }, + + "enable_monitoring": { + Type: schema.TypeBool, + Computed: true, + }, + + "ebs_block_device": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "delete_on_termination": { + Type: schema.TypeBool, + Computed: true, + }, + + "device_name": { + Type: schema.TypeString, + Computed: true, + }, + + "iops": { + Type: schema.TypeInt, + Computed: true, + }, + + "snapshot_id": { + Type: schema.TypeString, + Computed: true, + }, + + "volume_size": { + Type: schema.TypeInt, + Computed: true, + }, + + "volume_type": { + Type: schema.TypeString, + Computed: true, + }, + + "encrypted": { + Type: schema.TypeBool, + Computed: true, + }, + }, + }, + }, + + "ephemeral_block_device": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "device_name": { + Type: schema.TypeString, + Computed: true, + }, + + "virtual_name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + + "root_block_device": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "delete_on_termination": { + Type: schema.TypeBool, + Computed: true, + }, + + "iops": { + Type: schema.TypeInt, + Computed: true, + }, + + "volume_size": { + Type: schema.TypeInt, + Computed: true, + }, + + "volume_type": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + }, + } +} + +func dataSourceAwsLaunchConfigurationRead(d *schema.ResourceData, meta interface{}) error { + autoscalingconn := meta.(*AWSClient).autoscalingconn + ec2conn := meta.(*AWSClient).ec2conn + + if v, ok := d.GetOk("name"); ok { + d.SetId(v.(string)) + } + + describeOpts := autoscaling.DescribeLaunchConfigurationsInput{ + LaunchConfigurationNames: []*string{aws.String(d.Id())}, + } + + log.Printf("[DEBUG] launch configuration describe configuration: %s", describeOpts) + describConfs, err := autoscalingconn.DescribeLaunchConfigurations(&describeOpts) + if err != nil { + return fmt.Errorf("Error retrieving launch configuration: %s", err) + } + + lc := describConfs.LaunchConfigurations[0] + + d.Set("key_name", lc.KeyName) + d.Set("image_id", lc.ImageId) + d.Set("instance_type", lc.InstanceType) + d.Set("name", lc.LaunchConfigurationName) + d.Set("user_data", lc.UserData) + + d.Set("iam_instance_profile", lc.IamInstanceProfile) + d.Set("ebs_optimized", lc.EbsOptimized) + d.Set("spot_price", lc.SpotPrice) + d.Set("enable_monitoring", lc.InstanceMonitoring.Enabled) + d.Set("security_groups", lc.SecurityGroups) + d.Set("associate_public_ip_address", lc.AssociatePublicIpAddress) + + d.Set("vpc_classic_link_id", lc.ClassicLinkVPCId) + d.Set("vpc_classic_link_security_groups", lc.ClassicLinkVPCSecurityGroups) + + if err := readLCBlockDevices(d, lc, ec2conn); err != nil { + return err + } + + return nil +} diff --git a/aws/data_source_aws_launch_configuration_test.go b/aws/data_source_aws_launch_configuration_test.go new file mode 100644 index 00000000000..7722c6134c0 --- /dev/null +++ b/aws/data_source_aws_launch_configuration_test.go @@ -0,0 +1,68 @@ +package aws + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccAWSLaunchConfigurationDataSource_basic(t *testing.T) { + rInt := acctest.RandInt() + rName := "data.aws_launch_configuration.foo" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccLaunchConfigurationDataSourceConfig(rInt), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet(rName, "image_id"), + resource.TestCheckResourceAttrSet(rName, "instance_type"), + resource.TestCheckResourceAttrSet(rName, "associate_public_ip_address"), + resource.TestCheckResourceAttrSet(rName, "user_data"), + resource.TestCheckResourceAttr(rName, "root_block_device.#", "1"), + resource.TestCheckResourceAttr(rName, "ebs_block_device.#", "1"), + resource.TestCheckResourceAttr(rName, "ephemeral_block_device.#", "1"), + ), + }, + }, + }) +} + +func testAccLaunchConfigurationDataSourceConfig(rInt int) string { + return fmt.Sprintf(` +resource "aws_launch_configuration" "foo" { + name = "terraform-test-%d" + image_id = "ami-21f78e11" + instance_type = "m1.small" + associate_public_ip_address = true + user_data = "foobar-user-data" + + root_block_device { + volume_type = "gp2" + volume_size = 11 + } + ebs_block_device { + device_name = "/dev/sdb" + volume_size = 9 + } + ebs_block_device { + device_name = "/dev/sdc" + volume_size = 10 + volume_type = "io1" + iops = 100 + } + ephemeral_block_device { + device_name = "/dev/sde" + virtual_name = "ephemeral0" + } +} + +data "aws_launch_configuration" "foo" { + name = "${aws_launch_configuration.foo.name}" +} +`, rInt) +} diff --git a/aws/provider.go b/aws/provider.go index 380e2f75207..a5020dfe052 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -225,6 +225,7 @@ func Provider() terraform.ResourceProvider { "aws_kms_secret": dataSourceAwsKmsSecret(), "aws_lambda_function": dataSourceAwsLambdaFunction(), "aws_lambda_invocation": dataSourceAwsLambdaInvocation(), + "aws_launch_configuration": dataSourceAwsLaunchConfiguration(), "aws_mq_broker": dataSourceAwsMqBroker(), "aws_nat_gateway": dataSourceAwsNatGateway(), "aws_network_acls": dataSourceAwsNetworkAcls(), From 5d6fb812a99ccb1f18d425fe25b619fd34cc7760 Mon Sep 17 00:00:00 2001 From: Kash Date: Mon, 5 Mar 2018 11:03:21 -0500 Subject: [PATCH 2/4] add documentation --- website/aws.erb | 3 ++ .../docs/d/launch_configuration.html.markdown | 48 +++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 website/docs/d/launch_configuration.html.markdown diff --git a/website/aws.erb b/website/aws.erb index 01fba3efc5e..0070bbdc6e5 100644 --- a/website/aws.erb +++ b/website/aws.erb @@ -253,6 +253,9 @@ > aws_lambda_function + > + aws_launch_configuration + > aws_lb diff --git a/website/docs/d/launch_configuration.html.markdown b/website/docs/d/launch_configuration.html.markdown new file mode 100644 index 00000000000..76b6054639c --- /dev/null +++ b/website/docs/d/launch_configuration.html.markdown @@ -0,0 +1,48 @@ +--- +layout: "aws" +page_title: "AWS: aws_launch_configuration" +sidebar_current: "docs-aws-datasource-launch-configuration" +description: |- + Provides a Launch Configuration data source. +--- + +# aws_launch_configuration + +Provides information about a Launch Configuration. + +## Example Usage + +```hcl +data "aws_launch_configuration" "ubuntu" { + name = "test-launch-config" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the launch configuration. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the launch configuration. +* `name` - The name of the launch configuration. +* `image_id` - The EC2 image ID of the instance. +* `instance_type` - The 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. +* `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. +* `vpc_classic_link_security_groups` - The IDs of one or more security groups for the specified ClassicLink-enabled VPC. +* `user_data` - The user data of the instance. +* `enable_monitoring` - Whether detailed monitoring is enabled. +* `ebs_optimized` - Whether the launched EC2 instance will be EBS-optimized. +* `root_block_device` - The root block device of the instance. +* `ebs_block_device` - The EBS block devices attached to the instance. +* `ephemeral_block_device` - The Ephemeral volumes on the instance. +* `spot_price` - The price to use for reserving spot instances. +* `placement_tenancy` - The tenancy of the instance. From 88ef715ee551acf9e8d13c1b610b8dfe6f137357 Mon Sep 17 00:00:00 2001 From: Kash Date: Thu, 28 Jun 2018 10:18:03 -0400 Subject: [PATCH 3/4] nil checks and update documentation --- aws/data_source_aws_launch_configuration.go | 27 ++++++++-- .../docs/d/launch_configuration.html.markdown | 52 +++++++++++++------ 2 files changed, 59 insertions(+), 20 deletions(-) diff --git a/aws/data_source_aws_launch_configuration.go b/aws/data_source_aws_launch_configuration.go index 7f257eca24d..94822f5c444 100644 --- a/aws/data_source_aws_launch_configuration.go +++ b/aws/data_source_aws_launch_configuration.go @@ -1,6 +1,7 @@ package aws import ( + "errors" "fmt" "log" @@ -195,6 +196,14 @@ func dataSourceAwsLaunchConfigurationRead(d *schema.ResourceData, meta interface return fmt.Errorf("Error retrieving launch configuration: %s", err) } + if describConfs == nil || len(describConfs.LaunchConfigurations) == 0 { + return errors.New("No matching Launch Configuration found") + } + + if len(describConfs.LaunchConfigurations) > 1 { + return errors.New("Multiple matching Launch Configurations found") + } + lc := describConfs.LaunchConfigurations[0] d.Set("key_name", lc.KeyName) @@ -202,16 +211,24 @@ func dataSourceAwsLaunchConfigurationRead(d *schema.ResourceData, meta interface d.Set("instance_type", lc.InstanceType) d.Set("name", lc.LaunchConfigurationName) d.Set("user_data", lc.UserData) - d.Set("iam_instance_profile", lc.IamInstanceProfile) d.Set("ebs_optimized", lc.EbsOptimized) d.Set("spot_price", lc.SpotPrice) - d.Set("enable_monitoring", lc.InstanceMonitoring.Enabled) - d.Set("security_groups", lc.SecurityGroups) d.Set("associate_public_ip_address", lc.AssociatePublicIpAddress) - d.Set("vpc_classic_link_id", lc.ClassicLinkVPCId) - d.Set("vpc_classic_link_security_groups", lc.ClassicLinkVPCSecurityGroups) + d.Set("enable_monitoring", false) + + if lc.InstanceMonitoring != nil { + d.Set("enable_monitoring", lc.InstanceMonitoring.Enabled) + } + + if err := d.Set("security_groups", lc.SecurityGroups); err != nil { + return fmt.Errorf("error setting security_groups: %s", err) + } + + if err := d.Set("vpc_classic_link_security_groups", lc.ClassicLinkVPCSecurityGroups); err != nil { + return fmt.Errorf("error setting vpc_classic_link_security_groups: %s", err) + } if err := readLCBlockDevices(d, lc, ec2conn); err != nil { return err diff --git a/website/docs/d/launch_configuration.html.markdown b/website/docs/d/launch_configuration.html.markdown index 76b6054639c..ff3582b73b0 100644 --- a/website/docs/d/launch_configuration.html.markdown +++ b/website/docs/d/launch_configuration.html.markdown @@ -6,7 +6,7 @@ description: |- Provides a Launch Configuration data source. --- -# aws_launch_configuration +# Data Source: aws_launch_configuration Provides information about a Launch Configuration. @@ -29,20 +29,42 @@ The following arguments are supported: The following attributes are exported: * `id` - The ID of the launch configuration. -* `name` - The name of the launch configuration. -* `image_id` - The EC2 image ID of the instance. -* `instance_type` - The 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. -* `security_groups` - A list of associated security group IDS. -* `associate_public_ip_address` - Whether a public ip address is associated with the instance. +* `name` - The Name of the launch configuration. +* `image_id` - The EC2 Image ID of the instance. +* `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. +* `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. -* `vpc_classic_link_security_groups` - The IDs of one or more security groups for the specified ClassicLink-enabled VPC. -* `user_data` - The user data of the instance. -* `enable_monitoring` - Whether detailed monitoring is enabled. +* `vpc_classic_link_security_groups` - The IDs of one or more Security Groups for the specified ClassicLink-enabled VPC. +* `user_data` - The User Data of the instance. +* `enable_monitoring` - Whether Detailed Monitoring is Enabled. * `ebs_optimized` - Whether the launched EC2 instance will be EBS-optimized. -* `root_block_device` - The root block device of the instance. -* `ebs_block_device` - The EBS block devices attached to the instance. +* `root_block_device` - The Root Block Device of the instance. +* `ebs_block_device` - The EBS Block Devices attached to the instance. * `ephemeral_block_device` - The Ephemeral volumes on the instance. -* `spot_price` - The price to use for reserving spot instances. -* `placement_tenancy` - The tenancy of the instance. +* `spot_price` - The Price to use for reserving Spot instances. +* `placement_tenancy` - The Tenancy of the instance. + +`root_block_device` is exported with the following attributes: + +* `delete_on_termination` - Whether the EBS Volume will be deleted on instance termination. +* `iops` - The provisioned IOPs of the volume. +* `volume_size` - The Size of the volume. +* `volume_type` - The Type of the volume. + +`ebs_block_device` is exported with the following attributes: + +* `delete_on_termination` - Whether the EBS Volume will be deleted on instance termination. +* `device_name` - The Name of the device. +* `iops` - The provisioned IOPs of the volume. +* `snapshot_id` - The Snapshot ID of the mount. +* `volume_size` - The Size of the volume. +* `volume_type` - The Type of the volume. +* `encrypted` - Whether the volume is Encrypted. + +`ephemeral_block_device` is exported with the following attributes: + +* `device_name` - The Name of the device. +* `virtual_name` - The Virtual Name of the device. From 40d6ecfb965b8d75b42021ae9c28db45bf039c88 Mon Sep 17 00:00:00 2001 From: Kash Date: Thu, 28 Jun 2018 11:25:15 -0400 Subject: [PATCH 4/4] fix setting security group --- aws/data_source_aws_launch_configuration.go | 12 ++++- ...ta_source_aws_launch_configuration_test.go | 45 ++++++++++++++++++- 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/aws/data_source_aws_launch_configuration.go b/aws/data_source_aws_launch_configuration.go index 94822f5c444..e02cbd2a06a 100644 --- a/aws/data_source_aws_launch_configuration.go +++ b/aws/data_source_aws_launch_configuration.go @@ -222,11 +222,19 @@ func dataSourceAwsLaunchConfigurationRead(d *schema.ResourceData, meta interface d.Set("enable_monitoring", lc.InstanceMonitoring.Enabled) } - if err := d.Set("security_groups", lc.SecurityGroups); err != nil { + vpcSGs := make([]string, 0, len(lc.SecurityGroups)) + for _, sg := range lc.SecurityGroups { + vpcSGs = append(vpcSGs, *sg) + } + if err := d.Set("security_groups", vpcSGs); err != nil { return fmt.Errorf("error setting security_groups: %s", err) } - if err := d.Set("vpc_classic_link_security_groups", lc.ClassicLinkVPCSecurityGroups); err != nil { + classicSGs := make([]string, 0, len(lc.ClassicLinkVPCSecurityGroups)) + for _, sg := range lc.ClassicLinkVPCSecurityGroups { + classicSGs = append(classicSGs, *sg) + } + if err := d.Set("vpc_classic_link_security_groups", classicSGs); err != nil { return fmt.Errorf("error setting vpc_classic_link_security_groups: %s", err) } diff --git a/aws/data_source_aws_launch_configuration_test.go b/aws/data_source_aws_launch_configuration_test.go index 7722c6134c0..880e842e134 100644 --- a/aws/data_source_aws_launch_configuration_test.go +++ b/aws/data_source_aws_launch_configuration_test.go @@ -17,7 +17,7 @@ func TestAccAWSLaunchConfigurationDataSource_basic(t *testing.T) { Providers: testAccProviders, Steps: []resource.TestStep{ { - Config: testAccLaunchConfigurationDataSourceConfig(rInt), + Config: testAccLaunchConfigurationDataSourceConfig_basic(rInt), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttrSet(rName, "image_id"), resource.TestCheckResourceAttrSet(rName, "instance_type"), @@ -31,8 +31,25 @@ func TestAccAWSLaunchConfigurationDataSource_basic(t *testing.T) { }, }) } +func TestAccAWSLaunchConfigurationDataSource_securityGroups(t *testing.T) { + rInt := acctest.RandInt() + rName := "data.aws_launch_configuration.foo" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccLaunchConfigurationDataSourceConfig_securityGroups(rInt), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(rName, "security_groups.#", "1"), + ), + }, + }, + }) +} -func testAccLaunchConfigurationDataSourceConfig(rInt int) string { +func testAccLaunchConfigurationDataSourceConfig_basic(rInt int) string { return fmt.Sprintf(` resource "aws_launch_configuration" "foo" { name = "terraform-test-%d" @@ -66,3 +83,27 @@ data "aws_launch_configuration" "foo" { } `, rInt) } + +func testAccLaunchConfigurationDataSourceConfig_securityGroups(rInt int) string { + return fmt.Sprintf(` +resource "aws_vpc" "test" { + cidr_block = "10.1.0.0/16" +} + +resource "aws_security_group" "test" { + name = "terraform-test_%d" + vpc_id = "${aws_vpc.test.id}" +} + +resource "aws_launch_configuration" "test" { + name = "terraform-test-%d" + image_id = "ami-21f78e11" + instance_type = "m1.small" + security_groups = ["${aws_security_group.test.id}"] +} + +data "aws_launch_configuration" "foo" { + name = "${aws_launch_configuration.test.name}" +} +`, rInt, rInt) +}