terraform/builtin/providers/aws/resource_aws_security_group...

484 lines
12 KiB
Go

package aws
import (
"fmt"
"reflect"
"testing"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/awsutil"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)
func TestIpPermissionIDHash(t *testing.T) {
simple := &ec2.IPPermission{
IPProtocol: aws.String("tcp"),
FromPort: aws.Long(int64(80)),
ToPort: aws.Long(int64(8000)),
IPRanges: []*ec2.IPRange{
&ec2.IPRange{
CIDRIP: aws.String("10.0.0.0/8"),
},
},
}
egress := &ec2.IPPermission{
IPProtocol: aws.String("tcp"),
FromPort: aws.Long(int64(80)),
ToPort: aws.Long(int64(8000)),
IPRanges: []*ec2.IPRange{
&ec2.IPRange{
CIDRIP: aws.String("10.0.0.0/8"),
},
},
}
egress_all := &ec2.IPPermission{
IPProtocol: aws.String("-1"),
IPRanges: []*ec2.IPRange{
&ec2.IPRange{
CIDRIP: aws.String("10.0.0.0/8"),
},
},
}
vpc_security_group_source := &ec2.IPPermission{
IPProtocol: aws.String("tcp"),
FromPort: aws.Long(int64(80)),
ToPort: aws.Long(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"),
},
},
}
security_group_source := &ec2.IPPermission{
IPProtocol: aws.String("tcp"),
FromPort: aws.Long(int64(80)),
ToPort: aws.Long(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"),
},
},
}
// hardcoded hashes, to detect future change
cases := []struct {
Input *ec2.IPPermission
Type string
Output string
}{
{simple, "ingress", "sg-82613597"},
{egress, "egress", "sg-363054720"},
{egress_all, "egress", "sg-2766285362"},
{vpc_security_group_source, "egress", "sg-2661404947"},
{security_group_source, "egress", "sg-1841245863"},
}
for _, tc := range cases {
actual := ipPermissionIDHash(tc.Type, tc.Input)
if actual != tc.Output {
t.Errorf("input: %s - %s\noutput: %s", tc.Type, awsutil.StringValue(tc.Input), actual)
}
}
}
func TestAccAWSSecurityGroupRule_Ingress(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))
}
return nil
}
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSSecurityGroupRuleDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccAWSSecurityGroupRuleIngressConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSSecurityGroupRuleExists("aws_security_group.web", &group),
testAccCheckAWSSecurityGroupRuleAttributes(&group, "ingress"),
resource.TestCheckResourceAttr(
"aws_security_group_rule.ingress_1", "from_port", "80"),
testRuleCount,
),
},
},
})
}
func TestAccAWSSecurityGroupRule_IngressClassic(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))
}
return nil
}
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSSecurityGroupRuleDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccAWSSecurityGroupRuleIngressClassicConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSSecurityGroupRuleExists("aws_security_group.web", &group),
testAccCheckAWSSecurityGroupRuleAttributes(&group, "ingress"),
resource.TestCheckResourceAttr(
"aws_security_group_rule.ingress_1", "from_port", "80"),
testRuleCount,
),
},
},
})
}
func TestAccAWSSecurityGroupRule_MultiIngress(t *testing.T) {
var group ec2.SecurityGroup
testMultiRuleCount := func(*terraform.State) error {
if len(group.IPPermissions) != 2 {
return fmt.Errorf("Wrong Security Group rule count, expected %d, got %d",
2, len(group.IPPermissions))
}
var rule *ec2.IPPermission
for _, r := range group.IPPermissions {
if *r.FromPort == int64(80) {
rule = r
}
}
if *rule.ToPort != int64(8000) {
return fmt.Errorf("Wrong Security Group port 2 setting, expected %d, got %d",
8000, int(*rule.ToPort))
}
return nil
}
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSSecurityGroupRuleDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccAWSSecurityGroupRuleConfigMultiIngress,
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSSecurityGroupRuleExists("aws_security_group.web", &group),
testMultiRuleCount,
),
},
},
})
}
func TestAccAWSSecurityGroupRule_Egress(t *testing.T) {
var group ec2.SecurityGroup
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSSecurityGroupRuleDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccAWSSecurityGroupRuleEgressConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSSecurityGroupRuleExists("aws_security_group.web", &group),
testAccCheckAWSSecurityGroupRuleAttributes(&group, "egress"),
),
},
},
})
}
func TestAccAWSSecurityGroupRule_SelfReference(t *testing.T) {
var group ec2.SecurityGroup
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSSecurityGroupRuleDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccAWSSecurityGroupRuleConfigSelfReference,
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSSecurityGroupRuleExists("aws_security_group.web", &group),
),
},
},
})
}
func testAccCheckAWSSecurityGroupRuleDestroy(s *terraform.State) error {
conn := testAccProvider.Meta().(*AWSClient).ec2conn
for _, rs := range s.RootModule().Resources {
if rs.Type != "aws_security_group" {
continue
}
// Retrieve our group
req := &ec2.DescribeSecurityGroupsInput{
GroupIDs: []*string{aws.String(rs.Primary.ID)},
}
resp, err := conn.DescribeSecurityGroups(req)
if err == nil {
if len(resp.SecurityGroups) > 0 && *resp.SecurityGroups[0].GroupID == rs.Primary.ID {
return fmt.Errorf("Security Group (%s) still exists.", rs.Primary.ID)
}
return nil
}
ec2err, ok := err.(awserr.Error)
if !ok {
return err
}
// Confirm error code is what we want
if ec2err.Code() != "InvalidGroup.NotFound" {
return err
}
}
return nil
}
func testAccCheckAWSSecurityGroupRuleExists(n string, group *ec2.SecurityGroup) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Not found: %s", n)
}
if rs.Primary.ID == "" {
return fmt.Errorf("No Security Group is set")
}
conn := testAccProvider.Meta().(*AWSClient).ec2conn
req := &ec2.DescribeSecurityGroupsInput{
GroupIDs: []*string{aws.String(rs.Primary.ID)},
}
resp, err := conn.DescribeSecurityGroups(req)
if err != nil {
return err
}
if len(resp.SecurityGroups) > 0 && *resp.SecurityGroups[0].GroupID == rs.Primary.ID {
*group = *resp.SecurityGroups[0]
return nil
}
return fmt.Errorf("Security Group not found")
}
}
func testAccCheckAWSSecurityGroupRuleAttributes(group *ec2.SecurityGroup, ruleType string) resource.TestCheckFunc {
return func(s *terraform.State) error {
p := &ec2.IPPermission{
FromPort: aws.Long(80),
ToPort: aws.Long(8000),
IPProtocol: aws.String("tcp"),
IPRanges: []*ec2.IPRange{&ec2.IPRange{CIDRIP: aws.String("10.0.0.0/8")}},
}
var rules []*ec2.IPPermission
if ruleType == "ingress" {
rules = group.IPPermissions
} else {
rules = group.IPPermissionsEgress
}
if len(rules) == 0 {
return fmt.Errorf("No IPPerms")
}
// Compare our ingress
if !reflect.DeepEqual(rules[0], p) {
return fmt.Errorf(
"Got:\n\n%#v\n\nExpected:\n\n%#v\n",
rules[0],
p)
}
return nil
}
}
const testAccAWSSecurityGroupRuleIngressConfig = `
resource "aws_security_group" "web" {
name = "terraform_acceptance_test_example"
description = "Used in the terraform acceptance tests"
tags {
Name = "tf-acc-test"
}
}
resource "aws_security_group_rule" "ingress_1" {
type = "ingress"
protocol = "tcp"
from_port = 80
to_port = 8000
cidr_blocks = ["10.0.0.0/8"]
security_group_id = "${aws_security_group.web.id}"
}
`
const testAccAWSSecurityGroupRuleIngressClassicConfig = `
provider "aws" {
region = "us-east-1"
}
resource "aws_security_group" "web" {
name = "terraform_acceptance_test_example"
description = "Used in the terraform acceptance tests"
tags {
Name = "tf-acc-test"
}
}
resource "aws_security_group_rule" "ingress_1" {
type = "ingress"
protocol = "tcp"
from_port = 80
to_port = 8000
cidr_blocks = ["10.0.0.0/8"]
security_group_id = "${aws_security_group.web.id}"
}
`
const testAccAWSSecurityGroupRuleEgressConfig = `
resource "aws_security_group" "web" {
name = "terraform_acceptance_test_example"
description = "Used in the terraform acceptance tests"
tags {
Name = "tf-acc-test"
}
}
resource "aws_security_group_rule" "egress_1" {
type = "egress"
protocol = "tcp"
from_port = 80
to_port = 8000
cidr_blocks = ["10.0.0.0/8"]
security_group_id = "${aws_security_group.web.id}"
}
`
const testAccAWSSecurityGroupRuleConfigMultiIngress = `
resource "aws_security_group" "web" {
name = "terraform_acceptance_test_example_2"
description = "Used in the terraform acceptance tests"
}
resource "aws_security_group" "worker" {
name = "terraform_acceptance_test_example_worker"
description = "Used in the terraform acceptance tests"
}
resource "aws_security_group_rule" "ingress_1" {
type = "ingress"
protocol = "tcp"
from_port = 22
to_port = 22
cidr_blocks = ["10.0.0.0/8"]
security_group_id = "${aws_security_group.web.id}"
}
resource "aws_security_group_rule" "ingress_2" {
type = "ingress"
protocol = "tcp"
from_port = 80
to_port = 8000
self = true
security_group_id = "${aws_security_group.web.id}"
}
`
// check for GH-1985 regression
const testAccAWSSecurityGroupRuleConfigSelfReference = `
provider "aws" {
region = "us-west-2"
}
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags {
Name = "sg-self-test"
}
}
resource "aws_security_group" "web" {
name = "main"
vpc_id = "${aws_vpc.main.id}"
tags {
Name = "sg-self-test"
}
}
resource "aws_security_group_rule" "self" {
type = "ingress"
protocol = "-1"
from_port = 0
to_port = 0
self = true
security_group_id = "${aws_security_group.web.id}"
}
`