provider/aws: Support Tags for `aws_alb` and `aws_alb_target_group` (#8422)
resources Fixes #8420 Adds the ability to update tags on the ALB resource as well as supporting tags on `aws_alb_target_group` ``` ALB Tests: % make testacc TEST=./builtin/providers/aws TESTARGS='-run=TestAccAWSALB_' 2 ↵ ✹ ==> Checking that code complies with gofmt requirements... /Users/stacko/Code/go/bin/stringer go generate $(go list ./... | grep -v /terraform/vendor/) 2016/08/23 19:30:16 Generated command/internal_plugin_list.go TF_ACC=1 go test ./builtin/providers/aws -v -run=TestAccAWSALB_ -timeout 120m === RUN TestAccAWSALB_basic --- PASS: TestAccAWSALB_basic (67.18s) === RUN TestAccAWSALB_tags --- PASS: TestAccAWSALB_tags (99.88s) === RUN TestAccAWSALB_noSecurityGroup --- PASS: TestAccAWSALB_noSecurityGroup (62.49s) === RUN TestAccAWSALB_accesslogs --- PASS: TestAccAWSALB_accesslogs (126.25s) PASS ok github.com/hashicorp/terraform/builtin/providers/aws 355.835s ``` ``` ALB Target Group Tests: % make testacc TEST=./builtin/providers/aws TESTARGS='-run=TestAccAWSALBTargetGroup_' ==> Checking that code complies with gofmt requirements... /Users/stacko/Code/go/bin/stringer go generate $(go list ./... | grep -v /terraform/vendor/) 2016/08/23 19:37:37 Generated command/internal_plugin_list.go TF_ACC=1 go test ./builtin/providers/aws -v -run=TestAccAWSALBTargetGroup_ -timeout 120m === RUN TestAccAWSALBTargetGroup_basic --- PASS: TestAccAWSALBTargetGroup_basic (47.26s) === RUN TestAccAWSALBTargetGroup_tags --- PASS: TestAccAWSALBTargetGroup_tags (81.01s) === RUN TestAccAWSALBTargetGroup_updateHealthCheck --- PASS: TestAccAWSALBTargetGroup_updateHealthCheck (78.74s) PASS ok github.com/hashicorp/terraform/builtin/providers/aws 207.025s ```
This commit is contained in:
parent
70cc108614
commit
0d8709bdf3
|
@ -233,6 +233,12 @@ func resourceAwsAlbRead(d *schema.ResourceData, meta interface{}) error {
|
|||
func resourceAwsAlbUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||
elbconn := meta.(*AWSClient).elbv2conn
|
||||
|
||||
if !d.IsNewResource() {
|
||||
if err := setElbV2Tags(elbconn, d); err != nil {
|
||||
return errwrap.Wrapf("Error Modifying Tags on ALB: {{err}}", err)
|
||||
}
|
||||
}
|
||||
|
||||
attributes := make([]*elbv2.LoadBalancerAttribute, 0)
|
||||
|
||||
if d.HasChange("access_logs") {
|
||||
|
@ -310,29 +316,6 @@ func resourceAwsAlbDelete(d *schema.ResourceData, meta interface{}) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// tagsToMapELBv2 turns the list of tags into a map.
|
||||
func tagsToMapELBv2(ts []*elbv2.Tag) map[string]string {
|
||||
result := make(map[string]string)
|
||||
for _, t := range ts {
|
||||
result[*t.Key] = *t.Value
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// tagsFromMapELBv2 returns the tags for the given map of data.
|
||||
func tagsFromMapELBv2(m map[string]interface{}) []*elbv2.Tag {
|
||||
var result []*elbv2.Tag
|
||||
for k, v := range m {
|
||||
result = append(result, &elbv2.Tag{
|
||||
Key: aws.String(k),
|
||||
Value: aws.String(v.(string)),
|
||||
})
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// flattenSubnetsFromAvailabilityZones creates a slice of strings containing the subnet IDs
|
||||
// for the ALB based on the AvailabilityZones structure returned by the API.
|
||||
func flattenSubnetsFromAvailabilityZones(availabilityZones []*elbv2.AvailabilityZone) []string {
|
||||
|
|
|
@ -146,6 +146,8 @@ func resourceAwsAlbTargetGroup() *schema.Resource {
|
|||
},
|
||||
},
|
||||
},
|
||||
|
||||
"tags": tagsSchema(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -258,6 +260,10 @@ func resourceAwsAlbTargetGroupRead(d *schema.ResourceData, meta interface{}) err
|
|||
func resourceAwsAlbTargetGroupUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||
elbconn := meta.(*AWSClient).elbv2conn
|
||||
|
||||
if err := setElbV2Tags(elbconn, d); err != nil {
|
||||
return errwrap.Wrapf("Error Modifying Tags on ALB Target Group: {{err}}", err)
|
||||
}
|
||||
|
||||
if d.HasChange("health_check") {
|
||||
healthChecks := d.Get("health_check").([]interface{})
|
||||
|
||||
|
|
|
@ -51,6 +51,37 @@ func TestAccAWSALBTargetGroup_basic(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestAccAWSALBTargetGroup_tags(t *testing.T) {
|
||||
var conf elbv2.TargetGroup
|
||||
targetGroupName := fmt.Sprintf("test-target-group-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum))
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
IDRefreshName: "aws_alb_target_group.test",
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckAWSALBTargetGroupDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccAWSALBTargetGroupConfig_basic(targetGroupName),
|
||||
Check: resource.ComposeAggregateTestCheckFunc(
|
||||
testAccCheckAWSALBTargetGroupExists("aws_alb_target_group.test", &conf),
|
||||
resource.TestCheckResourceAttr("aws_alb_target_group.test", "tags.%", "1"),
|
||||
resource.TestCheckResourceAttr("aws_alb_target_group.test", "tags.TestName", "TestAccAWSALBTargetGroup_basic"),
|
||||
),
|
||||
},
|
||||
{
|
||||
Config: testAccAWSALBTargetGroupConfig_updateTags(targetGroupName),
|
||||
Check: resource.ComposeAggregateTestCheckFunc(
|
||||
testAccCheckAWSALBTargetGroupExists("aws_alb_target_group.test", &conf),
|
||||
resource.TestCheckResourceAttr("aws_alb_target_group.test", "tags.%", "2"),
|
||||
resource.TestCheckResourceAttr("aws_alb_target_group.test", "tags.Environment", "Production"),
|
||||
resource.TestCheckResourceAttr("aws_alb_target_group.test", "tags.Type", "ALB Target Group"),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccAWSALBTargetGroup_updateHealthCheck(t *testing.T) {
|
||||
var conf elbv2.TargetGroup
|
||||
targetGroupName := fmt.Sprintf("test-target-group-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum))
|
||||
|
@ -198,6 +229,50 @@ func testAccAWSALBTargetGroupConfig_basic(targetGroupName string) string {
|
|||
unhealthy_threshold = 3
|
||||
matcher = "200-299"
|
||||
}
|
||||
|
||||
tags {
|
||||
TestName = "TestAccAWSALBTargetGroup_basic"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_vpc" "test" {
|
||||
cidr_block = "10.0.0.0/16"
|
||||
|
||||
tags {
|
||||
TestName = "TestAccAWSALBTargetGroup_basic"
|
||||
}
|
||||
}`, targetGroupName)
|
||||
}
|
||||
|
||||
func testAccAWSALBTargetGroupConfig_updateTags(targetGroupName string) string {
|
||||
return fmt.Sprintf(`resource "aws_alb_target_group" "test" {
|
||||
name = "%s"
|
||||
port = 443
|
||||
protocol = "HTTPS"
|
||||
vpc_id = "${aws_vpc.test.id}"
|
||||
|
||||
deregistration_delay = 200
|
||||
|
||||
stickiness {
|
||||
type = "lb_cookie"
|
||||
cookie_duration = 10000
|
||||
}
|
||||
|
||||
health_check {
|
||||
path = "/health"
|
||||
interval = 60
|
||||
port = 8081
|
||||
protocol = "HTTP"
|
||||
timeout = 3
|
||||
healthy_threshold = 3
|
||||
unhealthy_threshold = 3
|
||||
matcher = "200-299"
|
||||
}
|
||||
|
||||
tags {
|
||||
Environment = "Production"
|
||||
Type = "ALB Target Group"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_vpc" "test" {
|
||||
|
|
|
@ -45,6 +45,37 @@ func TestAccAWSALB_basic(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestAccAWSALB_tags(t *testing.T) {
|
||||
var conf elbv2.LoadBalancer
|
||||
albName := fmt.Sprintf("testaccawsalb-basic-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum))
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
IDRefreshName: "aws_alb.alb_test",
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckAWSALBDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccAWSALBConfig_basic(albName),
|
||||
Check: resource.ComposeAggregateTestCheckFunc(
|
||||
testAccCheckAWSALBExists("aws_alb.alb_test", &conf),
|
||||
resource.TestCheckResourceAttr("aws_alb.alb_test", "tags.%", "1"),
|
||||
resource.TestCheckResourceAttr("aws_alb.alb_test", "tags.TestName", "TestAccAWSALB_basic"),
|
||||
),
|
||||
},
|
||||
{
|
||||
Config: testAccAWSALBConfig_updatedTags(albName),
|
||||
Check: resource.ComposeAggregateTestCheckFunc(
|
||||
testAccCheckAWSALBExists("aws_alb.alb_test", &conf),
|
||||
resource.TestCheckResourceAttr("aws_alb.alb_test", "tags.%", "2"),
|
||||
resource.TestCheckResourceAttr("aws_alb.alb_test", "tags.Type", "Sample Type Tag"),
|
||||
resource.TestCheckResourceAttr("aws_alb.alb_test", "tags.Environment", "Production"),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// TestAccAWSALB_noSecurityGroup regression tests the issue in #8264,
|
||||
// where if an ALB is created without a security group, a default one
|
||||
// is assigned.
|
||||
|
@ -118,7 +149,7 @@ func TestAccAWSALB_accesslogs(t *testing.T) {
|
|||
resource.TestCheckResourceAttr("aws_alb.alb_test", "subnets.#", "2"),
|
||||
resource.TestCheckResourceAttr("aws_alb.alb_test", "security_groups.#", "1"),
|
||||
resource.TestCheckResourceAttr("aws_alb.alb_test", "tags.%", "1"),
|
||||
resource.TestCheckResourceAttr("aws_alb.alb_test", "tags.TestName", "TestAccAWSALB_basic"),
|
||||
resource.TestCheckResourceAttr("aws_alb.alb_test", "tags.TestName", "TestAccAWSALB_basic1"),
|
||||
resource.TestCheckResourceAttr("aws_alb.alb_test", "enable_deletion_protection", "false"),
|
||||
resource.TestCheckResourceAttr("aws_alb.alb_test", "idle_timeout", "50"),
|
||||
resource.TestCheckResourceAttrSet("aws_alb.alb_test", "vpc_id"),
|
||||
|
@ -237,6 +268,73 @@ resource "aws_subnet" "alb_test" {
|
|||
}
|
||||
}
|
||||
|
||||
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"
|
||||
}
|
||||
}`, albName)
|
||||
}
|
||||
func testAccAWSALBConfig_updatedTags(albName string) string {
|
||||
return fmt.Sprintf(`resource "aws_alb" "alb_test" {
|
||||
name = "%s"
|
||||
internal = false
|
||||
security_groups = ["${aws_security_group.alb_test.id}"]
|
||||
subnets = ["${aws_subnet.alb_test.*.id}"]
|
||||
|
||||
idle_timeout = 30
|
||||
enable_deletion_protection = false
|
||||
|
||||
tags {
|
||||
Environment = "Production"
|
||||
Type = "Sample Type Tag"
|
||||
}
|
||||
}
|
||||
|
||||
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"
|
||||
|
@ -278,7 +376,7 @@ func testAccAWSALBConfig_accessLogs(albName, bucketName string) string {
|
|||
}
|
||||
|
||||
tags {
|
||||
TestName = "TestAccAWSALB_basic"
|
||||
TestName = "TestAccAWSALB_basic1"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/aws/aws-sdk-go/service/elbv2"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
)
|
||||
|
||||
|
@ -17,6 +18,43 @@ func tagsSchema() *schema.Schema {
|
|||
}
|
||||
}
|
||||
|
||||
func setElbV2Tags(conn *elbv2.ELBV2, d *schema.ResourceData) error {
|
||||
if d.HasChange("tags") {
|
||||
oraw, nraw := d.GetChange("tags")
|
||||
o := oraw.(map[string]interface{})
|
||||
n := nraw.(map[string]interface{})
|
||||
create, remove := diffElbV2Tags(tagsFromMapELBv2(o), tagsFromMapELBv2(n))
|
||||
|
||||
// Set tags
|
||||
if len(remove) > 0 {
|
||||
var tagKeys []*string
|
||||
for _, tag := range remove {
|
||||
tagKeys = append(tagKeys, tag.Key)
|
||||
}
|
||||
log.Printf("[DEBUG] Removing tags: %#v from %s", remove, d.Id())
|
||||
_, err := conn.RemoveTags(&elbv2.RemoveTagsInput{
|
||||
ResourceArns: []*string{aws.String(d.Id())},
|
||||
TagKeys: tagKeys,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if len(create) > 0 {
|
||||
log.Printf("[DEBUG] Creating tags: %s for %s", create, d.Id())
|
||||
_, err := conn.AddTags(&elbv2.AddTagsInput{
|
||||
ResourceArns: []*string{aws.String(d.Id())},
|
||||
Tags: create,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// setTags is a helper to set the tags for a resource. It expects the
|
||||
// tags field to be named "tags"
|
||||
func setTags(conn *ec2.EC2, d *schema.ResourceData) error {
|
||||
|
@ -97,3 +135,46 @@ func tagsToMap(ts []*ec2.Tag) map[string]string {
|
|||
|
||||
return result
|
||||
}
|
||||
|
||||
func diffElbV2Tags(oldTags, newTags []*elbv2.Tag) ([]*elbv2.Tag, []*elbv2.Tag) {
|
||||
// First, we're creating everything we have
|
||||
create := make(map[string]interface{})
|
||||
for _, t := range newTags {
|
||||
create[*t.Key] = *t.Value
|
||||
}
|
||||
|
||||
// Build the list of what to remove
|
||||
var remove []*elbv2.Tag
|
||||
for _, t := range oldTags {
|
||||
old, ok := create[*t.Key]
|
||||
if !ok || old != *t.Value {
|
||||
// Delete it!
|
||||
remove = append(remove, t)
|
||||
}
|
||||
}
|
||||
|
||||
return tagsFromMapELBv2(create), remove
|
||||
}
|
||||
|
||||
// tagsToMapELBv2 turns the list of tags into a map.
|
||||
func tagsToMapELBv2(ts []*elbv2.Tag) map[string]string {
|
||||
result := make(map[string]string)
|
||||
for _, t := range ts {
|
||||
result[*t.Key] = *t.Value
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// tagsFromMapELBv2 returns the tags for the given map of data.
|
||||
func tagsFromMapELBv2(m map[string]interface{}) []*elbv2.Tag {
|
||||
var result []*elbv2.Tag
|
||||
for k, v := range m {
|
||||
result = append(result, &elbv2.Tag{
|
||||
Key: aws.String(k),
|
||||
Value: aws.String(v.(string)),
|
||||
})
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ The following arguments are supported:
|
|||
* `deregistration_delay` - (Optional) The amount time for Elastic Load Balancing to wait before changing the state of a deregistering target from draining to unused. The range is 0-3600 seconds. The default value is 300 seconds.
|
||||
* `stickiness` - (Optional) A Stickiness block. Stickiness blocks are documented below.
|
||||
* `health_check` - (Optional) A Health Check block. Health Check blocks are documented below.
|
||||
* `tags` - (Optional) A mapping of tags to assign to the resource.
|
||||
|
||||
Stickiness Blocks (`stickiness`) support the following:
|
||||
|
||||
|
|
Loading…
Reference in New Issue