diff --git a/CHANGELOG.md b/CHANGELOG.md index c10a89cce..13eb8a5ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,12 @@ ## 0.7.4 (Unreleased) FEATURES: + * **New Resource:** `aws_codecommit_trigger` [GH-8751] IMPROVEMENTS: * provider/aws: Support 'publish' attribute in lambda_function [GH-8653] * provider/aws: Export AWS ELB service account ARN [GH-8700] + * provider/aws: Allow `aws_alb` to have the name auto-generated [GH-8673] * provider/google: Resources depending on the `network` attribute can now reference the network by `self_link` or `name` [GH-8639] * provider/postgresql: The standard environment variables PGHOST, PGUSER, PGPASSWORD and PGSSLMODE are now supported for provider configuration [GH-8666] diff --git a/builtin/providers/aws/resource_aws_alb.go b/builtin/providers/aws/resource_aws_alb.go index a7bbbdfb4..0668ed4af 100644 --- a/builtin/providers/aws/resource_aws_alb.go +++ b/builtin/providers/aws/resource_aws_alb.go @@ -8,6 +8,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/elbv2" "github.com/hashicorp/errwrap" + "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" ) @@ -28,8 +29,17 @@ func resourceAwsAlb() *schema.Resource { }, "name": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + ConflictsWith: []string{"name_prefix"}, + ValidateFunc: validateElbName, + }, + + "name_prefix": { Type: schema.TypeString, - Required: true, + Optional: true, ForceNew: true, ValidateFunc: validateElbName, }, @@ -111,8 +121,18 @@ func resourceAwsAlb() *schema.Resource { func resourceAwsAlbCreate(d *schema.ResourceData, meta interface{}) error { elbconn := meta.(*AWSClient).elbv2conn + var name string + if v, ok := d.GetOk("name"); ok { + name = v.(string) + } else if v, ok := d.GetOk("name_prefix"); ok { + name = resource.PrefixedUniqueId(v.(string)) + } else { + name = resource.PrefixedUniqueId("tf-lb-") + } + d.Set("name", name) + elbOpts := &elbv2.CreateLoadBalancerInput{ - Name: aws.String(d.Get("name").(string)), + Name: aws.String(name), Tags: tagsFromMapELBv2(d.Get("tags").(map[string]interface{})), } diff --git a/builtin/providers/aws/resource_aws_alb_test.go b/builtin/providers/aws/resource_aws_alb_test.go index c70786b99..d6d5a48f8 100644 --- a/builtin/providers/aws/resource_aws_alb_test.go +++ b/builtin/providers/aws/resource_aws_alb_test.go @@ -3,6 +3,7 @@ package aws import ( "errors" "fmt" + "regexp" "testing" "github.com/aws/aws-sdk-go/aws" @@ -45,6 +46,48 @@ func TestAccAWSALB_basic(t *testing.T) { }) } +func TestAccAWSALB_generatedName(t *testing.T) { + var conf elbv2.LoadBalancer + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + IDRefreshName: "aws_alb.alb_test", + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSALBDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSALBConfig_generatedName(), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSALBExists("aws_alb.alb_test", &conf), + resource.TestCheckResourceAttrSet("aws_alb.alb_test", "name"), + ), + }, + }, + }) +} + +func TestAccAWSALB_namePrefix(t *testing.T) { + var conf elbv2.LoadBalancer + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + IDRefreshName: "aws_alb.alb_test", + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSALBDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSALBConfig_namePrefix(), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSALBExists("aws_alb.alb_test", &conf), + resource.TestCheckResourceAttrSet("aws_alb.alb_test", "name"), + resource.TestMatchResourceAttr("aws_alb.alb_test", "name", + regexp.MustCompile("^tf-lb")), + ), + }, + }, + }) +} + func TestAccAWSALB_tags(t *testing.T) { var conf elbv2.LoadBalancer albName := fmt.Sprintf("testaccawsalb-basic-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)) @@ -292,6 +335,141 @@ resource "aws_security_group" "alb_test" { } }`, albName) } + +func testAccAWSALBConfig_generatedName() string { + return fmt.Sprintf(` +resource "aws_alb" "alb_test" { + internal = false + security_groups = ["${aws_security_group.alb_test.id}"] + subnets = ["${aws_subnet.alb_test.*.id}"] + + idle_timeout = 30 + enable_deletion_protection = false + + tags { + TestName = "TestAccAWSALB_basic" + } +} + +variable "subnets" { + default = ["10.0.1.0/24", "10.0.2.0/24"] + type = "list" +} + +data "aws_availability_zones" "available" {} + +resource "aws_vpc" "alb_test" { + cidr_block = "10.0.0.0/16" + + tags { + TestName = "TestAccAWSALB_basic" + } +} + +resource "aws_subnet" "alb_test" { + count = 2 + vpc_id = "${aws_vpc.alb_test.id}" + cidr_block = "${element(var.subnets, count.index)}" + map_public_ip_on_launch = true + availability_zone = "${element(data.aws_availability_zones.available.names, count.index)}" + + tags { + TestName = "TestAccAWSALB_basic" + } +} + +resource "aws_security_group" "alb_test" { + name = "allow_all_alb_test" + description = "Used for ALB Testing" + vpc_id = "${aws_vpc.alb_test.id}" + + ingress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + + tags { + TestName = "TestAccAWSALB_basic" + } +}`) +} + +func testAccAWSALBConfig_namePrefix() string { + return fmt.Sprintf(` +resource "aws_alb" "alb_test" { + name_prefix = "tf-lb" + internal = false + security_groups = ["${aws_security_group.alb_test.id}"] + subnets = ["${aws_subnet.alb_test.*.id}"] + + idle_timeout = 30 + enable_deletion_protection = false + + tags { + TestName = "TestAccAWSALB_basic" + } +} + +variable "subnets" { + default = ["10.0.1.0/24", "10.0.2.0/24"] + type = "list" +} + +data "aws_availability_zones" "available" {} + +resource "aws_vpc" "alb_test" { + cidr_block = "10.0.0.0/16" + + tags { + TestName = "TestAccAWSALB_basic" + } +} + +resource "aws_subnet" "alb_test" { + count = 2 + vpc_id = "${aws_vpc.alb_test.id}" + cidr_block = "${element(var.subnets, count.index)}" + map_public_ip_on_launch = true + availability_zone = "${element(data.aws_availability_zones.available.names, count.index)}" + + tags { + TestName = "TestAccAWSALB_basic" + } +} + +resource "aws_security_group" "alb_test" { + name = "allow_all_alb_test" + description = "Used for ALB Testing" + vpc_id = "${aws_vpc.alb_test.id}" + + ingress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + + tags { + TestName = "TestAccAWSALB_basic" + } +}`) +} func testAccAWSALBConfig_updatedTags(albName string) string { return fmt.Sprintf(`resource "aws_alb" "alb_test" { name = "%s" diff --git a/website/source/docs/providers/aws/r/alb.html.markdown b/website/source/docs/providers/aws/r/alb.html.markdown index cbba79ab3..c4b258253 100644 --- a/website/source/docs/providers/aws/r/alb.html.markdown +++ b/website/source/docs/providers/aws/r/alb.html.markdown @@ -37,8 +37,10 @@ resource "aws_alb" "test" { The following arguments are supported: -* `name` - (Required) The name of the ALB. This name must be unique within your AWS account, can have a maximum of -32 characters, must contain only alphanumeric characters or hyphens, and must not begin or end with a hyphen. +* `name` - (Optional) The name of the ALB. This name must be unique within your AWS account, can have a maximum of 32 characters, +must contain only alphanumeric characters or hyphens, and must not begin or end with a hyphen. If not specified, +Terraform will autogenerate a name beginning with `tf-lb`. +* `name_prefix` - (Optional) Creates a unique name beginning with the specified prefix. Conflicts with `name`. * `internal` - (Optional) If true, the ALB will be internal. * `security_groups` - (Optional) A list of security group IDs to assign to the ELB. * `access_logs` - (Optional) An Access Logs block. Access Logs documented below.