Merge pull request #8321 from hashicorp/f-aws-alb-attachment

provider/aws: Add aws_alb_target_group_attachment
This commit is contained in:
James Nugent 2016-08-19 16:26:04 +01:00 committed by GitHub
commit 41d8a45ae9
5 changed files with 340 additions and 0 deletions

View File

@ -156,6 +156,7 @@ func Provider() terraform.ResourceProvider {
"aws_alb_listener": resourceAwsAlbListener(), "aws_alb_listener": resourceAwsAlbListener(),
"aws_alb_listener_rule": resourceAwsAlbListenerRule(), "aws_alb_listener_rule": resourceAwsAlbListenerRule(),
"aws_alb_target_group": resourceAwsAlbTargetGroup(), "aws_alb_target_group": resourceAwsAlbTargetGroup(),
"aws_alb_target_group_attachment": resourceAwsAlbTargetGroupAttachment(),
"aws_ami": resourceAwsAmi(), "aws_ami": resourceAwsAmi(),
"aws_ami_copy": resourceAwsAmiCopy(), "aws_ami_copy": resourceAwsAmiCopy(),
"aws_ami_from_instance": resourceAwsAmiFromInstance(), "aws_ami_from_instance": resourceAwsAmiFromInstance(),

View File

@ -0,0 +1,131 @@
package aws
import (
"fmt"
"log"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/service/elbv2"
"github.com/hashicorp/errwrap"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
)
func resourceAwsAlbTargetGroupAttachment() *schema.Resource {
return &schema.Resource{
Create: resourceAwsAlbAttachmentCreate,
Read: resourceAwsAlbAttachmentRead,
Delete: resourceAwsAlbAttachmentDelete,
Schema: map[string]*schema.Schema{
"target_group_arn": {
Type: schema.TypeString,
ForceNew: true,
Required: true,
},
"target_id": {
Type: schema.TypeString,
ForceNew: true,
Required: true,
},
"port": {
Type: schema.TypeInt,
ForceNew: true,
Required: true,
},
},
}
}
func resourceAwsAlbAttachmentCreate(d *schema.ResourceData, meta interface{}) error {
elbconn := meta.(*AWSClient).elbv2conn
params := &elbv2.RegisterTargetsInput{
TargetGroupArn: aws.String(d.Get("target_group_arn").(string)),
Targets: []*elbv2.TargetDescription{
{
Id: aws.String(d.Get("target_id").(string)),
Port: aws.Int64(int64(d.Get("port").(int))),
},
},
}
log.Printf("[INFO] Registering Target %s (%d) with Target Group %s", d.Get("target_id").(string),
d.Get("port").(int), d.Get("target_group_arn").(string))
_, err := elbconn.RegisterTargets(params)
if err != nil {
return errwrap.Wrapf("Error registering targets with target group: {{err}}", err)
}
d.SetId(resource.PrefixedUniqueId(fmt.Sprintf("%s-", d.Get("target_group_arn"))))
return nil
}
func resourceAwsAlbAttachmentDelete(d *schema.ResourceData, meta interface{}) error {
elbconn := meta.(*AWSClient).elbv2conn
params := &elbv2.DeregisterTargetsInput{
TargetGroupArn: aws.String(d.Get("target_group_arn").(string)),
Targets: []*elbv2.TargetDescription{
{
Id: aws.String(d.Get("target_id").(string)),
Port: aws.Int64(int64(d.Get("port").(int))),
},
},
}
_, err := elbconn.DeregisterTargets(params)
if err != nil && !isTargetGroupNotFound(err) {
return errwrap.Wrapf("Error deregistering Targets: {{err}}", err)
}
d.SetId("")
return nil
}
// resourceAwsAlbAttachmentRead requires all of the fields in order to describe the correct
// target, so there is no work to do beyond ensuring that the target and group still exist.
func resourceAwsAlbAttachmentRead(d *schema.ResourceData, meta interface{}) error {
elbconn := meta.(*AWSClient).elbv2conn
resp, err := elbconn.DescribeTargetHealth(&elbv2.DescribeTargetHealthInput{
TargetGroupArn: aws.String(d.Get("target_group_arn").(string)),
Targets: []*elbv2.TargetDescription{
{
Id: aws.String(d.Get("target_id").(string)),
Port: aws.Int64(int64(d.Get("port").(int))),
},
},
})
if err != nil {
if isTargetGroupNotFound(err) {
log.Printf("[WARN] Target group does not exist, removing target attachment %s", d.Id())
d.SetId("")
return nil
}
if isInvalidTarget(err) {
log.Printf("[WARN] Target does not exist, removing target attachment %s", d.Id())
d.SetId("")
return nil
}
return errwrap.Wrapf("Error reading Target Health: {{err}}", err)
}
if len(resp.TargetHealthDescriptions) != 1 {
log.Printf("[WARN] Target does not exist, removing target attachment %s", d.Id())
d.SetId("")
return nil
}
return nil
}
func isInvalidTarget(err error) bool {
elberr, ok := err.(awserr.Error)
return ok && elberr.Code() == "InvalidTarget"
}

View File

@ -0,0 +1,154 @@
package aws
import (
"errors"
"fmt"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/elbv2"
"github.com/hashicorp/errwrap"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
"strconv"
"testing"
)
func TestAccAWSALBTargetGroupAttachment_basic(t *testing.T) {
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: testAccCheckAWSALBTargetGroupAttachmentDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSALBTargetGroupAttachmentConfig_basic(targetGroupName),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckAWSALBTargetGroupAttachmentExists("aws_alb_target_group_attachment.test"),
),
},
},
})
}
func testAccCheckAWSALBTargetGroupAttachmentExists(n string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Not found: %s", n)
}
if rs.Primary.ID == "" {
return errors.New("No Target Group Attachment ID is set")
}
conn := testAccProvider.Meta().(*AWSClient).elbv2conn
port, _ := strconv.Atoi(rs.Primary.Attributes["port"])
describe, err := conn.DescribeTargetHealth(&elbv2.DescribeTargetHealthInput{
TargetGroupArn: aws.String(rs.Primary.Attributes["target_group_arn"]),
Targets: []*elbv2.TargetDescription{
{
Id: aws.String(rs.Primary.Attributes["target_id"]),
Port: aws.Int64(int64(port)),
},
},
})
if err != nil {
return err
}
if len(describe.TargetHealthDescriptions) != 1 {
return errors.New("Target Group Attachment not found")
}
return nil
}
}
func testAccCheckAWSALBTargetGroupAttachmentDestroy(s *terraform.State) error {
conn := testAccProvider.Meta().(*AWSClient).elbv2conn
for _, rs := range s.RootModule().Resources {
if rs.Type != "aws_alb_target_group_attachment" {
continue
}
port, _ := strconv.Atoi(rs.Primary.Attributes["port"])
describe, err := conn.DescribeTargetHealth(&elbv2.DescribeTargetHealthInput{
TargetGroupArn: aws.String(rs.Primary.Attributes["target_group_arn"]),
Targets: []*elbv2.TargetDescription{
{
Id: aws.String(rs.Primary.Attributes["target_id"]),
Port: aws.Int64(int64(port)),
},
},
})
if err == nil {
if len(describe.TargetHealthDescriptions) != 0 {
return fmt.Errorf("Target Group Attachment %q still exists", rs.Primary.ID)
}
}
// Verify the error
if isTargetGroupNotFound(err) || isInvalidTarget(err) {
return nil
} else {
return errwrap.Wrapf("Unexpected error checking ALB destroyed: {{err}}", err)
}
}
return nil
}
func testAccAWSALBTargetGroupAttachmentConfig_basic(targetGroupName string) string {
return fmt.Sprintf(`
resource "aws_alb_target_group_attachment" "test" {
target_group_arn = "${aws_alb_target_group.test.arn}"
target_id = "${aws_instance.test.id}"
port = 80
}
resource "aws_instance" "test" {
ami = "ami-f701cb97"
instance_type = "t2.micro"
subnet_id = "${aws_subnet.subnet.id}"
}
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"
}
}
resource "aws_subnet" "subnet" {
cidr_block = "10.0.1.0/24"
vpc_id = "${aws_vpc.test.id}"
}
resource "aws_vpc" "test" {
cidr_block = "10.0.0.0/16"
}`, targetGroupName)
}

