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

provider/aws: aws_autoscaling_attachment resource #9146

Merged
merged 3 commits into from
Nov 3, 2016
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
1 change: 1 addition & 0 deletions builtin/providers/aws/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ func Provider() terraform.ResourceProvider {
"aws_app_cookie_stickiness_policy": resourceAwsAppCookieStickinessPolicy(),
"aws_appautoscaling_target": resourceAwsAppautoscalingTarget(),
"aws_appautoscaling_policy": resourceAwsAppautoscalingPolicy(),
"aws_autoscaling_attachment": resourceAwsAutoscalingAttachment(),
"aws_autoscaling_group": resourceAwsAutoscalingGroup(),
"aws_autoscaling_notification": resourceAwsAutoscalingNotification(),
"aws_autoscaling_policy": resourceAwsAutoscalingPolicy(),
Expand Down
108 changes: 108 additions & 0 deletions builtin/providers/aws/resource_aws_autoscaling_attachment.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package aws

import (
"fmt"
"log"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/autoscaling"
"github.com/hashicorp/errwrap"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
)

func resourceAwsAutoscalingAttachment() *schema.Resource {
return &schema.Resource{
Create: resourceAwsAutoscalingAttachmentCreate,
Read: resourceAwsAutoscalingAttachmentRead,
Delete: resourceAwsAutoscalingAttachmentDelete,

Schema: map[string]*schema.Schema{
"autoscaling_group_name": &schema.Schema{
Type: schema.TypeString,
ForceNew: true,
Required: true,
},

"elb": &schema.Schema{
Type: schema.TypeString,
ForceNew: true,
Required: true,
},
},
}
}

func resourceAwsAutoscalingAttachmentCreate(d *schema.ResourceData, meta interface{}) error {
asgconn := meta.(*AWSClient).autoscalingconn
asgName := d.Get("autoscaling_group_name").(string)
elbName := d.Get("elb").(string)

attachElbInput := &autoscaling.AttachLoadBalancersInput{
AutoScalingGroupName: aws.String(asgName),
LoadBalancerNames: []*string{aws.String(elbName)},
}

log.Printf("[INFO] registering asg %s with ELBs %s", asgName, elbName)

if _, err := asgconn.AttachLoadBalancers(attachElbInput); err != nil {
return errwrap.Wrapf(fmt.Sprintf("Failure attaching AutoScaling Group %s with Elastic Load Balancer: %s: {{err}}", asgName, elbName), err)
}

d.SetId(resource.PrefixedUniqueId(fmt.Sprintf("%s-", asgName)))

return resourceAwsAutoscalingAttachmentRead(d, meta)
}

func resourceAwsAutoscalingAttachmentRead(d *schema.ResourceData, meta interface{}) error {
asgconn := meta.(*AWSClient).autoscalingconn
asgName := d.Get("autoscaling_group_name").(string)
elbName := d.Get("elb").(string)

// Retrieve the ASG properites to get list of associated ELBs
asg, err := getAwsAutoscalingGroup(asgName, asgconn)

if err != nil {
return err
}
if asg == nil {
log.Printf("[INFO] Autoscaling Group %q not found", asgName)
d.SetId("")
return nil
}

found := false
for _, i := range asg.LoadBalancerNames {
if elbName == *i {
d.Set("elb", elbName)
found = true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would break here, so that you don't check rest of them, as there will be no need at this point, I believe.

break
}
}

if !found {
log.Printf("[WARN] Association for %s was not found in ASG assocation", elbName)
d.SetId("")
}

return nil
}

func resourceAwsAutoscalingAttachmentDelete(d *schema.ResourceData, meta interface{}) error {
asgconn := meta.(*AWSClient).autoscalingconn
asgName := d.Get("autoscaling_group_name").(string)
elbName := d.Get("elb").(string)

log.Printf("[INFO] Deleting ELB %s association from: %s", elbName, asgName)

detachOpts := &autoscaling.DetachLoadBalancersInput{
AutoScalingGroupName: aws.String(asgName),
LoadBalancerNames: []*string{aws.String(elbName)},
}

if _, err := asgconn.DetachLoadBalancers(detachOpts); err != nil {
return errwrap.Wrapf(fmt.Sprintf("Failure detaching AutoScaling Group %s with Elastic Load Balancer: %s: {{err}}", asgName, elbName), err)
}

return nil
}
144 changes: 144 additions & 0 deletions builtin/providers/aws/resource_aws_autoscaling_attachment_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
package aws

import (
"fmt"
"testing"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/autoscaling"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)

func TestAccAwsAutoscalingAttachment_basic(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccAWSAutoscalingAttachment_basic,
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSAutocalingAttachmentExists("aws_autoscaling_group.asg", 0),
),
},
// Add in one association
resource.TestStep{
Config: testAccAWSAutoscalingAttachment_associated,
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSAutocalingAttachmentExists("aws_autoscaling_group.asg", 1),
),
},
// Test adding a 2nd
resource.TestStep{
Config: testAccAWSAutoscalingAttachment_double_associated,
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSAutocalingAttachmentExists("aws_autoscaling_group.asg", 2),
),
},
// Now remove that newest one
resource.TestStep{
Config: testAccAWSAutoscalingAttachment_associated,
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSAutocalingAttachmentExists("aws_autoscaling_group.asg", 1),
),
},
// Now remove them both
resource.TestStep{
Config: testAccAWSAutoscalingAttachment_basic,
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSAutocalingAttachmentExists("aws_autoscaling_group.asg", 0),
),
},
},
})
}

