-
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.
Browse files
Browse the repository at this point in the history
Add top-level ELB Attachment resource
- Loading branch information
Showing
5 changed files
with
394 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,121 @@ | ||
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, | ||
Delete: resourceAwsElbAttachmentDelete, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"elb": &schema.Schema{ | ||
Type: schema.TypeString, | ||
ForceNew: true, | ||
Required: true, | ||
}, | ||
|
||
"instance": &schema.Schema{ | ||
Type: schema.TypeString, | ||
ForceNew: true, | ||
Required: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceAwsElbAttachmentCreate(d *schema.ResourceData, meta interface{}) error { | ||
elbconn := meta.(*AWSClient).elbconn | ||
elbName := d.Get("elb").(string) | ||
|
||
instance := d.Get("instance").(string) | ||
|
||
registerInstancesOpts := elb.RegisterInstancesWithLoadBalancerInput{ | ||
LoadBalancerName: aws.String(elbName), | ||
Instances: []*elb.Instance{{InstanceId: aws.String(instance)}}, | ||
} | ||
|
||
log.Printf("[INFO] registering instance %s with ELB %s", instance, elbName) | ||
|
||
_, 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) | ||
|
||
// only add the instance that was previously defined for this resource | ||
expected := d.Get("instance").(string) | ||
|
||
// Retrieve the ELB properties to get a list of attachments | ||
describeElbOpts := &elb.DescribeLoadBalancersInput{ | ||
LoadBalancerNames: []*string{aws.String(elbName)}, | ||
} | ||
|
||
resp, err := elbconn.DescribeLoadBalancers(describeElbOpts) | ||
if err != nil { | ||
if isLoadBalancerNotFound(err) { | ||
log.Printf("[ERROR] ELB %s not found", elbName) | ||
d.SetId("") | ||
return nil | ||
} | ||
return fmt.Errorf("Error retrieving ELB: %s", err) | ||
} | ||
if len(resp.LoadBalancerDescriptions) != 1 { | ||
log.Printf("[ERROR] Unable to find ELB: %s", resp.LoadBalancerDescriptions) | ||
d.SetId("") | ||
return nil | ||
} | ||
|
||
// only set the instance Id that this resource manages | ||
found := false | ||
for _, i := range resp.LoadBalancerDescriptions[0].Instances { | ||
if expected == *i.InstanceId { | ||
d.Set("instance", expected) | ||
found = true | ||
} | ||
} | ||
|
||
if !found { | ||
log.Printf("[WARN] instance %s not found in elb attachments", expected) | ||
d.SetId("") | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func resourceAwsElbAttachmentDelete(d *schema.ResourceData, meta interface{}) error { | ||
elbconn := meta.(*AWSClient).elbconn | ||
elbName := d.Get("elb").(string) | ||
|
||
instance := d.Get("instance").(string) | ||
|
||
log.Printf("[INFO] Deleting Attachment %s from: %s", instance, elbName) | ||
|
||
deRegisterInstancesOpts := elb.DeregisterInstancesFromLoadBalancerInput{ | ||
LoadBalancerName: aws.String(elbName), | ||
Instances: []*elb.Instance{{InstanceId: aws.String(instance)}}, | ||
} | ||
|
||
_, err := elbconn.DeregisterInstancesFromLoadBalancer(&deRegisterInstancesOpts) | ||
if err != nil { | ||
return fmt.Errorf("Failure deregistering instances from ELB: %s", err) | ||
} | ||
|
||
return nil | ||
} |
232 changes: 232 additions & 0 deletions
232
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,232 @@ | ||
package aws | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"testing" | ||
|
||
"github.com/aws/aws-sdk-go/service/elb" | ||
"github.com/hashicorp/terraform/helper/resource" | ||
"github.com/hashicorp/terraform/terraform" | ||
) | ||
|
||
func TestAccAWSELBAttachment_basic(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(2), | ||
), | ||
}, | ||
|
||
resource.TestStep{ | ||
Config: testAccAWSELBAttachmentConfig4, | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckAWSELBExists("aws_elb.bar", &conf), | ||
testCheckInstanceAttached(0), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
// remove and instance and check that it's correctly re-attached. | ||
func TestAccAWSELBAttachment_drift(t *testing.T) { | ||
var conf elb.LoadBalancerDescription | ||
|
||
deregInstance := func() { | ||
conn := testAccProvider.Meta().(*AWSClient).elbconn | ||
|
||
deRegisterInstancesOpts := elb.DeregisterInstancesFromLoadBalancerInput{ | ||
LoadBalancerName: conf.LoadBalancerName, | ||
Instances: conf.Instances, | ||
} | ||
|
||
log.Printf("[DEBUG] deregistering instance %s from ELB", conf.Instances[0].InstanceId) | ||
|
||
_, err := conn.DeregisterInstancesFromLoadBalancer(&deRegisterInstancesOpts) | ||
if err != nil { | ||
t.Fatalf("Failure deregistering instances from ELB: %s", err) | ||
} | ||
|
||
} | ||
|
||
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), | ||
), | ||
}, | ||
|
||
// remove an instance from the ELB, and make sure it gets re-added | ||
resource.TestStep{ | ||
Config: testAccAWSELBAttachmentConfig1, | ||
PreConfig: deregInstance, | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckAWSELBExists("aws_elb.bar", &conf), | ||
testCheckInstanceAttached(1), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
// add one attachment | ||
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" "foo1" { | ||
# us-west-2 | ||
ami = "ami-043a5034" | ||
instance_type = "t1.micro" | ||
} | ||
resource "aws_elb_attachment" "foo1" { | ||
elb = "${aws_elb.bar.id}" | ||
instance = "${aws_instance.foo1.id}" | ||
} | ||
` | ||
|
||
// add a second attachment | ||
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" "foo1" { | ||
# 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" "foo1" { | ||
elb = "${aws_elb.bar.id}" | ||
instance = "${aws_instance.foo1.id}" | ||
} | ||
resource "aws_elb_attachment" "foo2" { | ||
elb = "${aws_elb.bar.id}" | ||
instance = "${aws_instance.foo2.id}" | ||
} | ||
` | ||
|
||
// swap attachments between resources | ||
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" | ||
} | ||
} | ||
resource "aws_instance" "foo1" { | ||
# 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" "foo1" { | ||
elb = "${aws_elb.bar.id}" | ||
instance = "${aws_instance.foo2.id}" | ||
} | ||
resource "aws_elb_attachment" "foo2" { | ||
elb = "${aws_elb.bar.id}" | ||
instance = "${aws_instance.foo1.id}" | ||
} | ||
` | ||
|
||
// destroy attachments | ||
const testAccAWSELBAttachmentConfig4 = ` | ||
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" | ||
} | ||
} | ||
` |
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
Oops, something went wrong.