-
Notifications
You must be signed in to change notification settings - Fork 9.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add top-level ELB Attachment resource
Add an aws_elb_attachment resource so that the attment of instances to an ELB can be managed separately from an aws_elb and prevent dependency cycles.
- Loading branch information
Showing
3 changed files
with
266 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
package aws | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/service/elb" | ||
"github.com/hashicorp/terraform/helper/resource" | ||
"github.com/hashicorp/terraform/helper/schema" | ||
) | ||
|
||
func resourceAwsElbAttachment() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceAwsElbAttachmentCreate, | ||
Read: resourceAwsElbAttachmentRead, | ||
Update: resourceAwsElbAttachmentUpdate, | ||
Delete: resourceAwsElbAttachmentDelete, | ||
Importer: &schema.ResourceImporter{ | ||
State: schema.ImportStatePassthrough, | ||
}, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"elb": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Required: true, | ||
}, | ||
|
||
"instances": &schema.Schema{ | ||
Type: schema.TypeSet, | ||
Elem: &schema.Schema{Type: schema.TypeString}, | ||
Set: schema.HashString, | ||
Required: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceAwsElbAttachmentCreate(d *schema.ResourceData, meta interface{}) error { | ||
elbconn := meta.(*AWSClient).elbconn | ||
elbName := d.Get("elb").(string) | ||
|
||
instances := expandInstanceString(d.Get("instances").(*schema.Set).List()) | ||
|
||
registerInstancesOpts := elb.RegisterInstancesWithLoadBalancerInput{ | ||
LoadBalancerName: aws.String(elbName), | ||
Instances: instances, | ||
} | ||
|
||
_, err := elbconn.RegisterInstancesWithLoadBalancer(®isterInstancesOpts) | ||
if err != nil { | ||
return fmt.Errorf("Failure registering instances with ELB: %s", err) | ||
} | ||
|
||
d.SetId(resource.PrefixedUniqueId(fmt.Sprintf("%s-", elbName))) | ||
|
||
return nil | ||
} | ||
|
||
func resourceAwsElbAttachmentRead(d *schema.ResourceData, meta interface{}) error { | ||
elbconn := meta.(*AWSClient).elbconn | ||
elbName := d.Get("elb").(string) | ||
|
||
// Retrieve the ELB properties to get a list of attachments | ||
describeElbOpts := &elb.DescribeLoadBalancersInput{ | ||
LoadBalancerNames: []*string{aws.String(elbName)}, | ||
} | ||
|
||
describeResp, err := elbconn.DescribeLoadBalancers(describeElbOpts) | ||
if err != nil { | ||
return fmt.Errorf("Error retrieving ELB: %s", err) | ||
} | ||
if len(describeResp.LoadBalancerDescriptions) != 1 { | ||
return fmt.Errorf("Unable to find ELB: %#v", describeResp.LoadBalancerDescriptions) | ||
} | ||
|
||
lb := describeResp.LoadBalancerDescriptions[0] | ||
|
||
d.Set("instances", flattenInstances(lb.Instances)) | ||
|
||
return nil | ||
} | ||
|
||
func resourceAwsElbAttachmentUpdate(d *schema.ResourceData, meta interface{}) error { | ||
elbconn := meta.(*AWSClient).elbconn | ||
elbName := d.Get("elb").(string) | ||
|
||
if d.HasChange("instances") { | ||
o, n := d.GetChange("instances") | ||
os := o.(*schema.Set) | ||
ns := n.(*schema.Set) | ||
remove := expandInstanceString(os.Difference(ns).List()) | ||
add := expandInstanceString(ns.Difference(os).List()) | ||
|
||
if len(add) > 0 { | ||
registerInstancesOpts := elb.RegisterInstancesWithLoadBalancerInput{ | ||
LoadBalancerName: aws.String(elbName), | ||
Instances: add, | ||
} | ||
|
||
_, err := elbconn.RegisterInstancesWithLoadBalancer(®isterInstancesOpts) | ||
if err != nil { | ||
return fmt.Errorf("Failure registering instances with ELB: %s", err) | ||
} | ||
} | ||
if len(remove) > 0 { | ||
deRegisterInstancesOpts := elb.DeregisterInstancesFromLoadBalancerInput{ | ||
LoadBalancerName: aws.String(elbName), | ||
Instances: remove, | ||
} | ||
|
||
_, err := elbconn.DeregisterInstancesFromLoadBalancer(&deRegisterInstancesOpts) | ||
if err != nil { | ||
return fmt.Errorf("Failure deregistering instances from ELB: %s", err) | ||
} | ||
} | ||
} | ||
|
||
return resourceAwsElbAttachmentRead(d, meta) | ||
} | ||
|
||
func resourceAwsElbAttachmentDelete(d *schema.ResourceData, meta interface{}) error { | ||
elbconn := meta.(*AWSClient).elbconn | ||
elbName := d.Get("elb").(string) | ||
|
||
instanceSet := d.Get("instances").(*schema.Set) | ||
instances := expandInstanceString(instanceSet.List()) | ||
|
||
log.Printf("[INFO] Deleting Attachments %s from: %s", instanceSet, elbName) | ||
|
||
deRegisterInstancesOpts := elb.DeregisterInstancesFromLoadBalancerInput{ | ||
LoadBalancerName: aws.String(elbName), | ||
Instances: instances, | ||
} | ||
|
||
_, err := elbconn.DeregisterInstancesFromLoadBalancer(&deRegisterInstancesOpts) | ||
if err != nil { | ||
return fmt.Errorf("Failure deregistering instances from ELB: %s", err) | ||
} | ||
|
||
return nil | ||
} |
123 changes: 123 additions & 0 deletions
123
builtin/providers/aws/resource_aws_elb_attachment_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
package aws | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/aws/aws-sdk-go/service/elb" | ||
"github.com/hashicorp/terraform/helper/resource" | ||
"github.com/hashicorp/terraform/terraform" | ||
) | ||
|
||
func TestAccAWSELBAttachment(t *testing.T) { | ||
var conf elb.LoadBalancerDescription | ||
|
||
testCheckInstanceAttached := func(count int) resource.TestCheckFunc { | ||
return func(*terraform.State) error { | ||
if len(conf.Instances) != count { | ||
return fmt.Errorf("instance count does not match") | ||
} | ||
return nil | ||
} | ||
} | ||
|
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
IDRefreshName: "aws_elb.bar", | ||
Providers: testAccProviders, | ||
CheckDestroy: testAccCheckAWSELBDestroy, | ||
Steps: []resource.TestStep{ | ||
resource.TestStep{ | ||
Config: testAccAWSELBAttachmentConfig1, | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckAWSELBExists("aws_elb.bar", &conf), | ||
testCheckInstanceAttached(1), | ||
), | ||
}, | ||
|
||
resource.TestStep{ | ||
Config: testAccAWSELBAttachmentConfig2, | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckAWSELBExists("aws_elb.bar", &conf), | ||
testCheckInstanceAttached(2), | ||
), | ||
}, | ||
|
||
resource.TestStep{ | ||
Config: testAccAWSELBAttachmentConfig3, | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckAWSELBExists("aws_elb.bar", &conf), | ||
testCheckInstanceAttached(0), | ||
), | ||
}, | ||
}, | ||
}) | ||
|
||
} | ||
|
||
const testAccAWSELBAttachmentConfig1 = ` | ||
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_instance" "foo" { | ||
# us-west-2 | ||
ami = "ami-043a5034" | ||
instance_type = "t1.micro" | ||
} | ||
resource "aws_elb_attachment" "app" { | ||
elb = "${aws_elb.bar.id}" | ||
instances = ["${aws_instance.foo.id}"] | ||
} | ||
` | ||
|
||
const testAccAWSELBAttachmentConfig2 = ` | ||
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_instance" "foo" { | ||
# us-west-2 | ||
ami = "ami-043a5034" | ||
instance_type = "t1.micro" | ||
} | ||
resource "aws_instance" "foo2" { | ||
# us-west-2 | ||
ami = "ami-043a5034" | ||
instance_type = "t1.micro" | ||
} | ||
resource "aws_elb_attachment" "app" { | ||
elb = "${aws_elb.bar.id}" | ||
instances = ["${aws_instance.foo.id}", "${aws_instance.foo2.id}"] | ||
} | ||
` | ||
|
||
const testAccAWSELBAttachmentConfig3 = ` | ||
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" | ||
} | ||
} | ||
` |