func testAccCheckAWSAutocalingAttachmentExists(asgname string, loadBalancerCount int) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[asgname]
if !ok {
return fmt.Errorf("Not found: %s", asgname)
}

conn := testAccProvider.Meta().(*AWSClient).autoscalingconn
asg := rs.Primary.ID

actual, err := conn.DescribeAutoScalingGroups(&autoscaling.DescribeAutoScalingGroupsInput{
AutoScalingGroupNames: []*string{aws.String(asg)},
})

if err != nil {
return fmt.Errorf("Recieved an error when attempting to load %s: %s", asg, err)
}

if loadBalancerCount != len(actual.AutoScalingGroups[0].LoadBalancerNames) {
return fmt.Errorf("Error: ASG has the wrong number of load balacners associated. Expected [%d] but got [%d]", loadBalancerCount, len(actual.AutoScalingGroups[0].LoadBalancerNames))
}

return nil
}
}

const testAccAWSAutoscalingAttachment_basic = `
resource "aws_elb" "foo" {
availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"]

listener {
instance_port = 8000
instance_protocol = "http"
lb_port = 80
lb_protocol = "http"
}
}

resource "aws_elb" "bar" {
availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"]

listener {
instance_port = 8000
instance_protocol = "http"
lb_port = 80
lb_protocol = "http"
}
}

resource "aws_launch_configuration" "as_conf" {
name = "test_config"
image_id = "ami-f34032c3"
instance_type = "t1.micro"
}

resource "aws_autoscaling_group" "asg" {
availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"]
name = "asg-lb-assoc-terraform-test"
max_size = 1
min_size = 0
desired_capacity = 0
health_check_grace_period = 300
force_delete = true
launch_configuration = "${aws_launch_configuration.as_conf.name}"

tag {
key = "Name"
value = "terraform-asg-lg-assoc-test"
propagate_at_launch = true
}
}

`

const testAccAWSAutoscalingAttachment_associated = testAccAWSAutoscalingAttachment_basic + `
resource "aws_autoscaling_attachment" "asg_attachment_foo" {
autoscaling_group_name = "${aws_autoscaling_group.asg.id}"
elb = "${aws_elb.foo.id}"
}

`

const testAccAWSAutoscalingAttachment_double_associated = testAccAWSAutoscalingAttachment_associated + `
resource "aws_autoscaling_attachment" "asg_attachment_bar" {
autoscaling_group_name = "${aws_autoscaling_group.asg.id}"
elb = "${aws_elb.bar.id}"
}

`
1 change: 1 addition & 0 deletions builtin/providers/aws/resource_aws_autoscaling_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ func resourceAwsAutoscalingGroup() *schema.Resource {
"load_balancers": &schema.Schema{
Type: schema.TypeSet,
Optional: true,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
layout: "aws"
page_title: "AWS: aws_autoscaling_attachment"
sidebar_current: "docs-aws-resource-autoscaling-attachment"
description: |-
Provides an AutoScaling Group Attachment resource.
---

# aws\_autoscaling\_attachment

Provides an AutoScaling Attachment resource.

~> **NOTE on AutoScaling Groups and ASG Attachments:** Terraform currently provides
both a standalone ASG Attachment resource (describing an ASG attached to
an ELB), and an [AutoScaling Group resource](autoscaling_group.html) with
`load_balancers` defined in-line. At this time you cannot use an ASG with in-line
load balancers in conjunction with an ASG Attachment resource. Doing so will cause a
conflict and will overwrite attachments.
## Example Usage

```
# Create a new load balancer attachment
resource "aws_autoscaling_attachment" "asg_attachment_bar" {
autoscaling_group_name = "${aws_autoscaling_group.asg.id}"
elb = "${aws_elb.bar.id}"
}
```

## Argument Reference

The following arguments are supported:

* `autoscaling_group_name` - (Required) Name of ASG to associate with the ELB.
* `elb` - (Required) The name of the ELB.

4 changes: 4 additions & 0 deletions website/source/layouts/aws.erb
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,10 @@
<a href="/docs/providers/aws/r/autoscaling_group.html">aws_autoscaling_group</a>
</li>

<li<%= sidebar_current("docs-aws-resource-autoscaling-attachment") %>>
<a href="/docs/providers/aws/r/autoscaling_attachment.html">aws_autoscaling_attachment</a>
</li>

<li<%= sidebar_current("docs-aws-resource-autoscaling-lifecycle-hook") %>>
<a href="/docs/providers/aws/r/autoscaling_lifecycle_hooks.html">aws_autoscaling_lifecycle_hook</a>
</li>
Expand Down