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