github.com/GoogleCloudPlatform/terraformer@v0.8.18/providers/aws/aws_service.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 "context" 19 "os" 20 "regexp" 21 22 "github.com/aws/aws-sdk-go-v2/service/sts" 23 24 "github.com/aws/aws-sdk-go-v2/aws" 25 "github.com/aws/aws-sdk-go-v2/config" 26 "github.com/aws/aws-sdk-go-v2/credentials/stscreds" 27 28 "github.com/GoogleCloudPlatform/terraformer/terraformutils" 29 ) 30 31 type AWSService struct { //nolint 32 terraformutils.Service 33 } 34 35 var awsVariable = regexp.MustCompile(`(\${[0-9A-Za-z:]+})`) 36 37 var configCache *aws.Config 38 39 func (s *AWSService) generateConfig() (aws.Config, error) { 40 if configCache != nil { 41 return *configCache, nil 42 } 43 44 baseConfig, e := s.buildBaseConfig() 45 46 if e != nil { 47 return baseConfig, e 48 } 49 if s.Verbose { 50 baseConfig.ClientLogMode = aws.LogRequestWithBody & aws.LogResponseWithBody 51 } 52 53 creds, e := baseConfig.Credentials.Retrieve(context.TODO()) 54 55 if e != nil { 56 return baseConfig, e 57 } 58 59 // terraform cannot ask for MFA token, so we need to pass STS session token, which might contain credentials with MFA requirement 60 accessKey := os.Getenv("AWS_SECRET_ACCESS_KEY") 61 if accessKey == "" { 62 os.Setenv("AWS_ACCESS_KEY_ID", creds.AccessKeyID) 63 os.Setenv("AWS_SECRET_ACCESS_KEY", creds.SecretAccessKey) 64 65 if creds.SessionToken != "" { 66 os.Setenv("AWS_SESSION_TOKEN", creds.SessionToken) 67 } 68 } 69 configCache = &baseConfig 70 return baseConfig, nil 71 } 72 73 func (s *AWSService) buildBaseConfig() (aws.Config, error) { 74 var loadOptions []func(*config.LoadOptions) error 75 if s.GetArgs()["profile"].(string) != "" { 76 loadOptions = append(loadOptions, config.WithSharedConfigProfile(s.GetArgs()["profile"].(string))) 77 } 78 if s.GetArgs()["region"].(string) != "" { 79 os.Setenv("AWS_REGION", s.GetArgs()["region"].(string)) 80 } 81 loadOptions = append(loadOptions, config.WithAssumeRoleCredentialOptions(func(options *stscreds.AssumeRoleOptions) { 82 options.TokenProvider = stscreds.StdinTokenProvider 83 })) 84 return config.LoadDefaultConfig(context.TODO(), loadOptions...) 85 } 86 87 // for CF interpolation and IAM Policy variables 88 func (*AWSService) escapeAwsInterpolation(str string) string { 89 return awsVariable.ReplaceAllString(str, "$$$1") 90 } 91 92 func (s *AWSService) getAccountNumber(config aws.Config) (*string, error) { 93 stsSvc := sts.NewFromConfig(config) 94 identity, err := stsSvc.GetCallerIdentity(context.TODO(), &sts.GetCallerIdentityInput{}) 95 if err != nil { 96 return nil, err 97 } 98 return identity.Account, nil 99 }