terraform/builtin/providers/aws/config.go

461 lines
15 KiB
Go
Raw Normal View History

2014-06-24 04:01:57 +02:00
package aws
import (
"crypto/tls"
"errors"
2014-07-30 00:22:37 +02:00
"fmt"
"log"
"net/http"
"os"
2015-04-20 00:54:42 +02:00
"strings"
"time"
2014-06-24 04:01:57 +02:00
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/acm"
2016-03-05 23:12:19 +01:00
"github.com/aws/aws-sdk-go/service/apigateway"
"github.com/aws/aws-sdk-go/service/applicationautoscaling"
"github.com/aws/aws-sdk-go/service/autoscaling"
"github.com/aws/aws-sdk-go/service/cloudformation"
"github.com/aws/aws-sdk-go/service/cloudfront"
2015-08-28 00:11:56 +02:00
"github.com/aws/aws-sdk-go/service/cloudtrail"
"github.com/aws/aws-sdk-go/service/cloudwatch"
"github.com/aws/aws-sdk-go/service/cloudwatchevents"
2015-09-16 23:02:28 +02:00
"github.com/aws/aws-sdk-go/service/cloudwatchlogs"
2017-01-12 17:01:15 +01:00
"github.com/aws/aws-sdk-go/service/codebuild"
"github.com/aws/aws-sdk-go/service/codecommit"
"github.com/aws/aws-sdk-go/service/codedeploy"
"github.com/aws/aws-sdk-go/service/codepipeline"
"github.com/aws/aws-sdk-go/service/configservice"
"github.com/aws/aws-sdk-go/service/databasemigrationservice"
"github.com/aws/aws-sdk-go/service/directoryservice"
2015-06-04 02:12:41 +02:00
"github.com/aws/aws-sdk-go/service/dynamodb"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/ecr"
"github.com/aws/aws-sdk-go/service/ecs"
2015-06-02 22:19:50 +02:00
"github.com/aws/aws-sdk-go/service/efs"
"github.com/aws/aws-sdk-go/service/elasticache"
"github.com/aws/aws-sdk-go/service/elasticbeanstalk"
elasticsearch "github.com/aws/aws-sdk-go/service/elasticsearchservice"
"github.com/aws/aws-sdk-go/service/elastictranscoder"
"github.com/aws/aws-sdk-go/service/elb"
2016-08-11 23:25:40 +02:00
"github.com/aws/aws-sdk-go/service/elbv2"
"github.com/aws/aws-sdk-go/service/emr"
"github.com/aws/aws-sdk-go/service/firehose"
"github.com/aws/aws-sdk-go/service/glacier"
"github.com/aws/aws-sdk-go/service/iam"
"github.com/aws/aws-sdk-go/service/inspector"
"github.com/aws/aws-sdk-go/service/kinesis"
2015-09-09 17:58:24 +02:00
"github.com/aws/aws-sdk-go/service/kms"
2015-06-09 21:12:47 +02:00
"github.com/aws/aws-sdk-go/service/lambda"
"github.com/aws/aws-sdk-go/service/lightsail"
"github.com/aws/aws-sdk-go/service/opsworks"
"github.com/aws/aws-sdk-go/service/rds"
"github.com/aws/aws-sdk-go/service/redshift"
"github.com/aws/aws-sdk-go/service/route53"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/aws/aws-sdk-go/service/ses"
2017-01-10 15:17:39 +01:00
"github.com/aws/aws-sdk-go/service/sfn"
2016-07-12 13:55:58 +02:00
"github.com/aws/aws-sdk-go/service/simpledb"
"github.com/aws/aws-sdk-go/service/sns"
"github.com/aws/aws-sdk-go/service/sqs"
"github.com/aws/aws-sdk-go/service/ssm"
"github.com/aws/aws-sdk-go/service/sts"
"github.com/aws/aws-sdk-go/service/waf"
"github.com/davecgh/go-spew/spew"
"github.com/hashicorp/errwrap"
"github.com/hashicorp/go-cleanhttp"
"github.com/hashicorp/terraform/helper/logging"
"github.com/hashicorp/terraform/terraform"
2014-06-24 04:01:57 +02:00
)
type Config struct {
AccessKey string
SecretKey string
CredsFilename string
Profile string
Token string
Region string
MaxRetries int
2015-04-20 00:54:42 +02:00
AssumeRoleARN string
AssumeRoleExternalID string
AssumeRoleSessionName string
AssumeRolePolicy string
2015-04-20 00:54:42 +02:00
AllowedAccountIds []interface{}
ForbiddenAccountIds []interface{}
DynamoDBEndpoint string
KinesisEndpoint string
Ec2Endpoint string
IamEndpoint string
ElbEndpoint string
S3Endpoint string
Insecure bool
SkipCredsValidation bool
SkipRegionValidation bool
SkipRequestingAccountId bool
SkipMetadataApiCheck bool
S3ForcePathStyle bool
}
type AWSClient struct {
cfconn *cloudformation.CloudFormation
cloudfrontconn *cloudfront.CloudFront
cloudtrailconn *cloudtrail.CloudTrail
cloudwatchconn *cloudwatch.CloudWatch
cloudwatchlogsconn *cloudwatchlogs.CloudWatchLogs
cloudwatcheventsconn *cloudwatchevents.CloudWatchEvents
configconn *configservice.ConfigService
dmsconn *databasemigrationservice.DatabaseMigrationService
dsconn *directoryservice.DirectoryService
dynamodbconn *dynamodb.DynamoDB
ec2conn *ec2.EC2
ecrconn *ecr.ECR
ecsconn *ecs.ECS
efsconn *efs.EFS
elbconn *elb.ELB
2016-08-11 23:25:40 +02:00
elbv2conn *elbv2.ELBV2
emrconn *emr.EMR
esconn *elasticsearch.ElasticsearchService
acmconn *acm.ACM
apigateway *apigateway.APIGateway
appautoscalingconn *applicationautoscaling.ApplicationAutoScaling
autoscalingconn *autoscaling.AutoScaling
s3conn *s3.S3
sesConn *ses.SES
2016-07-12 13:55:58 +02:00
simpledbconn *simpledb.SimpleDB
sqsconn *sqs.SQS
snsconn *sns.SNS
stsconn *sts.STS
redshiftconn *redshift.Redshift
r53conn *route53.Route53
partition string
accountid string
supportedplatforms []string
region string
rdsconn *rds.RDS
iamconn *iam.IAM
kinesisconn *kinesis.Kinesis
kmsconn *kms.KMS
firehoseconn *firehose.Firehose
inspectorconn *inspector.Inspector
elasticacheconn *elasticache.ElastiCache
elasticbeanstalkconn *elasticbeanstalk.ElasticBeanstalk
elastictranscoderconn *elastictranscoder.ElasticTranscoder
lambdaconn *lambda.Lambda
lightsailconn *lightsail.Lightsail
opsworksconn *opsworks.OpsWorks
glacierconn *glacier.Glacier
2017-01-12 17:01:15 +01:00
codebuildconn *codebuild.CodeBuild
codedeployconn *codedeploy.CodeDeploy
codecommitconn *codecommit.CodeCommit
codepipelineconn *codepipeline.CodePipeline
2017-01-10 15:17:39 +01:00
sfnconn *sfn.SFN
ssmconn *ssm.SSM
wafconn *waf.WAF
}
// Client configures and returns a fully initialized AWSClient
func (c *Config) Client() (interface{}, error) {
// Get the auth and region. This can fail if keys/regions were not
// specified and we're attempting to use the environment.
if c.SkipRegionValidation {
log.Println("[INFO] Skipping region validation")
} else {
log.Println("[INFO] Building AWS region structure")
err := c.ValidateRegion()
if err != nil {
return nil, err
}
}
2016-03-05 23:12:19 +01:00
var client AWSClient
// store AWS region in client struct, for region specific operations such as
// bucket storage in S3
client.region = c.Region
2015-02-20 15:55:54 +01:00
log.Println("[INFO] Building AWS auth structure")
creds, err := GetCredentials(c)
if err != nil {
return nil, err
}
// Call Get to check for credential provider. If nothing found, we'll get an
// error, and we can present it nicely to the user
cp, err := creds.Get()
if err != nil {
if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == "NoCredentialProviders" {
return nil, errors.New(`No valid credential sources found for AWS Provider.
Please see https://terraform.io/docs/providers/aws/index.html for more information on
providing credentials for the AWS Provider`)
}
return nil, fmt.Errorf("Error loading credentials for AWS Provider: %s", err)
}
log.Printf("[INFO] AWS Auth provider used: %q", cp.ProviderName)
awsConfig := &aws.Config{
Credentials: creds,
Region: aws.String(c.Region),
MaxRetries: aws.Int(c.MaxRetries),
HTTPClient: cleanhttp.DefaultClient(),
S3ForcePathStyle: aws.Bool(c.S3ForcePathStyle),
}
if logging.IsDebugOrHigher() {
awsConfig.LogLevel = aws.LogLevel(aws.LogDebugWithHTTPBody)
awsConfig.Logger = awsLogger{}
}
if c.Insecure {
transport := awsConfig.HTTPClient.Transport.(*http.Transport)
transport.TLSClientConfig = &tls.Config{
InsecureSkipVerify: true,
}
}
// Set up base session
sess, err := session.NewSession(awsConfig)
if err != nil {
return nil, errwrap.Wrapf("Error creating AWS session: {{err}}", err)
}
// Removes the SDK Version handler, so we only have the provider User-Agent
// Ex: "User-Agent: APN/1.0 HashiCorp/1.0 Terraform/0.7.9-dev"
sess.Handlers.Build.Remove(request.NamedHandler{Name: "core.SDKVersionUserAgentHandler"})
sess.Handlers.Build.PushFrontNamed(addTerraformVersionToUserAgent)
if extraDebug := os.Getenv("TERRAFORM_AWS_AUTHFAILURE_DEBUG"); extraDebug != "" {
sess.Handlers.UnmarshalError.PushFrontNamed(debugAuthFailure)
}
// Some services exist only in us-east-1, e.g. because they manage
// resources that can span across multiple regions, or because
// signature format v4 requires region to be us-east-1 for global
// endpoints:
// http://docs.aws.amazon.com/general/latest/gr/sigv4_changes.html
usEast1Sess := sess.Copy(&aws.Config{Region: aws.String("us-east-1")})
// Some services have user-configurable endpoints
awsEc2Sess := sess.Copy(&aws.Config{Endpoint: aws.String(c.Ec2Endpoint)})
awsElbSess := sess.Copy(&aws.Config{Endpoint: aws.String(c.ElbEndpoint)})
awsIamSess := sess.Copy(&aws.Config{Endpoint: aws.String(c.IamEndpoint)})
awsS3Sess := sess.Copy(&aws.Config{Endpoint: aws.String(c.S3Endpoint)})
dynamoSess := sess.Copy(&aws.Config{Endpoint: aws.String(c.DynamoDBEndpoint)})
kinesisSess := sess.Copy(&aws.Config{Endpoint: aws.String(c.KinesisEndpoint)})
// These two services need to be set up early so we can check on AccountID
client.iamconn = iam.New(awsIamSess)
client.stsconn = sts.New(sess)
if !c.SkipCredsValidation {
err = c.ValidateCredentials(client.stsconn)
if err != nil {
return nil, err
}
}
if !c.SkipRequestingAccountId {
partition, accountId, err := GetAccountInfo(client.iamconn, client.stsconn, cp.ProviderName)
if err == nil {
client.partition = partition
client.accountid = accountId
2015-04-20 00:54:42 +02:00
}
}
authErr := c.ValidateAccountId(client.accountid)
if authErr != nil {
return nil, authErr
}
client.ec2conn = ec2.New(awsEc2Sess)
supportedPlatforms, err := GetSupportedEC2Platforms(client.ec2conn)
if err != nil {
// We intentionally fail *silently* because there's a chance
// user just doesn't have ec2:DescribeAccountAttributes permissions
log.Printf("[WARN] Unable to get supported EC2 platforms: %s", err)
} else {
client.supportedplatforms = supportedPlatforms
}
client.acmconn = acm.New(sess)
client.apigateway = apigateway.New(sess)
client.appautoscalingconn = applicationautoscaling.New(sess)
client.autoscalingconn = autoscaling.New(sess)
client.cfconn = cloudformation.New(sess)
client.cloudfrontconn = cloudfront.New(sess)
client.cloudtrailconn = cloudtrail.New(sess)
client.cloudwatchconn = cloudwatch.New(sess)
client.cloudwatcheventsconn = cloudwatchevents.New(sess)
client.cloudwatchlogsconn = cloudwatchlogs.New(sess)
client.codecommitconn = codecommit.New(sess)
2017-01-12 17:01:15 +01:00
client.codebuildconn = codebuild.New(sess)
client.codedeployconn = codedeploy.New(sess)
client.configconn = configservice.New(sess)
client.dmsconn = databasemigrationservice.New(sess)
client.codepipelineconn = codepipeline.New(sess)
client.dsconn = directoryservice.New(sess)
client.dynamodbconn = dynamodb.New(dynamoSess)
client.ecrconn = ecr.New(sess)
client.ecsconn = ecs.New(sess)
client.efsconn = efs.New(sess)
client.elasticacheconn = elasticache.New(sess)
client.elasticbeanstalkconn = elasticbeanstalk.New(sess)
client.elastictranscoderconn = elastictranscoder.New(sess)
client.elbconn = elb.New(awsElbSess)
client.elbv2conn = elbv2.New(awsElbSess)
client.emrconn = emr.New(sess)
client.esconn = elasticsearch.New(sess)
client.firehoseconn = firehose.New(sess)
client.inspectorconn = inspector.New(sess)
client.glacierconn = glacier.New(sess)
client.kinesisconn = kinesis.New(kinesisSess)
client.kmsconn = kms.New(sess)
client.lambdaconn = lambda.New(sess)
client.lightsailconn = lightsail.New(usEast1Sess)
provider/aws: Remove restriction on running aws_opsworks_* on us-east-1 (#12688) Fixes: #11824 A full set of acceptance tests for *all* OpsWorks tests are below. There is a single issue, opsworks_instance isn't ordering the layer_ids so it's non-deterministic which can come back. This introduces a false positive. The opsworks tests are running both against us-east-1 for some and us-west-2 for others. This must be marked as a backwards incompatibility in 0.9 just incase people are using the opsworks region parameter to try and override the provider region ``` % make testacc TEST=./builtin/providers/aws TESTARGS='-run=TestAccAWSOpsworksApplication' 2 ↵ ✹ ==> Checking that code complies with gofmt requirements... go generate $(go list ./... | grep -v /terraform/vendor/) 2017/03/14 17:11:36 Generated command/internal_plugin_list.go TF_ACC=1 go test ./builtin/providers/aws -v -run=TestAccAWSOpsworksApplication -timeout 120m === RUN TestAccAWSOpsworksApplication --- PASS: TestAccAWSOpsworksApplication (164.29s) PASS ok github.com/hashicorp/terraform/builtin/providers/aws 164.319s ``` ``` % make testacc TEST=./builtin/providers/aws TESTARGS='-run=TestAccAWSOpsworksCustomLayer' ✹ ==> Checking that code complies with gofmt requirements... go generate $(go list ./... | grep -v /terraform/vendor/) 2017/03/14 17:16:18 Generated command/internal_plugin_list.go TF_ACC=1 go test ./builtin/providers/aws -v -run=TestAccAWSOpsworksCustomLayer -timeout 120m === RUN TestAccAWSOpsworksCustomLayerImportBasic --- PASS: TestAccAWSOpsworksCustomLayerImportBasic (105.98s) === RUN TestAccAWSOpsworksCustomLayer --- PASS: TestAccAWSOpsworksCustomLayer (92.68s) PASS ok github.com/hashicorp/terraform/builtin/providers/aws 198.684s ``` ``` % make testacc TEST=./builtin/providers/aws TESTARGS='-run=TestAccAWSOpsworksPermission' ✹ ==> Checking that code complies with gofmt requirements... go generate $(go list ./... | grep -v /terraform/vendor/) 2017/03/14 17:23:28 Generated command/internal_plugin_list.go TF_ACC=1 go test ./builtin/providers/aws -v -run=TestAccAWSOpsworksPermission -timeout 120m === RUN TestAccAWSOpsworksPermission --- PASS: TestAccAWSOpsworksPermission (226.36s) PASS ok github.com/hashicorp/terraform/builtin/providers/aws 226.386s ``` ``` % make testacc TEST=./builtin/providers/aws TESTARGS='-run=TestAccAWSOpsworksRailsAppLayer' ✹ ==> Checking that code complies with gofmt requirements... go generate $(go list ./... | grep -v /terraform/vendor/) 2017/03/14 17:28:01 Generated command/internal_plugin_list.go TF_ACC=1 go test ./builtin/providers/aws -v -run=TestAccAWSOpsworksRailsAppLayer -timeout 120m === RUN TestAccAWSOpsworksRailsAppLayer --- PASS: TestAccAWSOpsworksRailsAppLayer (129.39s) PASS ok github.com/hashicorp/terraform/builtin/providers/aws 129.426s ``` ``` % make testacc TEST=./builtin/providers/aws TESTARGS='-run=TestAccAWSOpsworksUserProfile' ✹ ==> Checking that code complies with gofmt requirements... go generate $(go list ./... | grep -v /terraform/vendor/) 2017/03/14 17:37:46 Generated command/internal_plugin_list.go TF_ACC=1 go test ./builtin/providers/aws -v -run=TestAccAWSOpsworksUserProfile -timeout 120m === RUN TestAccAWSOpsworksUserProfile --- PASS: TestAccAWSOpsworksUserProfile (42.60s) PASS ok github.com/hashicorp/terraform/builtin/providers/aws 42.624s ``` ``` % make testacc TEST=./builtin/providers/aws TESTARGS='-run=TestAccAWSOpsworksStack' 2 ↵ ✹ ==> Checking that code complies with gofmt requirements... go generate $(go list ./... | grep -v /terraform/vendor/) 2017/03/14 18:00:50 Generated command/internal_plugin_list.go TF_ACC=1 go test ./builtin/providers/aws -v -run=TestAccAWSOpsworksStack -timeout 120m === RUN TestAccAWSOpsworksStackImportBasic --- PASS: TestAccAWSOpsworksStackImportBasic (50.28s) === RUN TestAccAWSOpsworksStackNoVpc --- PASS: TestAccAWSOpsworksStackNoVpc (25.92s) === RUN TestAccAWSOpsworksStackVpc --- PASS: TestAccAWSOpsworksStackVpc (76.80s) PASS ok github.com/hashicorp/terraform/builtin/providers/aws 153.025s ``` ``` % make testacc TEST=./builtin/providers/aws TESTARGS='-run=TestAccAWSOpsworksRdsDbInstance' ✹ ==> Checking that code complies with gofmt requirements... go generate $(go list ./... | grep -v /terraform/vendor/) 2017/03/14 17:38:36 Generated command/internal_plugin_list.go TF_ACC=1 go test ./builtin/providers/aws -v -run=TestAccAWSOpsworksRdsDbInstance -timeout 120m === RUN TestAccAWSOpsworksRdsDbInstance --- PASS: TestAccAWSOpsworksRdsDbInstance (916.15s) PASS ok github.com/hashicorp/terraform/builtin/providers/aws 916.177s ``` ``` % make testacc TEST=./builtin/providers/aws TESTARGS='-run=TestAccAWSOpsworksInstance' 2 ↵ ==> Checking that code complies with gofmt requirements... go generate $(go list ./... | grep -v /terraform/vendor/) 2017/03/14 17:26:45 Generated command/internal_plugin_list.go TF_ACC=1 go test ./builtin/providers/aws -v -run=TestAccAWSOpsworksInstance -timeout 120m === RUN TestAccAWSOpsworksInstance_importBasic --- PASS: TestAccAWSOpsworksInstance_importBasic (85.52s) === RUN TestAccAWSOpsworksInstance --- FAIL: TestAccAWSOpsworksInstance (114.09s) testing.go:268: Step 1 error: After applying this step, the plan was not empty: DIFF: UPDATE: aws_opsworks_instance.tf-acc layer_ids.0: "4c29b76f-df72-409e-a5c4-9459b7d9b4a4" => "a4a859cf-2a07-447e-a151-a97a6d827db7" layer_ids.1: "a4a859cf-2a07-447e-a151-a97a6d827db7" => "4c29b76f-df72-409e-a5c4-9459b7d9b4a4" FAIL exit status 1 FAIL github.com/hashicorp/terraform/builtin/providers/aws 199.643s make: *** [testacc] Error 1 ```
2017-03-15 15:17:53 +01:00
client.opsworksconn = opsworks.New(sess)
client.r53conn = route53.New(usEast1Sess)
client.rdsconn = rds.New(sess)
client.redshiftconn = redshift.New(sess)
client.simpledbconn = simpledb.New(sess)
client.s3conn = s3.New(awsS3Sess)
client.sesConn = ses.New(sess)
2017-01-10 15:17:39 +01:00
client.sfnconn = sfn.New(sess)
client.snsconn = sns.New(sess)
client.sqsconn = sqs.New(sess)
client.ssmconn = ssm.New(sess)
client.wafconn = waf.New(sess)
return &client, nil
2014-06-24 04:01:57 +02:00
}
// ValidateRegion returns an error if the configured region is not a
// valid aws region and nil otherwise.
2015-03-13 15:42:50 +01:00
func (c *Config) ValidateRegion() error {
var regions = []string{
"ap-northeast-1",
"ap-northeast-2",
"ap-south-1",
"ap-southeast-1",
"ap-southeast-2",
"ca-central-1",
"cn-north-1",
"eu-central-1",
"eu-west-1",
"eu-west-2",
"sa-east-1",
"us-east-1",
"us-east-2",
"us-gov-west-1",
"us-west-1",
"us-west-2",
}
2014-07-30 00:22:37 +02:00
for _, valid := range regions {
if c.Region == valid {
2015-03-13 15:42:50 +01:00
return nil
2014-07-30 00:22:37 +02:00
}
}
2015-03-13 15:42:50 +01:00
return fmt.Errorf("Not a valid region: %s", c.Region)
2014-06-24 04:01:57 +02:00
}
2015-04-20 00:54:42 +02:00
// Validate credentials early and fail before we do any graph walking.
func (c *Config) ValidateCredentials(stsconn *sts.STS) error {
_, err := stsconn.GetCallerIdentity(&sts.GetCallerIdentityInput{})
2015-07-21 15:57:59 +02:00
return err
}
// ValidateAccountId returns a context-specific error if the configured account
// id is explicitly forbidden or not authorised; and nil if it is authorised.
func (c *Config) ValidateAccountId(accountId string) error {
2015-04-20 00:54:42 +02:00
if c.AllowedAccountIds == nil && c.ForbiddenAccountIds == nil {
return nil
}
log.Println("[INFO] Validating account ID")
2015-04-20 00:54:42 +02:00
if c.ForbiddenAccountIds != nil {
for _, id := range c.ForbiddenAccountIds {
if id == accountId {
2015-04-20 00:54:42 +02:00
return fmt.Errorf("Forbidden account ID (%s)", id)
}
}
}
if c.AllowedAccountIds != nil {
for _, id := range c.AllowedAccountIds {
if id == accountId {
2015-04-20 00:54:42 +02:00
return nil
}
}
return fmt.Errorf("Account ID not allowed (%s)", accountId)
2015-04-20 00:54:42 +02:00
}
return nil
}
func GetSupportedEC2Platforms(conn *ec2.EC2) ([]string, error) {
attrName := "supported-platforms"
input := ec2.DescribeAccountAttributesInput{
AttributeNames: []*string{aws.String(attrName)},
}
attributes, err := conn.DescribeAccountAttributes(&input)
if err != nil {
return nil, err
}
var platforms []string
for _, attr := range attributes.AccountAttributes {
if *attr.AttributeName == attrName {
for _, v := range attr.AttributeValues {
platforms = append(platforms, *v.AttributeValue)
}
break
}
}
if len(platforms) == 0 {
return nil, fmt.Errorf("No EC2 platforms detected")
}
return platforms, nil
}
// addTerraformVersionToUserAgent is a named handler that will add Terraform's
// version information to requests made by the AWS SDK.
var addTerraformVersionToUserAgent = request.NamedHandler{
Name: "terraform.TerraformVersionUserAgentHandler",
Fn: request.MakeAddToUserAgentHandler(
"APN/1.0 HashiCorp/1.0 Terraform", terraform.VersionString()),
}
var debugAuthFailure = request.NamedHandler{
Name: "terraform.AuthFailureAdditionalDebugHandler",
Fn: func(req *request.Request) {
if isAWSErr(req.Error, "AuthFailure", "AWS was not able to validate the provided access credentials") {
log.Printf("[INFO] Additional AuthFailure Debugging Context")
log.Printf("[INFO] Current system UTC time: %s", time.Now().UTC())
log.Printf("[INFO] Request object: %s", spew.Sdump(req))
}
},
}
type awsLogger struct{}
func (l awsLogger) Log(args ...interface{}) {
tokens := make([]string, 0, len(args))
for _, arg := range args {
if token, ok := arg.(string); ok {
tokens = append(tokens, token)
}
}
log.Printf("[DEBUG] [aws-sdk-go] %s", strings.Join(tokens, " "))
}