github.com/alexissmirnov/terraform@v0.4.3-0.20150423153700-1ef9731a2f14/builtin/providers/aws/resource_aws_network_acl_test.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  
     7  	"github.com/awslabs/aws-sdk-go/aws"
     8  	"github.com/awslabs/aws-sdk-go/service/ec2"
     9  	"github.com/hashicorp/terraform/helper/resource"
    10  	"github.com/hashicorp/terraform/terraform"
    11  )
    12  
    13  func TestAccAWSNetworkAcl_EgressAndIngressRules(t *testing.T) {
    14  	var networkAcl ec2.NetworkACL
    15  
    16  	resource.Test(t, resource.TestCase{
    17  		PreCheck:     func() { testAccPreCheck(t) },
    18  		Providers:    testAccProviders,
    19  		CheckDestroy: testAccCheckAWSNetworkAclDestroy,
    20  		Steps: []resource.TestStep{
    21  			resource.TestStep{
    22  				Config: testAccAWSNetworkAclEgressNIngressConfig,
    23  				Check: resource.ComposeTestCheckFunc(
    24  					testAccCheckAWSNetworkAclExists("aws_network_acl.bar", &networkAcl),
    25  					resource.TestCheckResourceAttr(
    26  						"aws_network_acl.bar", "ingress.3409203205.protocol", "tcp"),
    27  					resource.TestCheckResourceAttr(
    28  						"aws_network_acl.bar", "ingress.3409203205.rule_no", "1"),
    29  					resource.TestCheckResourceAttr(
    30  						"aws_network_acl.bar", "ingress.3409203205.from_port", "80"),
    31  					resource.TestCheckResourceAttr(
    32  						"aws_network_acl.bar", "ingress.3409203205.to_port", "80"),
    33  					resource.TestCheckResourceAttr(
    34  						"aws_network_acl.bar", "ingress.3409203205.action", "allow"),
    35  					resource.TestCheckResourceAttr(
    36  						"aws_network_acl.bar", "ingress.3409203205.cidr_block", "10.3.10.3/18"),
    37  					resource.TestCheckResourceAttr(
    38  						"aws_network_acl.bar", "egress.2579689292.protocol", "tcp"),
    39  					resource.TestCheckResourceAttr(
    40  						"aws_network_acl.bar", "egress.2579689292.rule_no", "2"),
    41  					resource.TestCheckResourceAttr(
    42  						"aws_network_acl.bar", "egress.2579689292.from_port", "443"),
    43  					resource.TestCheckResourceAttr(
    44  						"aws_network_acl.bar", "egress.2579689292.to_port", "443"),
    45  					resource.TestCheckResourceAttr(
    46  						"aws_network_acl.bar", "egress.2579689292.cidr_block", "10.3.2.3/18"),
    47  					resource.TestCheckResourceAttr(
    48  						"aws_network_acl.bar", "egress.2579689292.action", "allow"),
    49  				),
    50  			},
    51  		},
    52  	})
    53  }
    54  
    55  func TestAccAWSNetworkAcl_OnlyIngressRules(t *testing.T) {
    56  	var networkAcl ec2.NetworkACL
    57  
    58  	resource.Test(t, resource.TestCase{
    59  		PreCheck:     func() { testAccPreCheck(t) },
    60  		Providers:    testAccProviders,
    61  		CheckDestroy: testAccCheckAWSNetworkAclDestroy,
    62  		Steps: []resource.TestStep{
    63  			resource.TestStep{
    64  				Config: testAccAWSNetworkAclIngressConfig,
    65  				Check: resource.ComposeTestCheckFunc(
    66  					testAccCheckAWSNetworkAclExists("aws_network_acl.foos", &networkAcl),
    67  					// testAccCheckSubnetAssociation("aws_network_acl.foos", "aws_subnet.blob"),
    68  					resource.TestCheckResourceAttr(
    69  						"aws_network_acl.foos", "ingress.2750166237.protocol", "tcp"),
    70  					resource.TestCheckResourceAttr(
    71  						"aws_network_acl.foos", "ingress.2750166237.rule_no", "2"),
    72  					resource.TestCheckResourceAttr(
    73  						"aws_network_acl.foos", "ingress.2750166237.from_port", "443"),
    74  					resource.TestCheckResourceAttr(
    75  						"aws_network_acl.foos", "ingress.2750166237.to_port", "443"),
    76  					resource.TestCheckResourceAttr(
    77  						"aws_network_acl.foos", "ingress.2750166237.action", "deny"),
    78  					resource.TestCheckResourceAttr(
    79  						"aws_network_acl.foos", "ingress.2750166237.cidr_block", "10.2.2.3/18"),
    80  				),
    81  			},
    82  		},
    83  	})
    84  }
    85  
    86  func TestAccAWSNetworkAcl_OnlyIngressRulesChange(t *testing.T) {
    87  	var networkAcl ec2.NetworkACL
    88  
    89  	resource.Test(t, resource.TestCase{
    90  		PreCheck:     func() { testAccPreCheck(t) },
    91  		Providers:    testAccProviders,
    92  		CheckDestroy: testAccCheckAWSNetworkAclDestroy,
    93  		Steps: []resource.TestStep{
    94  			resource.TestStep{
    95  				Config: testAccAWSNetworkAclIngressConfig,
    96  				Check: resource.ComposeTestCheckFunc(
    97  					testAccCheckAWSNetworkAclExists("aws_network_acl.foos", &networkAcl),
    98  					testIngressRuleLength(&networkAcl, 2),
    99  					resource.TestCheckResourceAttr(
   100  						"aws_network_acl.foos", "ingress.37211640.protocol", "tcp"),
   101  					resource.TestCheckResourceAttr(
   102  						"aws_network_acl.foos", "ingress.37211640.rule_no", "1"),
   103  					resource.TestCheckResourceAttr(
   104  						"aws_network_acl.foos", "ingress.37211640.from_port", "0"),
   105  					resource.TestCheckResourceAttr(
   106  						"aws_network_acl.foos", "ingress.37211640.to_port", "22"),
   107  					resource.TestCheckResourceAttr(
   108  						"aws_network_acl.foos", "ingress.37211640.action", "deny"),
   109  					resource.TestCheckResourceAttr(
   110  						"aws_network_acl.foos", "ingress.37211640.cidr_block", "10.2.2.3/18"),
   111  					resource.TestCheckResourceAttr(
   112  						"aws_network_acl.foos", "ingress.2750166237.from_port", "443"),
   113  					resource.TestCheckResourceAttr(
   114  						"aws_network_acl.foos", "ingress.2750166237.rule_no", "2"),
   115  				),
   116  			},
   117  			resource.TestStep{
   118  				Config: testAccAWSNetworkAclIngressConfigChange,
   119  				Check: resource.ComposeTestCheckFunc(
   120  					testAccCheckAWSNetworkAclExists("aws_network_acl.foos", &networkAcl),
   121  					testIngressRuleLength(&networkAcl, 1),
   122  					resource.TestCheckResourceAttr(
   123  						"aws_network_acl.foos", "ingress.37211640.protocol", "tcp"),
   124  					resource.TestCheckResourceAttr(
   125  						"aws_network_acl.foos", "ingress.37211640.rule_no", "1"),
   126  					resource.TestCheckResourceAttr(
   127  						"aws_network_acl.foos", "ingress.37211640.from_port", "0"),
   128  					resource.TestCheckResourceAttr(
   129  						"aws_network_acl.foos", "ingress.37211640.to_port", "22"),
   130  					resource.TestCheckResourceAttr(
   131  						"aws_network_acl.foos", "ingress.37211640.action", "deny"),
   132  					resource.TestCheckResourceAttr(
   133  						"aws_network_acl.foos", "ingress.37211640.cidr_block", "10.2.2.3/18"),
   134  				),
   135  			},
   136  		},
   137  	})
   138  }
   139  
   140  func TestAccAWSNetworkAcl_OnlyEgressRules(t *testing.T) {
   141  	var networkAcl ec2.NetworkACL
   142  
   143  	resource.Test(t, resource.TestCase{
   144  		PreCheck:     func() { testAccPreCheck(t) },
   145  		Providers:    testAccProviders,
   146  		CheckDestroy: testAccCheckAWSNetworkAclDestroy,
   147  		Steps: []resource.TestStep{
   148  			resource.TestStep{
   149  				Config: testAccAWSNetworkAclEgressConfig,
   150  				Check: resource.ComposeTestCheckFunc(
   151  					testAccCheckAWSNetworkAclExists("aws_network_acl.bond", &networkAcl),
   152  					testAccCheckTagsSDK(&networkAcl.Tags, "foo", "bar"),
   153  				),
   154  			},
   155  		},
   156  	})
   157  }
   158  
   159  func TestAccAWSNetworkAcl_SubnetChange(t *testing.T) {
   160  
   161  	resource.Test(t, resource.TestCase{
   162  		PreCheck:     func() { testAccPreCheck(t) },
   163  		Providers:    testAccProviders,
   164  		CheckDestroy: testAccCheckAWSNetworkAclDestroy,
   165  		Steps: []resource.TestStep{
   166  			resource.TestStep{
   167  				Config: testAccAWSNetworkAclSubnetConfig,
   168  				Check: resource.ComposeTestCheckFunc(
   169  					testAccCheckSubnetIsAssociatedWithAcl("aws_network_acl.bar", "aws_subnet.old"),
   170  				),
   171  			},
   172  			resource.TestStep{
   173  				Config: testAccAWSNetworkAclSubnetConfigChange,
   174  				Check: resource.ComposeTestCheckFunc(
   175  					testAccCheckSubnetIsNotAssociatedWithAcl("aws_network_acl.bar", "aws_subnet.old"),
   176  					testAccCheckSubnetIsAssociatedWithAcl("aws_network_acl.bar", "aws_subnet.new"),
   177  				),
   178  			},
   179  		},
   180  	})
   181  
   182  }
   183  
   184  func testAccCheckAWSNetworkAclDestroy(s *terraform.State) error {
   185  	conn := testAccProvider.Meta().(*AWSClient).ec2conn
   186  
   187  	for _, rs := range s.RootModule().Resources {
   188  		if rs.Type != "aws_network" {
   189  			continue
   190  		}
   191  
   192  		// Retrieve the network acl
   193  		resp, err := conn.DescribeNetworkACLs(&ec2.DescribeNetworkACLsInput{
   194  			NetworkACLIDs: []*string{aws.String(rs.Primary.ID)},
   195  		})
   196  		if err == nil {
   197  			if len(resp.NetworkACLs) > 0 && *resp.NetworkACLs[0].NetworkACLID == rs.Primary.ID {
   198  				return fmt.Errorf("Network Acl (%s) still exists.", rs.Primary.ID)
   199  			}
   200  
   201  			return nil
   202  		}
   203  
   204  		ec2err, ok := err.(aws.APIError)
   205  		if !ok {
   206  			return err
   207  		}
   208  		// Confirm error code is what we want
   209  		if ec2err.Code != "InvalidNetworkAclID.NotFound" {
   210  			return err
   211  		}
   212  	}
   213  
   214  	return nil
   215  }
   216  
   217  func testAccCheckAWSNetworkAclExists(n string, networkAcl *ec2.NetworkACL) resource.TestCheckFunc {
   218  	return func(s *terraform.State) error {
   219  		rs, ok := s.RootModule().Resources[n]
   220  		if !ok {
   221  			return fmt.Errorf("Not found: %s", n)
   222  		}
   223  
   224  		if rs.Primary.ID == "" {
   225  			return fmt.Errorf("No Security Group is set")
   226  		}
   227  		conn := testAccProvider.Meta().(*AWSClient).ec2conn
   228  
   229  		resp, err := conn.DescribeNetworkACLs(&ec2.DescribeNetworkACLsInput{
   230  			NetworkACLIDs: []*string{aws.String(rs.Primary.ID)},
   231  		})
   232  		if err != nil {
   233  			return err
   234  		}
   235  
   236  		if len(resp.NetworkACLs) > 0 && *resp.NetworkACLs[0].NetworkACLID == rs.Primary.ID {
   237  			*networkAcl = *resp.NetworkACLs[0]
   238  			return nil
   239  		}
   240  
   241  		return fmt.Errorf("Network Acls not found")
   242  	}
   243  }
   244  
   245  func testIngressRuleLength(networkAcl *ec2.NetworkACL, length int) resource.TestCheckFunc {
   246  	return func(s *terraform.State) error {
   247  		var ingressEntries []*ec2.NetworkACLEntry
   248  		for _, e := range networkAcl.Entries {
   249  			if *e.Egress == false {
   250  				ingressEntries = append(ingressEntries, e)
   251  			}
   252  		}
   253  		// There is always a default rule (ALL Traffic ... DENY)
   254  		// so we have to increase the lenght by 1
   255  		if len(ingressEntries) != length+1 {
   256  			return fmt.Errorf("Invalid number of ingress entries found; count = %d", len(ingressEntries))
   257  		}
   258  		return nil
   259  	}
   260  }
   261  
   262  func testAccCheckSubnetIsAssociatedWithAcl(acl string, sub string) resource.TestCheckFunc {
   263  	return func(s *terraform.State) error {
   264  		networkAcl := s.RootModule().Resources[acl]
   265  		subnet := s.RootModule().Resources[sub]
   266  
   267  		conn := testAccProvider.Meta().(*AWSClient).ec2conn
   268  		resp, err := conn.DescribeNetworkACLs(&ec2.DescribeNetworkACLsInput{
   269  			NetworkACLIDs: []*string{aws.String(networkAcl.Primary.ID)},
   270  			Filters: []*ec2.Filter{
   271  				&ec2.Filter{
   272  					Name:   aws.String("association.subnet-id"),
   273  					Values: []*string{aws.String(subnet.Primary.ID)},
   274  				},
   275  			},
   276  		})
   277  		if err != nil {
   278  			return err
   279  		}
   280  		if len(resp.NetworkACLs) > 0 {
   281  			return nil
   282  		}
   283  
   284  		// r, _ := conn.NetworkACLs([]string{}, ec2.NewFilter())
   285  		// fmt.Printf("\n\nall acls\n %#v\n\n", r.NetworkAcls)
   286  		// conn.NetworkAcls([]string{}, filter)
   287  
   288  		return fmt.Errorf("Network Acl %s is not associated with subnet %s", acl, sub)
   289  	}
   290  }
   291  
   292  func testAccCheckSubnetIsNotAssociatedWithAcl(acl string, subnet string) resource.TestCheckFunc {
   293  	return func(s *terraform.State) error {
   294  		networkAcl := s.RootModule().Resources[acl]
   295  		subnet := s.RootModule().Resources[subnet]
   296  
   297  		conn := testAccProvider.Meta().(*AWSClient).ec2conn
   298  		resp, err := conn.DescribeNetworkACLs(&ec2.DescribeNetworkACLsInput{
   299  			NetworkACLIDs: []*string{aws.String(networkAcl.Primary.ID)},
   300  			Filters: []*ec2.Filter{
   301  				&ec2.Filter{
   302  					Name:   aws.String("association.subnet-id"),
   303  					Values: []*string{aws.String(subnet.Primary.ID)},
   304  				},
   305  			},
   306  		})
   307  
   308  		if err != nil {
   309  			return err
   310  		}
   311  		if len(resp.NetworkACLs) > 0 {
   312  			return fmt.Errorf("Network Acl %s is still associated with subnet %s", acl, subnet)
   313  		}
   314  		return nil
   315  	}
   316  }
   317  
   318  const testAccAWSNetworkAclIngressConfig = `
   319  resource "aws_vpc" "foo" {
   320  	cidr_block = "10.1.0.0/16"
   321  }
   322  resource "aws_subnet" "blob" {
   323  	cidr_block = "10.1.1.0/24"
   324  	vpc_id = "${aws_vpc.foo.id}"
   325  	map_public_ip_on_launch = true
   326  }
   327  resource "aws_network_acl" "foos" {
   328  	vpc_id = "${aws_vpc.foo.id}"
   329  	ingress = {
   330  		protocol = "tcp"
   331  		rule_no = 1
   332  		action = "deny"
   333  		cidr_block =  "10.2.2.3/18"
   334  		from_port = 0
   335  		to_port = 22
   336  	}
   337  	ingress = {
   338  		protocol = "tcp"
   339  		rule_no = 2
   340  		action = "deny"
   341  		cidr_block =  "10.2.2.3/18"
   342  		from_port = 443
   343  		to_port = 443
   344  	}
   345  	subnet_id = "${aws_subnet.blob.id}"
   346  }
   347  `
   348  const testAccAWSNetworkAclIngressConfigChange = `
   349  resource "aws_vpc" "foo" {
   350  	cidr_block = "10.1.0.0/16"
   351  }
   352  resource "aws_subnet" "blob" {
   353  	cidr_block = "10.1.1.0/24"
   354  	vpc_id = "${aws_vpc.foo.id}"
   355  	map_public_ip_on_launch = true
   356  }
   357  resource "aws_network_acl" "foos" {
   358  	vpc_id = "${aws_vpc.foo.id}"
   359  	ingress = {
   360  		protocol = "tcp"
   361  		rule_no = 1
   362  		action = "deny"
   363  		cidr_block =  "10.2.2.3/18"
   364  		from_port = 0
   365  		to_port = 22
   366  	}
   367  	subnet_id = "${aws_subnet.blob.id}"
   368  }
   369  `
   370  
   371  const testAccAWSNetworkAclEgressConfig = `
   372  resource "aws_vpc" "foo" {
   373  	cidr_block = "10.2.0.0/16"
   374  }
   375  resource "aws_subnet" "blob" {
   376  	cidr_block = "10.2.0.0/24"
   377  	vpc_id = "${aws_vpc.foo.id}"
   378  	map_public_ip_on_launch = true
   379  }
   380  resource "aws_network_acl" "bond" {
   381  	vpc_id = "${aws_vpc.foo.id}"
   382  	egress = {
   383  		protocol = "tcp"
   384  		rule_no = 2
   385  		action = "allow"
   386  		cidr_block =  "10.2.2.3/18"
   387  		from_port = 443
   388  		to_port = 443
   389  	}
   390  
   391  	egress = {
   392  		protocol = "tcp"
   393  		rule_no = 1
   394  		action = "allow"
   395  		cidr_block =  "10.2.10.3/18"
   396  		from_port = 80
   397  		to_port = 80
   398  	}
   399  
   400  	egress = {
   401  		protocol = "tcp"
   402  		rule_no = 3
   403  		action = "allow"
   404  		cidr_block =  "10.2.10.3/18"
   405  		from_port = 22
   406  		to_port = 22
   407  	}
   408  
   409  	tags {
   410  		foo = "bar"
   411  	}
   412  }
   413  `
   414  
   415  const testAccAWSNetworkAclEgressNIngressConfig = `
   416  resource "aws_vpc" "foo" {
   417  	cidr_block = "10.3.0.0/16"
   418  }
   419  resource "aws_subnet" "blob" {
   420  	cidr_block = "10.3.0.0/24"
   421  	vpc_id = "${aws_vpc.foo.id}"
   422  	map_public_ip_on_launch = true
   423  }
   424  resource "aws_network_acl" "bar" {
   425  	vpc_id = "${aws_vpc.foo.id}"
   426  	egress = {
   427  		protocol = "tcp"
   428  		rule_no = 2
   429  		action = "allow"
   430  		cidr_block =  "10.3.2.3/18"
   431  		from_port = 443
   432  		to_port = 443
   433  	}
   434  
   435  	ingress = {
   436  		protocol = "tcp"
   437  		rule_no = 1
   438  		action = "allow"
   439  		cidr_block =  "10.3.10.3/18"
   440  		from_port = 80
   441  		to_port = 80
   442  	}
   443  }
   444  `
   445  const testAccAWSNetworkAclSubnetConfig = `
   446  resource "aws_vpc" "foo" {
   447  	cidr_block = "10.1.0.0/16"
   448  }
   449  resource "aws_subnet" "old" {
   450  	cidr_block = "10.1.111.0/24"
   451  	vpc_id = "${aws_vpc.foo.id}"
   452  	map_public_ip_on_launch = true
   453  }
   454  resource "aws_subnet" "new" {
   455  	cidr_block = "10.1.1.0/24"
   456  	vpc_id = "${aws_vpc.foo.id}"
   457  	map_public_ip_on_launch = true
   458  }
   459  resource "aws_network_acl" "roll" {
   460  	vpc_id = "${aws_vpc.foo.id}"
   461  	subnet_id = "${aws_subnet.new.id}"
   462  }
   463  resource "aws_network_acl" "bar" {
   464  	vpc_id = "${aws_vpc.foo.id}"
   465  	subnet_id = "${aws_subnet.old.id}"
   466  }
   467  `
   468  
   469  const testAccAWSNetworkAclSubnetConfigChange = `
   470  resource "aws_vpc" "foo" {
   471  	cidr_block = "10.1.0.0/16"
   472  }
   473  resource "aws_subnet" "old" {
   474  	cidr_block = "10.1.111.0/24"
   475  	vpc_id = "${aws_vpc.foo.id}"
   476  	map_public_ip_on_launch = true
   477  }
   478  resource "aws_subnet" "new" {
   479  	cidr_block = "10.1.1.0/24"
   480  	vpc_id = "${aws_vpc.foo.id}"
   481  	map_public_ip_on_launch = true
   482  }
   483  resource "aws_network_acl" "bar" {
   484  	vpc_id = "${aws_vpc.foo.id}"
   485  	subnet_id = "${aws_subnet.new.id}"
   486  }
   487  `