provider/aws: Add support for IPv6 to aws_security_group_rule (#12645)
``` % make testacc TEST=./builtin/providers/aws TESTARGS='-run=TestAccAWSSecurityGroupRule_' ✹ ✭ ==> Checking that code complies with gofmt requirements... go generate $(go list ./... | grep -v /terraform/vendor/) 2017/03/13 15:40:39 Generated command/internal_plugin_list.go TF_ACC=1 go test ./builtin/providers/aws -v -run=TestAccAWSSecurityGroupRule_ -timeout 120m === RUN TestAccAWSSecurityGroupRule_Ingress_VPC --- PASS: TestAccAWSSecurityGroupRule_Ingress_VPC (53.36s) === RUN TestAccAWSSecurityGroupRule_Ingress_Protocol --- PASS: TestAccAWSSecurityGroupRule_Ingress_Protocol (85.22s) === RUN TestAccAWSSecurityGroupRule_Ingress_Ipv6 --- PASS: TestAccAWSSecurityGroupRule_Ingress_Ipv6 (87.55s) === RUN TestAccAWSSecurityGroupRule_Ingress_Classic --- PASS: TestAccAWSSecurityGroupRule_Ingress_Classic (50.58s) === RUN TestAccAWSSecurityGroupRule_MultiIngress --- PASS: TestAccAWSSecurityGroupRule_MultiIngress (47.98s) === RUN TestAccAWSSecurityGroupRule_Egress --- PASS: TestAccAWSSecurityGroupRule_Egress (50.48s) === RUN TestAccAWSSecurityGroupRule_SelfReference --- PASS: TestAccAWSSecurityGroupRule_SelfReference (82.45s) === RUN TestAccAWSSecurityGroupRule_ExpectInvalidTypeError --- PASS: TestAccAWSSecurityGroupRule_ExpectInvalidTypeError (0.01s) === RUN TestAccAWSSecurityGroupRule_PartialMatching_basic --- PASS: TestAccAWSSecurityGroupRule_PartialMatching_basic (95.55s) === RUN TestAccAWSSecurityGroupRule_PartialMatching_Source --- PASS: TestAccAWSSecurityGroupRule_PartialMatching_Source (95.65s) === RUN TestAccAWSSecurityGroupRule_Issue5310 --- PASS: TestAccAWSSecurityGroupRule_Issue5310 (45.91s) === RUN TestAccAWSSecurityGroupRule_Race --- PASS: TestAccAWSSecurityGroupRule_Race (697.79s) === RUN TestAccAWSSecurityGroupRule_SelfSource --- PASS: TestAccAWSSecurityGroupRule_SelfSource (96.19s) === RUN TestAccAWSSecurityGroupRule_PrefixListEgress --- PASS: TestAccAWSSecurityGroupRule_PrefixListEgress (97.51s) PASS ok github.com/hashicorp/terraform/builtin/providers/aws 1586.248s ```
This commit is contained in:
parent
9fe61d0f1e
commit
d87cc0721f
|
@ -61,6 +61,13 @@ func resourceAwsSecurityGroupRule() *schema.Resource {
|
|||
Elem: &schema.Schema{Type: schema.TypeString},
|
||||
},
|
||||
|
||||
"ipv6_cidr_blocks": {
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
ForceNew: true,
|
||||
Elem: &schema.Schema{Type: schema.TypeString},
|
||||
},
|
||||
|
||||
"prefix_list_ids": {
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
|
@ -400,6 +407,19 @@ func findRuleMatch(p *ec2.IpPermission, rules []*ec2.IpPermission, isVPC bool) *
|
|||
continue
|
||||
}
|
||||
|
||||
remaining = len(p.Ipv6Ranges)
|
||||
for _, ipv6 := range p.Ipv6Ranges {
|
||||
for _, ipv6ip := range r.Ipv6Ranges {
|
||||
if *ipv6.CidrIpv6 == *ipv6ip.CidrIpv6 {
|
||||
remaining--
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if remaining > 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
remaining = len(p.PrefixListIds)
|
||||
for _, pl := range p.PrefixListIds {
|
||||
for _, rpl := range r.PrefixListIds {
|
||||
|
@ -463,6 +483,18 @@ func ipPermissionIDHash(sg_id, ruleType string, ip *ec2.IpPermission) string {
|
|||
}
|
||||
}
|
||||
|
||||
if len(ip.Ipv6Ranges) > 0 {
|
||||
s := make([]string, len(ip.Ipv6Ranges))
|
||||
for i, r := range ip.Ipv6Ranges {
|
||||
s[i] = *r.CidrIpv6
|
||||
}
|
||||
sort.Strings(s)
|
||||
|
||||
for _, v := range s {
|
||||
buf.WriteString(fmt.Sprintf("%s-", v))
|
||||
}
|
||||
}
|
||||
|
||||
if len(ip.PrefixListIds) > 0 {
|
||||
s := make([]string, len(ip.PrefixListIds))
|
||||
for i, pl := range ip.PrefixListIds {
|
||||
|
@ -555,6 +587,18 @@ func expandIPPerm(d *schema.ResourceData, sg *ec2.SecurityGroup) (*ec2.IpPermiss
|
|||
}
|
||||
}
|
||||
|
||||
if raw, ok := d.GetOk("ipv6_cidr_blocks"); ok {
|
||||
list := raw.([]interface{})
|
||||
perm.Ipv6Ranges = make([]*ec2.Ipv6Range, len(list))
|
||||
for i, v := range list {
|
||||
cidrIP, ok := v.(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("empty element found in ipv6_cidr_blocks - consider using the compact function")
|
||||
}
|
||||
perm.Ipv6Ranges[i] = &ec2.Ipv6Range{CidrIpv6: aws.String(cidrIP)}
|
||||
}
|
||||
}
|
||||
|
||||
if raw, ok := d.GetOk("prefix_list_ids"); ok {
|
||||
list := raw.([]interface{})
|
||||
perm.PrefixListIds = make([]*ec2.PrefixListId, len(list))
|
||||
|
@ -584,6 +628,12 @@ func setFromIPPerm(d *schema.ResourceData, sg *ec2.SecurityGroup, rule *ec2.IpPe
|
|||
|
||||
d.Set("cidr_blocks", cb)
|
||||
|
||||
var ipv6 []string
|
||||
for _, ip := range rule.Ipv6Ranges {
|
||||
ipv6 = append(ipv6, *ip.CidrIpv6)
|
||||
}
|
||||
d.Set("ipv6_cidr_blocks", ipv6)
|
||||
|
||||
var pl []string
|
||||
for _, p := range rule.PrefixListIds {
|
||||
pl = append(pl, *p.PrefixListId)
|
||||
|
@ -603,15 +653,16 @@ func setFromIPPerm(d *schema.ResourceData, sg *ec2.SecurityGroup, rule *ec2.IpPe
|
|||
return nil
|
||||
}
|
||||
|
||||
// Validates that either 'cidr_blocks', 'self', or 'source_security_group_id' is set
|
||||
// Validates that either 'cidr_blocks', 'ipv6_cidr_blocks', 'self', or 'source_security_group_id' is set
|
||||
func validateAwsSecurityGroupRule(d *schema.ResourceData) error {
|
||||
_, blocksOk := d.GetOk("cidr_blocks")
|
||||
_, ipv6Ok := d.GetOk("ipv6_cidr_blocks")
|
||||
_, sourceOk := d.GetOk("source_security_group_id")
|
||||
_, selfOk := d.GetOk("self")
|
||||
_, prefixOk := d.GetOk("prefix_list_ids")
|
||||
if !blocksOk && !sourceOk && !selfOk && !prefixOk {
|
||||
if !blocksOk && !sourceOk && !selfOk && !prefixOk && !ipv6Ok {
|
||||
return fmt.Errorf(
|
||||
"One of ['cidr_blocks', 'self', 'source_security_group_id', 'prefix_list_ids'] must be set to create an AWS Security Group Rule")
|
||||
"One of ['cidr_blocks', 'ipv6_cidr_blocks', 'self', 'source_security_group_id', 'prefix_list_ids'] must be set to create an AWS Security Group Rule")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -52,15 +52,15 @@ func TestIpPermissionIDHash(t *testing.T) {
|
|||
FromPort: aws.Int64(int64(80)),
|
||||
ToPort: aws.Int64(int64(8000)),
|
||||
UserIdGroupPairs: []*ec2.UserIdGroupPair{
|
||||
&ec2.UserIdGroupPair{
|
||||
{
|
||||
UserId: aws.String("987654321"),
|
||||
GroupId: aws.String("sg-12345678"),
|
||||
},
|
||||
&ec2.UserIdGroupPair{
|
||||
{
|
||||
UserId: aws.String("123456789"),
|
||||
GroupId: aws.String("sg-987654321"),
|
||||
},
|
||||
&ec2.UserIdGroupPair{
|
||||
{
|
||||
UserId: aws.String("123456789"),
|
||||
GroupId: aws.String("sg-12345678"),
|
||||
},
|
||||
|
@ -72,15 +72,15 @@ func TestIpPermissionIDHash(t *testing.T) {
|
|||
FromPort: aws.Int64(int64(80)),
|
||||
ToPort: aws.Int64(int64(8000)),
|
||||
UserIdGroupPairs: []*ec2.UserIdGroupPair{
|
||||
&ec2.UserIdGroupPair{
|
||||
{
|
||||
UserId: aws.String("987654321"),
|
||||
GroupName: aws.String("my-security-group"),
|
||||
},
|
||||
&ec2.UserIdGroupPair{
|
||||
{
|
||||
UserId: aws.String("123456789"),
|
||||
GroupName: aws.String("my-security-group"),
|
||||
},
|
||||
&ec2.UserIdGroupPair{
|
||||
{
|
||||
UserId: aws.String("123456789"),
|
||||
GroupName: aws.String("my-other-security-group"),
|
||||
},
|
||||
|
@ -183,6 +183,46 @@ func TestAccAWSSecurityGroupRule_Ingress_Protocol(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestAccAWSSecurityGroupRule_Ingress_Ipv6(t *testing.T) {
|
||||
var group ec2.SecurityGroup
|
||||
|
||||
testRuleCount := func(*terraform.State) error {
|
||||
if len(group.IpPermissions) != 1 {
|
||||
return fmt.Errorf("Wrong Security Group rule count, expected %d, got %d",
|
||||
1, len(group.IpPermissions))
|
||||
}
|
||||
|
||||
rule := group.IpPermissions[0]
|
||||
if *rule.FromPort != int64(80) {
|
||||
return fmt.Errorf("Wrong Security Group port setting, expected %d, got %d",
|
||||
80, int(*rule.FromPort))
|
||||
}
|
||||
|
||||
ipv6Address := rule.Ipv6Ranges[0]
|
||||
if *ipv6Address.CidrIpv6 != "::/0" {
|
||||
return fmt.Errorf("Wrong Security Group IPv6 address, expected %s, got %s",
|
||||
"::/0", *ipv6Address.CidrIpv6)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckAWSSecurityGroupRuleDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccAWSSecurityGroupRuleIngress_ipv6Config,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckAWSSecurityGroupRuleExists("aws_security_group.web", &group),
|
||||
testRuleCount,
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccAWSSecurityGroupRule_Ingress_Classic(t *testing.T) {
|
||||
var group ec2.SecurityGroup
|
||||
rInt := acctest.RandInt()
|
||||
|
@ -376,7 +416,7 @@ func TestAccAWSSecurityGroupRule_PartialMatching_Source(t *testing.T) {
|
|||
ToPort: aws.Int64(80),
|
||||
IpProtocol: aws.String("tcp"),
|
||||
UserIdGroupPairs: []*ec2.UserIdGroupPair{
|
||||
&ec2.UserIdGroupPair{GroupId: nat.GroupId},
|
||||
{GroupId: nat.GroupId},
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -696,6 +736,34 @@ func testAccAWSSecurityGroupRuleIngressConfig(rInt int) string {
|
|||
}`, rInt)
|
||||
}
|
||||
|
||||
const testAccAWSSecurityGroupRuleIngress_ipv6Config = `
|
||||
resource "aws_vpc" "tftest" {
|
||||
cidr_block = "10.0.0.0/16"
|
||||
|
||||
tags {
|
||||
Name = "tf-testing"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_security_group" "web" {
|
||||
vpc_id = "${aws_vpc.tftest.id}"
|
||||
|
||||
tags {
|
||||
Name = "tf-acc-test"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "ingress_1" {
|
||||
type = "ingress"
|
||||
protocol = "6"
|
||||
from_port = 80
|
||||
to_port = 8000
|
||||
ipv6_cidr_blocks = ["::/0"]
|
||||
|
||||
security_group_id = "${aws_security_group.web.id}"
|
||||
}
|
||||
`
|
||||
|
||||
const testAccAWSSecurityGroupRuleIngress_protocolConfig = `
|
||||
resource "aws_vpc" "tftest" {
|
||||
cidr_block = "10.0.0.0/16"
|
||||
|
|
|
@ -42,6 +42,7 @@ The following arguments are supported:
|
|||
* `type` - (Required) The type of rule being created. Valid options are `ingress` (inbound)
|
||||
or `egress` (outbound).
|
||||
* `cidr_blocks` - (Optional) List of CIDR blocks. Cannot be specified with `source_security_group_id`.
|
||||
* `ipv6_cidr_blocks` - (Optional) List of IPv6 CIDR blocks.
|
||||
* `prefix_list_ids` - (Optional) List of prefix list IDs (for allowing access to VPC endpoints).
|
||||
Only valid with `egress`.
|
||||
* `from_port` - (Required) The start port (or ICMP type number if protocol is "icmp").
|
||||
|
|
Loading…
Reference in New Issue