github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/aws/resource_aws_default_security_group.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "log" 6 7 "github.com/aws/aws-sdk-go/aws" 8 "github.com/aws/aws-sdk-go/service/ec2" 9 "github.com/hashicorp/errwrap" 10 "github.com/hashicorp/terraform/helper/schema" 11 ) 12 13 func resourceAwsDefaultSecurityGroup() *schema.Resource { 14 // reuse aws_security_group_rule schema, and methods for READ, UPDATE 15 dsg := resourceAwsSecurityGroup() 16 dsg.Create = resourceAwsDefaultSecurityGroupCreate 17 dsg.Delete = resourceAwsDefaultSecurityGroupDelete 18 19 // Descriptions cannot be updated 20 delete(dsg.Schema, "description") 21 22 // name is a computed value for Default Security Groups and cannot be changed 23 delete(dsg.Schema, "name_prefix") 24 dsg.Schema["name"] = &schema.Schema{ 25 Type: schema.TypeString, 26 Computed: true, 27 } 28 29 // We want explicit management of Rules here, so we do not allow them to be 30 // computed. Instead, an empty config will enforce just that; removal of the 31 // rules 32 dsg.Schema["ingress"].Computed = false 33 dsg.Schema["egress"].Computed = false 34 return dsg 35 } 36 37 func resourceAwsDefaultSecurityGroupCreate(d *schema.ResourceData, meta interface{}) error { 38 conn := meta.(*AWSClient).ec2conn 39 securityGroupOpts := &ec2.DescribeSecurityGroupsInput{ 40 Filters: []*ec2.Filter{ 41 &ec2.Filter{ 42 Name: aws.String("group-name"), 43 Values: []*string{aws.String("default")}, 44 }, 45 }, 46 } 47 48 var vpcId string 49 if v, ok := d.GetOk("vpc_id"); ok { 50 vpcId = v.(string) 51 securityGroupOpts.Filters = append(securityGroupOpts.Filters, &ec2.Filter{ 52 Name: aws.String("vpc-id"), 53 Values: []*string{aws.String(vpcId)}, 54 }) 55 } 56 57 var err error 58 log.Printf("[DEBUG] Commandeer Default Security Group: %s", securityGroupOpts) 59 resp, err := conn.DescribeSecurityGroups(securityGroupOpts) 60 if err != nil { 61 return fmt.Errorf("Error creating Default Security Group: %s", err) 62 } 63 64 var g *ec2.SecurityGroup 65 if vpcId != "" { 66 // if vpcId contains a value, then we expect just a single Security Group 67 // returned, as default is a protected name for each VPC, and for each 68 // Region on EC2 Classic 69 if len(resp.SecurityGroups) != 1 { 70 return fmt.Errorf("[ERR] Error finding default security group; found (%d) groups: %s", len(resp.SecurityGroups), resp) 71 } 72 g = resp.SecurityGroups[0] 73 } else { 74 // we need to filter through any returned security groups for the group 75 // named "default", and does not belong to a VPC 76 for _, sg := range resp.SecurityGroups { 77 if sg.VpcId == nil && *sg.GroupName == "default" { 78 g = sg 79 } 80 } 81 } 82 83 if g == nil { 84 return fmt.Errorf("[ERR] Error finding default security group: no matching group found") 85 } 86 87 d.SetId(*g.GroupId) 88 89 log.Printf("[INFO] Default Security Group ID: %s", d.Id()) 90 91 if err := setTags(conn, d); err != nil { 92 return err 93 } 94 95 if err := revokeDefaultSecurityGroupRules(meta, g); err != nil { 96 return errwrap.Wrapf("{{err}}", err) 97 } 98 99 return resourceAwsSecurityGroupUpdate(d, meta) 100 } 101 102 func resourceAwsDefaultSecurityGroupDelete(d *schema.ResourceData, meta interface{}) error { 103 log.Printf("[WARN] Cannot destroy Default Security Group. Terraform will remove this resource from the state file, however resources may remain.") 104 d.SetId("") 105 return nil 106 } 107 108 func revokeDefaultSecurityGroupRules(meta interface{}, g *ec2.SecurityGroup) error { 109 conn := meta.(*AWSClient).ec2conn 110 111 log.Printf("[WARN] Removing all ingress and egress rules found on Default Security Group (%s)", *g.GroupId) 112 if len(g.IpPermissionsEgress) > 0 { 113 req := &ec2.RevokeSecurityGroupEgressInput{ 114 GroupId: g.GroupId, 115 IpPermissions: g.IpPermissionsEgress, 116 } 117 118 log.Printf("[DEBUG] Revoking default egress rules for Default Security Group for %s", *g.GroupId) 119 if _, err := conn.RevokeSecurityGroupEgress(req); err != nil { 120 return fmt.Errorf( 121 "Error revoking default egress rules for Default Security Group (%s): %s", 122 *g.GroupId, err) 123 } 124 } 125 if len(g.IpPermissions) > 0 { 126 // a limitation in EC2 Classic is that a call to RevokeSecurityGroupIngress 127 // cannot contain both the GroupName and the GroupId 128 for _, p := range g.IpPermissions { 129 for _, uigp := range p.UserIdGroupPairs { 130 if uigp.GroupId != nil && uigp.GroupName != nil { 131 uigp.GroupName = nil 132 } 133 } 134 } 135 req := &ec2.RevokeSecurityGroupIngressInput{ 136 GroupId: g.GroupId, 137 IpPermissions: g.IpPermissions, 138 } 139 140 log.Printf("[DEBUG] Revoking default ingress rules for Default Security Group for (%s): %s", *g.GroupId, req) 141 if _, err := conn.RevokeSecurityGroupIngress(req); err != nil { 142 return fmt.Errorf( 143 "Error revoking default ingress rules for Default Security Group (%s): %s", 144 *g.GroupId, err) 145 } 146 } 147 148 return nil 149 }