View File

@ -0,0 +1,50 @@
---
layout: "aws"
page_title: "AWS: aws_alb_target_group_attachment"
sidebar_current: "docs-aws-resource-alb-target-group-attachment"
description: |-
Provides the ability to register instances and containers with an ALB
target group
---
# aws\_alb\_target\_group\_attachment
Provides the ability to register instances and containers with an ALB
target group
## Example Usage
```
resource "aws_alb_target_group_attachment" "test" {
target_group_arn = "${aws_alb_target_group.test.arn}"
target_id = "${aws_instance.test.id}"
port = 80
}
resource "aws_alb_target_group" "test" {
// Other arguments
}
resource "aws_instance" "test" {
// Other arguments
}
```
## Argument Reference
The following arguments are supported:
* `target_group_arn` - (Required) The ARN of the target group with which to register targets
* `target_id` (Required) The ID of the target. This is the Instance ID for an instance, or the container ID for an ECS container.
* `port` - (Required) The port on which targets receive traffic.
## Attributes Reference
The following attributes are exported in addition to the arguments listed above:
* `id` - A unique identifier for the attachment
## Import
Target Group Attachments cannot be imported.

View File

@ -226,6 +226,10 @@
<a href="/docs/providers/aws/r/alb_target_group.html">aws_alb_target_group</a> <a href="/docs/providers/aws/r/alb_target_group.html">aws_alb_target_group</a>
</li> </li>
<li<%= sidebar_current("docs-aws-resource-alb-target-group-attachment") %>>
<a href="/docs/providers/aws/r/alb_target_group_attachment.html">aws_alb_target_group_attachment</a>
</li>
<li<%= sidebar_current("docs-aws-resource-ami") %>> <li<%= sidebar_current("docs-aws-resource-ami") %>>
<a href="/docs/providers/aws/r/ami.html">aws_ami</a> <a href="/docs/providers/aws/r/ami.html">aws_ami</a>
</li> </li>