From 4c9a4ad04145745882119aa1f9cc1b8704d26679 Mon Sep 17 00:00:00 2001 From: Jack Pearkes Date: Fri, 27 Jun 2014 12:47:19 -0400 Subject: [PATCH] providers/aws: add elb layout, move instance into it's own namespace --- builtin/providers/aws/resource_aws_elb.go | 56 +++++++ .../providers/aws/resource_aws_instance.go | 152 +++++++++++++++++ builtin/providers/aws/resource_provider.go | 4 + builtin/providers/aws/resources.go | 154 +----------------- 4 files changed, 218 insertions(+), 148 deletions(-) create mode 100644 builtin/providers/aws/resource_aws_elb.go create mode 100644 builtin/providers/aws/resource_aws_instance.go diff --git a/builtin/providers/aws/resource_aws_elb.go b/builtin/providers/aws/resource_aws_elb.go new file mode 100644 index 000000000..b5226c6ed --- /dev/null +++ b/builtin/providers/aws/resource_aws_elb.go @@ -0,0 +1,56 @@ +package aws + +import ( + "fmt" + "log" + + "github.com/hashicorp/terraform/helper/diff" + "github.com/hashicorp/terraform/terraform" + "github.com/pearkes/goamz/elb" +) + +func resource_aws_elb_create( + s *terraform.ResourceState, + d *terraform.ResourceDiff, + meta interface{}) (*terraform.ResourceState, error) { + p := meta.(*ResourceProvider) + elbconn := p.elbconn + + // Merge the diff into the state so that we have all the attributes + // properly. + rs := s.MergeDiff(d) + + // Create + + return +} + +func resource_aws_elb_destroy( + s *terraform.ResourceState, + meta interface{}) error { + p := meta.(*ResourceProvider) + elbconn := p.elbconn + + // destroy + + return +} + +func resource_aws_elb_diff( + s *terraform.ResourceState, + c *terraform.ResourceConfig, + meta interface{}) (*terraform.ResourceDiff, error) { + + // diff +} + +func resource_aws_elb_refresh( + s *terraform.ResourceState, + meta interface{}) (*terraform.ResourceState, error) { + p := meta.(*ResourceProvider) + elbconn := p.elbconn + + // retrieve elb health status and describe instances? + + return +} diff --git a/builtin/providers/aws/resource_aws_instance.go b/builtin/providers/aws/resource_aws_instance.go new file mode 100644 index 000000000..b18c42fda --- /dev/null +++ b/builtin/providers/aws/resource_aws_instance.go @@ -0,0 +1,152 @@ +package aws + +import ( + "fmt" + "log" + + "github.com/hashicorp/terraform/helper/diff" + "github.com/hashicorp/terraform/terraform" + "github.com/mitchellh/goamz/ec2" +) + +func resource_aws_instance_create( + s *terraform.ResourceState, + d *terraform.ResourceDiff, + meta interface{}) (*terraform.ResourceState, error) { + p := meta.(*ResourceProvider) + ec2conn := p.ec2conn + + // Merge the diff into the state so that we have all the attributes + // properly. + rs := s.MergeDiff(d) + + // Create the instance + runOpts := &ec2.RunInstances{ + ImageId: rs.Attributes["ami"], + InstanceType: rs.Attributes["instance_type"], + } + log.Printf("[DEBUG] Run configuration: %#v", runOpts) + runResp, err := ec2conn.RunInstances(runOpts) + if err != nil { + return nil, fmt.Errorf("Error launching source instance: %s", err) + } + + instance := &runResp.Instances[0] + log.Printf("[INFO] Instance ID: %s", instance.InstanceId) + + // Store the resulting ID so we can look this up later + rs.ID = instance.InstanceId + + // Wait for the instance to become running so we can get some attributes + // that aren't available until later. + log.Printf( + "[DEBUG] Waiting for instance (%s) to become running", + instance.InstanceId) + instanceRaw, err := WaitForState(&StateChangeConf{ + Pending: []string{"pending"}, + Target: "running", + Refresh: InstanceStateRefreshFunc(ec2conn, instance.InstanceId), + }) + if err != nil { + return rs, fmt.Errorf( + "Error waiting for instance (%s) to become ready: %s", + instance.InstanceId, err) + } + instance = instanceRaw.(*ec2.Instance) + + // Set our attributes + return resource_aws_instance_update_state(rs, instance) +} + +func resource_aws_instance_destroy( + s *terraform.ResourceState, + meta interface{}) error { + p := meta.(*ResourceProvider) + ec2conn := p.ec2conn + + log.Printf("[INFO] Terminating instance: %s", s.ID) + if _, err := ec2conn.TerminateInstances([]string{s.ID}); err != nil { + return fmt.Errorf("Error terminating instance: %s", err) + } + + log.Printf( + "[DEBUG] Waiting for instance (%s) to become terminated", + s.ID) + _, err := WaitForState(&StateChangeConf{ + Pending: []string{"pending", "running", "shutting-down", "stopped", "stopping"}, + Target: "terminated", + Refresh: InstanceStateRefreshFunc(ec2conn, s.ID), + }) + if err != nil { + return fmt.Errorf( + "Error waiting for instance (%s) to terminate: %s", + s.ID, err) + } + + return nil +} + +func resource_aws_instance_diff( + s *terraform.ResourceState, + c *terraform.ResourceConfig, + meta interface{}) (*terraform.ResourceDiff, error) { + b := &diff.ResourceBuilder{ + CreateComputedAttrs: []string{ + "public_dns", + "public_ip", + "private_dns", + "private_ip", + }, + + RequiresNewAttrs: []string{ + "ami", + "availability_zone", + "instance_type", + }, + } + + return b.Diff(s, c) +} + +func resource_aws_instance_refresh( + s *terraform.ResourceState, + meta interface{}) (*terraform.ResourceState, error) { + p := meta.(*ResourceProvider) + ec2conn := p.ec2conn + + resp, err := ec2conn.Instances([]string{s.ID}, ec2.NewFilter()) + if err != nil { + // If the instance was not found, return nil so that we can show + // that the instance is gone. + if ec2err, ok := err.(*ec2.Error); ok && ec2err.Code == "InvalidInstanceID.NotFound" { + return nil, nil + } + + // Some other error, report it + return s, err + } + + // If nothing was found, then return no state + if len(resp.Reservations) == 0 { + return nil, nil + } + + instance := &resp.Reservations[0].Instances[0] + + // If the instance is terminated, then it is gone + if instance.State.Name == "terminated" { + return nil, nil + } + + return resource_aws_instance_update_state(s, instance) +} + +func resource_aws_instance_update_state( + s *terraform.ResourceState, + instance *ec2.Instance) (*terraform.ResourceState, error) { + s.Attributes["public_dns"] = instance.DNSName + s.Attributes["public_ip"] = instance.PublicIpAddress + s.Attributes["private_dns"] = instance.PrivateDNSName + s.Attributes["private_ip"] = instance.PrivateIpAddress + return s, nil +} diff --git a/builtin/providers/aws/resource_provider.go b/builtin/providers/aws/resource_provider.go index 4b4d3b6bb..850b4d705 100644 --- a/builtin/providers/aws/resource_provider.go +++ b/builtin/providers/aws/resource_provider.go @@ -7,12 +7,14 @@ import ( "github.com/hashicorp/terraform/helper/multierror" "github.com/hashicorp/terraform/terraform" "github.com/mitchellh/goamz/ec2" + "github.com/pearkes/goamz/elb" ) type ResourceProvider struct { Config Config ec2conn *ec2.EC2 + elbconn *elb.ELB } func (p *ResourceProvider) Validate(c *terraform.ResourceConfig) ([]string, []error) { @@ -47,6 +49,8 @@ func (p *ResourceProvider) Configure(c *terraform.ResourceConfig) error { if len(errs) == 0 { log.Println("Initializing EC2 connection") p.ec2conn = ec2.New(auth, region) + log.Println("Initializing ELB connection") + p.elbconn = elb.New(auth, region) } if len(errs) > 0 { diff --git a/builtin/providers/aws/resources.go b/builtin/providers/aws/resources.go index b3a4d7769..77820baed 100644 --- a/builtin/providers/aws/resources.go +++ b/builtin/providers/aws/resources.go @@ -1,13 +1,7 @@ package aws import ( - "fmt" - "log" - - "github.com/hashicorp/terraform/helper/diff" "github.com/hashicorp/terraform/helper/resource" - "github.com/hashicorp/terraform/terraform" - "github.com/mitchellh/goamz/ec2" ) // resourceMap is the mapping of resources we support to their basic @@ -23,148 +17,12 @@ func init() { Diff: resource_aws_instance_diff, Refresh: resource_aws_instance_refresh, }, + "aws_elastic_load_balancer": resource.Resource{ + Create: resource_aws_elb_create, + Destroy: resource_aws_elb_destroy, + Diff: resource_aws_elb_diff, + Refresh: resource_aws_elb_refresh, + }, }, } } - -func resource_aws_instance_create( - s *terraform.ResourceState, - d *terraform.ResourceDiff, - meta interface{}) (*terraform.ResourceState, error) { - p := meta.(*ResourceProvider) - ec2conn := p.ec2conn - - // Merge the diff into the state so that we have all the attributes - // properly. - rs := s.MergeDiff(d) - - // Create the instance - runOpts := &ec2.RunInstances{ - ImageId: rs.Attributes["ami"], - InstanceType: rs.Attributes["instance_type"], - } - log.Printf("[DEBUG] Run configuration: %#v", runOpts) - runResp, err := ec2conn.RunInstances(runOpts) - if err != nil { - return nil, fmt.Errorf("Error launching source instance: %s", err) - } - - instance := &runResp.Instances[0] - log.Printf("[INFO] Instance ID: %s", instance.InstanceId) - - // Store the resulting ID so we can look this up later - rs.ID = instance.InstanceId - - // Wait for the instance to become running so we can get some attributes - // that aren't available until later. - log.Printf( - "[DEBUG] Waiting for instance (%s) to become running", - instance.InstanceId) - instanceRaw, err := WaitForState(&StateChangeConf{ - Pending: []string{"pending"}, - Target: "running", - Refresh: InstanceStateRefreshFunc(ec2conn, instance.InstanceId), - }) - if err != nil { - return rs, fmt.Errorf( - "Error waiting for instance (%s) to become ready: %s", - instance.InstanceId, err) - } - instance = instanceRaw.(*ec2.Instance) - - // Set our attributes - return resource_aws_instance_update_state(rs, instance) -} - -func resource_aws_instance_destroy( - s *terraform.ResourceState, - meta interface{}) error { - p := meta.(*ResourceProvider) - ec2conn := p.ec2conn - - log.Printf("[INFO] Terminating instance: %s", s.ID) - if _, err := ec2conn.TerminateInstances([]string{s.ID}); err != nil { - return fmt.Errorf("Error terminating instance: %s", err) - } - - log.Printf( - "[DEBUG] Waiting for instance (%s) to become terminated", - s.ID) - _, err := WaitForState(&StateChangeConf{ - Pending: []string{"pending", "running", "shutting-down", "stopped", "stopping"}, - Target: "terminated", - Refresh: InstanceStateRefreshFunc(ec2conn, s.ID), - }) - if err != nil { - return fmt.Errorf( - "Error waiting for instance (%s) to terminate: %s", - s.ID, err) - } - - return nil -} - -func resource_aws_instance_diff( - s *terraform.ResourceState, - c *terraform.ResourceConfig, - meta interface{}) (*terraform.ResourceDiff, error) { - b := &diff.ResourceBuilder{ - Attrs: map[string]diff.AttrType{ - "ami": diff.AttrTypeCreate, - "availability_zone": diff.AttrTypeCreate, - "instance_type": diff.AttrTypeCreate, - }, - - ComputedAttrs: []string{ - "public_dns", - "public_ip", - "private_dns", - "private_ip", - }, - } - - return b.Diff(s, c) -} - -func resource_aws_instance_refresh( - s *terraform.ResourceState, - meta interface{}) (*terraform.ResourceState, error) { - p := meta.(*ResourceProvider) - ec2conn := p.ec2conn - - resp, err := ec2conn.Instances([]string{s.ID}, ec2.NewFilter()) - if err != nil { - // If the instance was not found, return nil so that we can show - // that the instance is gone. - if ec2err, ok := err.(*ec2.Error); ok && ec2err.Code == "InvalidInstanceID.NotFound" { - return nil, nil - } - - // Some other error, report it - return s, err - } - - // If nothing was found, then return no state - if len(resp.Reservations) == 0 { - return nil, nil - } - - instance := &resp.Reservations[0].Instances[0] - - // If the instance is terminated, then it is gone - if instance.State.Name == "terminated" { - return nil, nil - } - - return resource_aws_instance_update_state(s, instance) -} - -func resource_aws_instance_update_state( - s *terraform.ResourceState, - instance *ec2.Instance) (*terraform.ResourceState, error) { - s.Attributes["public_dns"] = instance.DNSName - s.Attributes["public_ip"] = instance.PublicIpAddress - s.Attributes["private_dns"] = instance.PrivateDNSName - s.Attributes["private_ip"] = instance.PrivateIpAddress - return s, nil -}