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