github.com/mponton/terratest@v0.44.0/modules/aws/vpc_test.go (about)

     1  package aws
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/stretchr/testify/assert"
     7  	"github.com/stretchr/testify/require"
     8  
     9  	"github.com/aws/aws-sdk-go/aws"
    10  	"github.com/aws/aws-sdk-go/service/ec2"
    11  )
    12  
    13  func TestGetDefaultVpc(t *testing.T) {
    14  	t.Parallel()
    15  
    16  	region := GetRandomStableRegion(t, nil, nil)
    17  	vpc := GetDefaultVpc(t, region)
    18  
    19  	assert.NotEmpty(t, vpc.Name)
    20  	assert.True(t, len(vpc.Subnets) > 0)
    21  	assert.Regexp(t, "^vpc-[[:alnum:]]+$", vpc.Id)
    22  }
    23  
    24  func TestGetVpcById(t *testing.T) {
    25  	t.Parallel()
    26  
    27  	region := GetRandomStableRegion(t, nil, nil)
    28  	vpc := createVpc(t, region)
    29  	defer deleteVpc(t, *vpc.VpcId, region)
    30  
    31  	vpcTest := GetVpcById(t, *vpc.VpcId, region)
    32  	assert.Equal(t, *vpc.VpcId, vpcTest.Id)
    33  }
    34  
    35  func TestGetVpcsE(t *testing.T) {
    36  	t.Parallel()
    37  
    38  	region := GetRandomStableRegion(t, nil, nil)
    39  	azs := GetAvailabilityZones(t, region)
    40  
    41  	isDefaultFilterName := "isDefault"
    42  	isDefaultFilterValue := "true"
    43  
    44  	defaultVpcFilter := ec2.Filter{Name: &isDefaultFilterName, Values: []*string{&isDefaultFilterValue}}
    45  	vpcs, _ := GetVpcsE(t, []*ec2.Filter{&defaultVpcFilter}, region)
    46  
    47  	require.Equal(t, len(vpcs), 1)
    48  	assert.NotEmpty(t, vpcs[0].Name)
    49  
    50  	// the default VPC has by default one subnet per availability zone
    51  	// https://docs.aws.amazon.com/vpc/latest/userguide/default-vpc.html
    52  	assert.True(t, len(vpcs[0].Subnets) >= len(azs))
    53  }
    54  
    55  func TestGetFirstTwoOctets(t *testing.T) {
    56  	t.Parallel()
    57  
    58  	firstTwo := GetFirstTwoOctets("10.100.0.0/28")
    59  	if firstTwo != "10.100" {
    60  		t.Errorf("Received: %s, Expected: 10.100", firstTwo)
    61  	}
    62  }
    63  
    64  func TestIsPublicSubnet(t *testing.T) {
    65  	t.Parallel()
    66  
    67  	region := GetRandomStableRegion(t, nil, nil)
    68  	vpc := createVpc(t, region)
    69  	defer deleteVpc(t, *vpc.VpcId, region)
    70  
    71  	routeTable := createRouteTable(t, *vpc.VpcId, region)
    72  	subnet := createSubnet(t, *vpc.VpcId, *routeTable.RouteTableId, region)
    73  	assert.False(t, IsPublicSubnet(t, *subnet.SubnetId, region))
    74  
    75  	createPublicRoute(t, *vpc.VpcId, *routeTable.RouteTableId, region)
    76  	assert.True(t, IsPublicSubnet(t, *subnet.SubnetId, region))
    77  }
    78  
    79  func TestGetDefaultSubnetIDsForVpc(t *testing.T) {
    80  	t.Parallel()
    81  
    82  	region := GetRandomStableRegion(t, nil, nil)
    83  	defaultVpc := GetDefaultVpc(t, region)
    84  
    85  	defaultSubnetIDs := GetDefaultSubnetIDsForVpc(t, *defaultVpc)
    86  	assert.NotEmpty(t, defaultSubnetIDs)
    87  
    88  	availabilityZones := []string{}
    89  	for _, id := range defaultSubnetIDs {
    90  		// default subnets are by default public
    91  		// https://docs.aws.amazon.com/vpc/latest/userguide/default-vpc.html
    92  		assert.True(t, IsPublicSubnet(t, id, region))
    93  		for _, subnet := range defaultVpc.Subnets {
    94  			if id == subnet.Id {
    95  				availabilityZones = append(availabilityZones, subnet.AvailabilityZone)
    96  			}
    97  		}
    98  	}
    99  	// only one default subnet is allowed per AZ
   100  	uniqueAZs := map[string]bool{}
   101  	for _, az := range availabilityZones {
   102  		uniqueAZs[az] = true
   103  	}
   104  	assert.Equal(t, len(defaultSubnetIDs), len(uniqueAZs))
   105  }
   106  
   107  func TestGetTagsForVpc(t *testing.T) {
   108  	t.Parallel()
   109  
   110  	region := GetRandomStableRegion(t, nil, nil)
   111  	vpc := createVpc(t, region)
   112  	defer deleteVpc(t, *vpc.VpcId, region)
   113  
   114  	noTags := GetTagsForVpc(t, *vpc.VpcId, region)
   115  	assert.True(t, len(vpc.Tags) == 0)
   116  	assert.True(t, len(noTags) == 0)
   117  
   118  	testTags := make(map[string]string)
   119  	testTags["TagKey1"] = "TagValue1"
   120  	testTags["TagKey2"] = "TagValue2"
   121  
   122  	AddTagsToResource(t, region, *vpc.VpcId, testTags)
   123  	vpcWithTags := GetVpcById(t, *vpc.VpcId, region)
   124  	tags := GetTagsForVpc(t, *vpc.VpcId, region)
   125  
   126  	assert.True(t, len(vpcWithTags.Tags) == len(testTags))
   127  	assert.True(t, len(tags) == len(testTags))
   128  }
   129  
   130  func TestGetTagsForSubnet(t *testing.T) {
   131  	t.Parallel()
   132  
   133  	region := GetRandomStableRegion(t, nil, nil)
   134  	vpc := createVpc(t, region)
   135  	defer deleteVpc(t, *vpc.VpcId, region)
   136  
   137  	routeTable := createRouteTable(t, *vpc.VpcId, region)
   138  	subnet := createSubnet(t, *vpc.VpcId, *routeTable.RouteTableId, region)
   139  
   140  	noTags := GetTagsForSubnet(t, *subnet.SubnetId, region)
   141  	assert.True(t, len(subnet.Tags) == 0)
   142  	assert.True(t, len(noTags) == 0)
   143  
   144  	testTags := make(map[string]string)
   145  	testTags["TagKey1"] = "TagValue1"
   146  	testTags["TagKey2"] = "TagValue2"
   147  
   148  	AddTagsToResource(t, region, *subnet.SubnetId, testTags)
   149  
   150  	subnetWithTags := GetSubnetsForVpc(t, *vpc.VpcId, region)[0]
   151  	tags := GetTagsForSubnet(t, *subnet.SubnetId, region)
   152  
   153  	assert.True(t, len(subnetWithTags.Tags) == len(testTags))
   154  	assert.True(t, len(tags) == len(testTags))
   155  	assert.True(t, testTags["TagKey1"] == "TagValue1")
   156  	assert.True(t, testTags["TagKey2"] == "TagValue2")
   157  }
   158  
   159  func TestGetDefaultAzSubnets(t *testing.T) {
   160  	t.Parallel()
   161  
   162  	region := GetRandomStableRegion(t, nil, nil)
   163  	vpc := GetDefaultVpc(t, region)
   164  
   165  	// Note: cannot know exact list of default azs aheard of time, but we know that
   166  	//it must be greater than 0 for default vpc.
   167  	subnets := GetAzDefaultSubnetsForVpc(t, vpc.Id, region)
   168  	assert.NotZero(t, len(subnets))
   169  }
   170  
   171  func createPublicRoute(t *testing.T, vpcId string, routeTableId string, region string) {
   172  	ec2Client := NewEc2Client(t, region)
   173  
   174  	createIGWOut, igerr := ec2Client.CreateInternetGateway(&ec2.CreateInternetGatewayInput{})
   175  	require.NoError(t, igerr)
   176  
   177  	_, aigerr := ec2Client.AttachInternetGateway(&ec2.AttachInternetGatewayInput{
   178  		InternetGatewayId: createIGWOut.InternetGateway.InternetGatewayId,
   179  		VpcId:             aws.String(vpcId),
   180  	})
   181  	require.NoError(t, aigerr)
   182  
   183  	_, err := ec2Client.CreateRoute(&ec2.CreateRouteInput{
   184  		RouteTableId:         aws.String(routeTableId),
   185  		DestinationCidrBlock: aws.String("0.0.0.0/0"),
   186  		GatewayId:            createIGWOut.InternetGateway.InternetGatewayId,
   187  	})
   188  
   189  	require.NoError(t, err)
   190  }
   191  
   192  func createRouteTable(t *testing.T, vpcId string, region string) ec2.RouteTable {
   193  	ec2Client := NewEc2Client(t, region)
   194  
   195  	createRouteTableOutput, err := ec2Client.CreateRouteTable(&ec2.CreateRouteTableInput{
   196  		VpcId: aws.String(vpcId),
   197  	})
   198  
   199  	require.NoError(t, err)
   200  	return *createRouteTableOutput.RouteTable
   201  }
   202  
   203  func createSubnet(t *testing.T, vpcId string, routeTableId string, region string) ec2.Subnet {
   204  	ec2Client := NewEc2Client(t, region)
   205  
   206  	createSubnetOutput, err := ec2Client.CreateSubnet(&ec2.CreateSubnetInput{
   207  		CidrBlock: aws.String("10.10.1.0/24"),
   208  		VpcId:     aws.String(vpcId),
   209  	})
   210  	require.NoError(t, err)
   211  
   212  	_, err = ec2Client.AssociateRouteTable(&ec2.AssociateRouteTableInput{
   213  		RouteTableId: aws.String(routeTableId),
   214  		SubnetId:     aws.String(*createSubnetOutput.Subnet.SubnetId),
   215  	})
   216  	require.NoError(t, err)
   217  
   218  	return *createSubnetOutput.Subnet
   219  }
   220  
   221  func createVpc(t *testing.T, region string) ec2.Vpc {
   222  	ec2Client := NewEc2Client(t, region)
   223  
   224  	createVpcOutput, err := ec2Client.CreateVpc(&ec2.CreateVpcInput{
   225  		CidrBlock: aws.String("10.10.0.0/16"),
   226  	})
   227  
   228  	require.NoError(t, err)
   229  	return *createVpcOutput.Vpc
   230  }
   231  
   232  func deleteRouteTables(t *testing.T, vpcId string, region string) {
   233  	ec2Client := NewEc2Client(t, region)
   234  
   235  	vpcIDFilterName := "vpc-id"
   236  	vpcIDFilter := ec2.Filter{Name: &vpcIDFilterName, Values: []*string{&vpcId}}
   237  
   238  	// "You can't delete the main route table."
   239  	mainRTFilterName := "association.main"
   240  	mainRTFilterValue := "false"
   241  	notMainRTFilter := ec2.Filter{Name: &mainRTFilterName, Values: []*string{&mainRTFilterValue}}
   242  
   243  	filters := []*ec2.Filter{&vpcIDFilter, &notMainRTFilter}
   244  
   245  	rtOutput, err := ec2Client.DescribeRouteTables(&ec2.DescribeRouteTablesInput{Filters: filters})
   246  	require.NoError(t, err)
   247  
   248  	for _, rt := range rtOutput.RouteTables {
   249  
   250  		// "You must disassociate the route table from any subnets before you can delete it."
   251  		for _, assoc := range rt.Associations {
   252  			_, disassocErr := ec2Client.DisassociateRouteTable(&ec2.DisassociateRouteTableInput{
   253  				AssociationId: assoc.RouteTableAssociationId,
   254  			})
   255  			require.NoError(t, disassocErr)
   256  		}
   257  
   258  		_, err := ec2Client.DeleteRouteTable(&ec2.DeleteRouteTableInput{
   259  			RouteTableId: rt.RouteTableId,
   260  		})
   261  		require.NoError(t, err)
   262  	}
   263  }
   264  
   265  func deleteSubnets(t *testing.T, vpcId string, region string) {
   266  	ec2Client := NewEc2Client(t, region)
   267  	vpcIDFilterName := "vpc-id"
   268  	vpcIDFilter := ec2.Filter{Name: &vpcIDFilterName, Values: []*string{&vpcId}}
   269  
   270  	subnetsOutput, err := ec2Client.DescribeSubnets(&ec2.DescribeSubnetsInput{Filters: []*ec2.Filter{&vpcIDFilter}})
   271  	require.NoError(t, err)
   272  
   273  	for _, subnet := range subnetsOutput.Subnets {
   274  		_, err := ec2Client.DeleteSubnet(&ec2.DeleteSubnetInput{
   275  			SubnetId: subnet.SubnetId,
   276  		})
   277  		require.NoError(t, err)
   278  	}
   279  }
   280  
   281  func deleteInternetGateways(t *testing.T, vpcId string, region string) {
   282  	ec2Client := NewEc2Client(t, region)
   283  	vpcIDFilterName := "attachment.vpc-id"
   284  	vpcIDFilter := ec2.Filter{Name: &vpcIDFilterName, Values: []*string{&vpcId}}
   285  
   286  	igwOutput, err := ec2Client.DescribeInternetGateways(&ec2.DescribeInternetGatewaysInput{Filters: []*ec2.Filter{&vpcIDFilter}})
   287  	require.NoError(t, err)
   288  
   289  	for _, igw := range igwOutput.InternetGateways {
   290  
   291  		_, detachErr := ec2Client.DetachInternetGateway(&ec2.DetachInternetGatewayInput{
   292  			InternetGatewayId: igw.InternetGatewayId,
   293  			VpcId:             aws.String(vpcId),
   294  		})
   295  		require.NoError(t, detachErr)
   296  
   297  		_, err := ec2Client.DeleteInternetGateway(&ec2.DeleteInternetGatewayInput{
   298  			InternetGatewayId: igw.InternetGatewayId,
   299  		})
   300  		require.NoError(t, err)
   301  	}
   302  }
   303  
   304  func deleteVpc(t *testing.T, vpcId string, region string) {
   305  	ec2Client := NewEc2Client(t, region)
   306  
   307  	deleteRouteTables(t, vpcId, region)
   308  	deleteSubnets(t, vpcId, region)
   309  	deleteInternetGateways(t, vpcId, region)
   310  
   311  	_, err := ec2Client.DeleteVpc(&ec2.DeleteVpcInput{
   312  		VpcId: aws.String(vpcId),
   313  	})
   314  	require.NoError(t, err)
   315  }