diff --git a/builtin/providers/aws/resource_aws_instance.go b/builtin/providers/aws/resource_aws_instance.go index 4aee71b395..df00804a29 100644 --- a/builtin/providers/aws/resource_aws_instance.go +++ b/builtin/providers/aws/resource_aws_instance.go @@ -6,6 +6,7 @@ import ( "strconv" "time" + "github.com/hashicorp/terraform/flatmap" "github.com/hashicorp/terraform/helper/diff" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" @@ -24,13 +25,34 @@ func resource_aws_instance_create( rs := s.MergeDiff(d) delete(rs.Attributes, "source_dest_check") - // Create the instance + // Build the creation struct runOpts := &ec2.RunInstances{ ImageId: rs.Attributes["ami"], InstanceType: rs.Attributes["instance_type"], KeyName: rs.Attributes["key_name"], SubnetId: rs.Attributes["subnet_id"], } + if raw := flatmap.Expand(rs.Attributes, "security_groups"); raw != nil { + if sgs, ok := raw.([]interface{}); ok { + for _, sg := range sgs { + str, ok := sg.(string) + if !ok { + continue + } + + var g ec2.SecurityGroup + if runOpts.SubnetId != "" { + g.Id = str + } else { + g.Name = str + } + + runOpts.SecurityGroups = append(runOpts.SecurityGroups, g) + } + } + } + + // Create the instance log.Printf("[DEBUG] Run configuration: %#v", runOpts) runResp, err := ec2conn.RunInstances(runOpts) if err != nil { @@ -151,6 +173,7 @@ func resource_aws_instance_diff( "availability_zone": diff.AttrTypeCreate, "instance_type": diff.AttrTypeCreate, "key_name": diff.AttrTypeCreate, + "security_groups": diff.AttrTypeCreate, "subnet_id": diff.AttrTypeCreate, "source_dest_check": diff.AttrTypeUpdate, }, @@ -212,6 +235,23 @@ func resource_aws_instance_update_state( s.Attributes["subnet_id"] = instance.SubnetId s.Dependencies = nil + // Build up the security groups + sgs := make([]string, len(instance.SecurityGroups)) + for i, sg := range instance.SecurityGroups { + if instance.SubnetId != "" { + sgs[i] = sg.Id + } else { + sgs[i] = sg.Name + } + + s.Dependencies = append(s.Dependencies, + terraform.ResourceDependency{ID: sg.Id}, + ) + } + flatmap.Map(s.Attributes).Merge(flatmap.Flatten(map[string]interface{}{ + "security_groups": sgs, + })) + if instance.SubnetId != "" { s.Dependencies = append(s.Dependencies, terraform.ResourceDependency{ID: instance.SubnetId}, diff --git a/builtin/providers/aws/resource_aws_instance_test.go b/builtin/providers/aws/resource_aws_instance_test.go index 70acfb5f28..5cafe6f54b 100644 --- a/builtin/providers/aws/resource_aws_instance_test.go +++ b/builtin/providers/aws/resource_aws_instance_test.go @@ -9,9 +9,20 @@ import ( "github.com/mitchellh/goamz/ec2" ) -func TestAccAWSInstance(t *testing.T) { +func TestAccAWSInstance_normal(t *testing.T) { var v ec2.Instance + testCheck := func(*terraform.State) error { + if len(v.SecurityGroups) == 0 { + return fmt.Errorf("no security groups: %#v", v.SecurityGroups) + } + if v.SecurityGroups[0].Name != "tf_test_foo" { + return fmt.Errorf("no security groups: %#v", v.SecurityGroups) + } + + return nil + } + resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, @@ -22,6 +33,7 @@ func TestAccAWSInstance(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists( "aws_instance.foo", &v), + testCheck, ), }, }, @@ -146,10 +158,16 @@ func testAccCheckInstanceExists(n string, i *ec2.Instance) resource.TestCheckFun } const testAccInstanceConfig = ` +resource "aws_security_group" "tf_test_foo" { + name = "tf_test_foo" + description = "foo" +} + resource "aws_instance" "foo" { # us-west-2 ami = "ami-4fccb37f" instance_type = "m1.small" + security_groups = ["${aws_security_group.tf_test_foo.name}"] } `