github.com/terraform-modules-krish/terratest@v0.29.0/modules/aws/region.go (about) 1 package aws 2 3 import ( 4 "os" 5 6 "github.com/aws/aws-sdk-go/aws" 7 "github.com/aws/aws-sdk-go/service/ec2" 8 "github.com/terraform-modules-krish/terratest/modules/collections" 9 "github.com/terraform-modules-krish/terratest/modules/logger" 10 "github.com/terraform-modules-krish/terratest/modules/random" 11 "github.com/terraform-modules-krish/terratest/modules/testing" 12 ) 13 14 // You can set this environment variable to force Terratest to use a specific region rather than a random one. This is 15 // convenient when iterating locally. 16 const regionOverrideEnvVarName = "TERRATEST_REGION" 17 18 // AWS API calls typically require an AWS region. We typically require the user to set one explicitly, but in some 19 // cases, this doesn't make sense (e.g., for fetching the lsit of regions in an account), so for those cases, we use 20 // this region as a default. 21 const defaultRegion = "us-east-1" 22 23 // Reference for launch dates: https://aws.amazon.com/about-aws/global-infrastructure/ 24 var stableRegions = []string{ 25 "us-east-1", // Launched 2006 26 "us-east-2", // Launched 2016 27 "us-west-1", // Launched 2009 28 "us-west-2", // Launched 2011 29 "ca-central-1", // Launched 2016 30 "sa-east-1", // Launched 2011 31 "eu-west-1", // Launched 2007 32 "eu-west-2", // Launched 2016 33 "eu-west-3", // Launched 2017 34 "eu-central-1", // Launched 2014 35 "ap-southeast-1", // Launched 2010 36 "ap-southeast-2", // Launched 2012 37 "ap-northeast-1", // Launched 2011 38 "ap-northeast-2", // Launched 2016 39 "ap-south-1", // Launched 2016 40 } 41 42 // GetRandomStableRegion gets a randomly chosen AWS region that is considered stable. Like GetRandomRegion, you can 43 // further restrict the stable region list using approvedRegions and forbiddenRegions. We consider stable regions to be 44 // those that have been around for at least 1 year. 45 // Note that regions in the approvedRegions list that are not considered stable are ignored. 46 func GetRandomStableRegion(t testing.TestingT, approvedRegions []string, forbiddenRegions []string) string { 47 regionsToPickFrom := stableRegions 48 if len(approvedRegions) > 0 { 49 regionsToPickFrom = collections.ListIntersection(regionsToPickFrom, approvedRegions) 50 } 51 if len(forbiddenRegions) > 0 { 52 regionsToPickFrom = collections.ListSubtract(regionsToPickFrom, forbiddenRegions) 53 } 54 return GetRandomRegion(t, regionsToPickFrom, nil) 55 } 56 57 // GetRandomRegion gets a randomly chosen AWS region. If approvedRegions is not empty, this will be a region from the approvedRegions 58 // list; otherwise, this method will fetch the latest list of regions from the AWS APIs and pick one of those. If 59 // forbiddenRegions is not empty, this method will make sure the returned region is not in the forbiddenRegions list. 60 func GetRandomRegion(t testing.TestingT, approvedRegions []string, forbiddenRegions []string) string { 61 region, err := GetRandomRegionE(t, approvedRegions, forbiddenRegions) 62 if err != nil { 63 t.Fatal(err) 64 } 65 return region 66 } 67 68 // GetRandomRegionE gets a randomly chosen AWS region. If approvedRegions is not empty, this will be a region from the approvedRegions 69 // list; otherwise, this method will fetch the latest list of regions from the AWS APIs and pick one of those. If 70 // forbiddenRegions is not empty, this method will make sure the returned region is not in the forbiddenRegions list. 71 func GetRandomRegionE(t testing.TestingT, approvedRegions []string, forbiddenRegions []string) (string, error) { 72 regionFromEnvVar := os.Getenv(regionOverrideEnvVarName) 73 if regionFromEnvVar != "" { 74 logger.Logf(t, "Using AWS region %s from environment variable %s", regionFromEnvVar, regionOverrideEnvVarName) 75 return regionFromEnvVar, nil 76 } 77 78 regionsToPickFrom := approvedRegions 79 80 if len(regionsToPickFrom) == 0 { 81 allRegions, err := GetAllAwsRegionsE(t) 82 if err != nil { 83 return "", err 84 } 85 regionsToPickFrom = allRegions 86 } 87 88 regionsToPickFrom = collections.ListSubtract(regionsToPickFrom, forbiddenRegions) 89 region := random.RandomString(regionsToPickFrom) 90 91 logger.Logf(t, "Using region %s", region) 92 return region, nil 93 } 94 95 // GetAllAwsRegions gets the list of AWS regions available in this account. 96 func GetAllAwsRegions(t testing.TestingT) []string { 97 out, err := GetAllAwsRegionsE(t) 98 if err != nil { 99 t.Fatal(err) 100 } 101 return out 102 } 103 104 // GetAllAwsRegionsE gets the list of AWS regions available in this account. 105 func GetAllAwsRegionsE(t testing.TestingT) ([]string, error) { 106 logger.Log(t, "Looking up all AWS regions available in this account") 107 108 ec2Client, err := NewEc2ClientE(t, defaultRegion) 109 if err != nil { 110 return nil, err 111 } 112 113 out, err := ec2Client.DescribeRegions(&ec2.DescribeRegionsInput{}) 114 if err != nil { 115 return nil, err 116 } 117 118 regions := []string{} 119 for _, region := range out.Regions { 120 regions = append(regions, aws.StringValue(region.RegionName)) 121 } 122 123 return regions, nil 124 } 125 126 // GetAvailabilityZones gets the Availability Zones for a given AWS region. Note that for certain regions (e.g. us-east-1), different AWS 127 // accounts have access to different availability zones. 128 func GetAvailabilityZones(t testing.TestingT, region string) []string { 129 out, err := GetAvailabilityZonesE(t, region) 130 if err != nil { 131 t.Fatal(err) 132 } 133 return out 134 } 135 136 // GetAvailabilityZonesE gets the Availability Zones for a given AWS region. Note that for certain regions (e.g. us-east-1), different AWS 137 // accounts have access to different availability zones. 138 func GetAvailabilityZonesE(t testing.TestingT, region string) ([]string, error) { 139 logger.Logf(t, "Looking up all availability zones available in this account for region %s", region) 140 141 ec2Client, err := NewEc2ClientE(t, region) 142 if err != nil { 143 return nil, err 144 } 145 146 resp, err := ec2Client.DescribeAvailabilityZones(&ec2.DescribeAvailabilityZonesInput{}) 147 if err != nil { 148 return nil, err 149 } 150 151 var out []string 152 for _, availabilityZone := range resp.AvailabilityZones { 153 out = append(out, aws.StringValue(availabilityZone.ZoneName)) 154 } 155 156 return out, nil 157 }