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, ¬MainRTFilter} 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 }