github.com/GoogleCloudPlatform/terraformer@v0.8.18/providers/aws/aws_provider.go (about) 1 // Copyright 2018 The Terraformer Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package aws 16 17 import ( 18 "os" 19 "strconv" 20 21 "github.com/GoogleCloudPlatform/terraformer/terraformutils" 22 "github.com/pkg/errors" 23 "github.com/zclconf/go-cty/cty" 24 ) 25 26 type AWSProvider struct { //nolint 27 terraformutils.Provider 28 region string 29 profile string 30 } 31 32 const GlobalRegion = "aws-global" 33 const MainRegionPublicPartition = "us-east-1" 34 const NoRegion = "" 35 36 // SupportedGlobalResources should be bound to a default region. AWS doesn't specify in which region default services are 37 // placed (see https://docs.aws.amazon.com/general/latest/gr/rande.html), so we shouldn't assume any region as well 38 // 39 // AWS WAF V2 if added, should not be included in this list since it is a composition of regional and global resources. 40 var SupportedGlobalResources = []string{ 41 "budgets", 42 "cloudfront", 43 "ecrpublic", 44 "iam", 45 "organization", 46 "route53", 47 "waf", 48 } 49 50 func (p AWSProvider) GetResourceConnections() map[string]map[string][]string { 51 return map[string]map[string][]string{ 52 "alb": { 53 "sg": []string{"security_groups", "id"}, 54 "subnet": []string{"subnets", "id"}, 55 "alb": []string{ 56 "load_balancer_arn", "id", 57 "listener_arn", "id", 58 // TF ALB TG attachment logic doesn't work well with references (doesn't interpolate) 59 }, 60 }, 61 "auto_scaling": { 62 "sg": []string{"security_groups", "id"}, 63 "subnet": []string{"vpc_zone_identifier", "id"}, 64 }, 65 "ec2_instance": { 66 "sg": []string{"vpc_security_group_ids", "id"}, 67 "subnet": []string{"subnet_id", "id"}, 68 "ebs": []string{"ebs_block_device", "id"}, 69 }, 70 "elasticache": { 71 "vpc": []string{"vpc_id", "id"}, 72 "subnet": []string{"subnet_ids", "id"}, 73 "sg": []string{"security_group_ids", "id"}, 74 }, 75 "ebs": { 76 // TF EBS attachment logic doesn't work well with references (doesn't interpolate) 77 }, 78 "ecs": { 79 // ECS is not able anymore to support references (doesn't interpolate) 80 "subnet": []string{"network_configuration.subnets", "id"}, 81 "sg": []string{"network_configuration.security_groups", "id"}, 82 }, 83 "eks": { 84 "subnet": []string{"vpc_config.subnet_ids", "id"}, 85 "sg": []string{"vpc_config.security_group_ids", "id"}, 86 }, 87 "elb": { 88 "sg": []string{"security_groups", "id"}, 89 "subnet": []string{"subnets", "id"}, 90 }, 91 "igw": {"vpc": []string{"vpc_id", "id"}}, 92 "msk": { 93 "subnet": []string{"broker_node_group_info.client_subnets", "id"}, 94 "sg": []string{"broker_node_group_info.security_groups", "id"}, 95 }, 96 "nacl": { 97 "subnet": []string{"subnet_ids", "id"}, 98 "vpc": []string{"vpc_id", "id"}, 99 }, 100 "organization": { 101 "organization": []string{ 102 "policy_id", "id", 103 "parent_id", "id", 104 "target_id", "id", 105 }, 106 }, 107 "rds": { 108 "subnet": []string{"subnet_ids", "id"}, 109 "sg": []string{"vpc_security_group_ids", "id"}, 110 }, 111 "route_table": { 112 "route_table": []string{"route_table_id", "id"}, 113 "subnet": []string{"subnet_id", "id"}, 114 "vpc": []string{"vpc_id", "id"}, 115 }, 116 "sns": { 117 "sns": []string{"topic_arn", "id"}, 118 "sqs": []string{"endpoint", "arn"}, 119 }, 120 "sg": { 121 "sg": []string{ 122 "egress.security_groups", "id", 123 "ingress.security_groups", "id", 124 "security_group_id", "id", 125 "source_security_group_id", "id", 126 }, 127 }, 128 "subnet": {"vpc": []string{"vpc_id", "id"}}, 129 "transit_gateway": { 130 "vpc": []string{"vpc_id", "id"}, 131 "transit_gateway": []string{"transit_gateway_id", "id"}, 132 "subnet": []string{"subnet_ids", "id"}, 133 "vpn_connection": []string{"vpn_connection_id", "id"}, 134 }, 135 "vpn_gateway": {"vpc": []string{"vpc_id", "id"}}, 136 "vpn_connection": { 137 "customer_gateway": []string{"customer_gateway_id", "id"}, 138 "vpn_gateway": []string{"vpn_gateway_id", "id"}, 139 }, 140 } 141 } 142 143 func (p AWSProvider) GetProviderData(arg ...string) map[string]interface{} { 144 awsConfig := map[string]interface{}{} 145 146 if p.region == GlobalRegion { 147 awsConfig["region"] = MainRegionPublicPartition // For TF to workaround terraform-providers/terraform-provider-aws#1043 148 } else if p.region != NoRegion { 149 awsConfig["region"] = p.region 150 } 151 152 return map[string]interface{}{ 153 "provider": map[string]interface{}{ 154 "aws": awsConfig, 155 }, 156 } 157 } 158 159 func (p *AWSProvider) GetConfig() cty.Value { 160 if p.region != GlobalRegion { 161 return cty.ObjectVal(map[string]cty.Value{ 162 "region": cty.StringVal(p.region), 163 "skip_region_validation": cty.True, 164 }) 165 } 166 return cty.ObjectVal(map[string]cty.Value{ 167 "region": cty.StringVal(""), 168 "skip_region_validation": cty.True, 169 }) 170 } 171 172 func (p *AWSProvider) GetBasicConfig() cty.Value { 173 return p.GetConfig() 174 } 175 176 // check projectName in env params 177 func (p *AWSProvider) Init(args []string) error { 178 p.region = args[0] 179 p.profile = args[1] 180 181 // Terraformer accepts region and profile configuration, so we must detect what env variables to adjust to make Go SDK rely on them. AWS_SDK_LOAD_CONFIG here must be checked to determine correct variable to set. 182 enableSharedConfig, _ := strconv.ParseBool(os.Getenv("AWS_SDK_LOAD_CONFIG")) 183 var err error 184 if p.region != GlobalRegion && p.region != NoRegion { 185 if enableSharedConfig { 186 err = os.Setenv("AWS_DEFAULT_REGION", p.region) 187 } else { 188 err = os.Setenv("AWS_REGION", p.region) 189 } 190 if err != nil { 191 return err 192 } 193 } 194 195 if p.profile != "default" && p.profile != "" { 196 if enableSharedConfig { 197 err = os.Setenv("AWS_DEFAULT_PROFILE", p.profile) 198 } else { 199 err = os.Setenv("AWS_PROFILE", p.profile) 200 } 201 if err != nil { 202 return err 203 } 204 } 205 return nil 206 } 207 208 func (p *AWSProvider) GetName() string { 209 return "aws" 210 } 211 212 func (p *AWSProvider) InitService(serviceName string, verbose bool) error { 213 var isSupported bool 214 if _, isSupported = p.GetSupportedService()[serviceName]; !isSupported { 215 return errors.New("aws: " + serviceName + " not supported service") 216 } 217 p.Service = p.GetSupportedService()[serviceName] 218 p.Service.SetName(serviceName) 219 p.Service.SetVerbose(verbose) 220 p.Service.SetProviderName(p.GetName()) 221 p.Service.SetArgs(map[string]interface{}{ 222 "region": p.region, 223 "profile": p.profile, 224 "skip_region_validation": true, 225 }) 226 return nil 227 } 228 229 // GetAWSSupportService return map of support service for AWS 230 func (p *AWSProvider) GetSupportedService() map[string]terraformutils.ServiceGenerator { 231 return map[string]terraformutils.ServiceGenerator{ 232 "accessanalyzer": &AwsFacade{service: &AccessAnalyzerGenerator{}}, 233 "acm": &AwsFacade{service: &ACMGenerator{}}, 234 "alb": &AwsFacade{service: &AlbGenerator{}}, 235 "api_gateway": &AwsFacade{service: &APIGatewayGenerator{}}, 236 "appsync": &AwsFacade{service: &AppSyncGenerator{}}, 237 "auto_scaling": &AwsFacade{service: &AutoScalingGenerator{}}, 238 "batch": &AwsFacade{service: &BatchGenerator{}}, 239 "budgets": &AwsFacade{service: &BudgetsGenerator{}}, 240 "cloud9": &AwsFacade{service: &Cloud9Generator{}}, 241 "cloudformation": &AwsFacade{service: &CloudFormationGenerator{}}, 242 "cloudfront": &AwsFacade{service: &CloudFrontGenerator{}}, 243 "cloudhsm": &AwsFacade{service: &CloudHsmGenerator{}}, 244 "cloudtrail": &AwsFacade{service: &CloudTrailGenerator{}}, 245 "cloudwatch": &AwsFacade{service: &CloudWatchGenerator{}}, 246 "codebuild": &AwsFacade{service: &CodeBuildGenerator{}}, 247 "codecommit": &AwsFacade{service: &CodeCommitGenerator{}}, 248 "codedeploy": &AwsFacade{service: &CodeDeployGenerator{}}, 249 "codepipeline": &AwsFacade{service: &CodePipelineGenerator{}}, 250 "cognito": &AwsFacade{service: &CognitoGenerator{}}, 251 "config": &AwsFacade{service: &ConfigGenerator{}}, 252 "customer_gateway": &AwsFacade{service: &CustomerGatewayGenerator{}}, 253 "datapipeline": &AwsFacade{service: &DataPipelineGenerator{}}, 254 "devicefarm": &AwsFacade{service: &DeviceFarmGenerator{}}, 255 "docdb": &AwsFacade{service: &DocDBGenerator{}}, 256 "dynamodb": &AwsFacade{service: &DynamoDbGenerator{}}, 257 "ebs": &AwsFacade{service: &EbsGenerator{}}, 258 "ec2_instance": &AwsFacade{service: &Ec2Generator{}}, 259 "ecr": &AwsFacade{service: &EcrGenerator{}}, 260 "ecrpublic": &AwsFacade{service: &EcrPublicGenerator{}}, 261 "ecs": &AwsFacade{service: &EcsGenerator{}}, 262 "efs": &AwsFacade{service: &EfsGenerator{}}, 263 "eks": &AwsFacade{service: &EksGenerator{}}, 264 "eip": &AwsFacade{service: &ElasticIPGenerator{}}, 265 "elasticache": &AwsFacade{service: &ElastiCacheGenerator{}}, 266 "elastic_beanstalk": &AwsFacade{service: &BeanstalkGenerator{}}, 267 "elb": &AwsFacade{service: &ElbGenerator{}}, 268 "emr": &AwsFacade{service: &EmrGenerator{}}, 269 "eni": &AwsFacade{service: &EniGenerator{}}, 270 "es": &AwsFacade{service: &EsGenerator{}}, 271 "firehose": &AwsFacade{service: &FirehoseGenerator{}}, 272 "glue": &AwsFacade{service: &GlueGenerator{}}, 273 "iam": &AwsFacade{service: &IamGenerator{}}, 274 "igw": &AwsFacade{service: &IgwGenerator{}}, 275 "iot": &AwsFacade{service: &IotGenerator{}}, 276 "kinesis": &AwsFacade{service: &KinesisGenerator{}}, 277 "kms": &AwsFacade{service: &KmsGenerator{}}, 278 "lambda": &AwsFacade{service: &LambdaGenerator{}}, 279 "logs": &AwsFacade{service: &LogsGenerator{}}, 280 "media_package": &AwsFacade{service: &MediaPackageGenerator{}}, 281 "media_store": &AwsFacade{service: &MediaStoreGenerator{}}, 282 "msk": &AwsFacade{service: &MskGenerator{}}, 283 "nacl": &AwsFacade{service: &NaclGenerator{}}, 284 "nat": &AwsFacade{service: &NatGatewayGenerator{}}, 285 "opsworks": &AwsFacade{service: &OpsworksGenerator{}}, 286 "organization": &AwsFacade{service: &OrganizationGenerator{}}, 287 "qldb": &AwsFacade{service: &QLDBGenerator{}}, 288 "rds": &AwsFacade{service: &RDSGenerator{}}, 289 "resourcegroups": &AwsFacade{service: &ResourceGroupsGenerator{}}, 290 "route53": &AwsFacade{service: &Route53Generator{}}, 291 "route_table": &AwsFacade{service: &RouteTableGenerator{}}, 292 "s3": &AwsFacade{service: &S3Generator{}}, 293 "secretsmanager": &AwsFacade{service: &SecretsManagerGenerator{}}, 294 "securityhub": &AwsFacade{service: &SecurityhubGenerator{}}, 295 "servicecatalog": &AwsFacade{service: &ServiceCatalogGenerator{}}, 296 "ses": &AwsFacade{service: &SesGenerator{}}, 297 "sfn": &AwsFacade{service: &SfnGenerator{}}, 298 "sg": &AwsFacade{service: &SecurityGenerator{}}, 299 "sqs": &AwsFacade{service: &SqsGenerator{}}, 300 "sns": &AwsFacade{service: &SnsGenerator{}}, 301 "ssm": &AwsFacade{service: &SsmGenerator{}}, 302 "subnet": &AwsFacade{service: &SubnetGenerator{}}, 303 "swf": &AwsFacade{service: &SWFGenerator{}}, 304 "transit_gateway": &AwsFacade{service: &TransitGatewayGenerator{}}, 305 "waf": &AwsFacade{service: &WafGenerator{}}, 306 "waf_regional": &AwsFacade{service: &WafRegionalGenerator{}}, 307 "vpc": &AwsFacade{service: &VpcGenerator{}}, 308 "vpc_peering": &AwsFacade{service: &VpcPeeringConnectionGenerator{}}, 309 "vpn_connection": &AwsFacade{service: &VpnConnectionGenerator{}}, 310 "vpn_gateway": &AwsFacade{service: &VpnGatewayGenerator{}}, 311 "workspaces": &AwsFacade{service: &WorkspacesGenerator{}}, 312 "xray": &AwsFacade{service: &XrayGenerator{}}, 313 } 314 } 315 316 func StringValue(value *string) string { 317 if value != nil { 318 return *value 319 } 320 return "" 321 }