providers/aws: detect credentials more robustly

aws hides its credentials in many places:
multiple env vars, config files,
ec2 metadata.

Terraform currently recognizes only the env vars;
to use the other options, you had to put in a
dummy empty value for access_key and secret_key.

Rather than duplicate all aws checks, ask the
aws sdk to fetch credentials earlier.
This commit is contained in:
Josh Bleecher Snyder 2015-05-06 20:02:09 -07:00
parent febf27a48e
commit ed67f8f588
2 changed files with 33 additions and 22 deletions

View File

@ -62,16 +62,9 @@ func (c *Config) Client() (interface{}, error) {
client.region = c.Region
log.Println("[INFO] Building AWS auth structure")
creds := credentials.NewChainCredentials([]credentials.Provider{
&credentials.StaticProvider{Value: credentials.Value{
AccessKeyID: c.AccessKey,
SecretAccessKey: c.SecretKey,
SessionToken: c.Token,
}},
&credentials.EnvProvider{},
&credentials.SharedCredentialsProvider{Filename: "", Profile: ""},
&credentials.EC2RoleProvider{},
})
// We fetched all credential sources in Provider.
// If it is available, it is stored in c.
creds := credentials.NewStaticCredentials(c.AccessKey, c.SecretKey, c.Token)
awsConfig := &aws.Config{
Credentials: creds,
Region: c.Region,

View File

@ -1,6 +1,9 @@
package aws
import (
"sync"
"github.com/awslabs/aws-sdk-go/aws/credentials"
"github.com/hashicorp/terraform/helper/hashcode"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/terraform"
@ -11,35 +14,50 @@ func Provider() terraform.ResourceProvider {
// TODO: Move the validation to this, requires conditional schemas
// TODO: Move the configuration to this, requires validation
// Prepare to handle external sources of credentials.
// Static credentials are intentionally omitted;
// this is used when no static credentials are provided.
creds := credentials.NewChainCredentials([]credentials.Provider{
&credentials.EnvProvider{},
&credentials.SharedCredentialsProvider{},
&credentials.EC2RoleProvider{},
})
var credVal credentials.Value
var credErr error
var once sync.Once
getCreds := func() {
credVal, credErr = creds.Get()
}
return &schema.Provider{
Schema: map[string]*schema.Schema{
"access_key": &schema.Schema{
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.MultiEnvDefaultFunc([]string{
"AWS_ACCESS_KEY",
"AWS_ACCESS_KEY_ID",
}, nil),
DefaultFunc: func() (interface{}, error) {
once.Do(getCreds)
return credVal.AccessKeyID, credErr
},
Description: descriptions["access_key"],
},
"secret_key": &schema.Schema{
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.MultiEnvDefaultFunc([]string{
"AWS_SECRET_KEY",
"AWS_SECRET_ACCESS_KEY",
}, nil),
DefaultFunc: func() (interface{}, error) {
once.Do(getCreds)
return credVal.SecretAccessKey, credErr
},
Description: descriptions["secret_key"],
},
"token": &schema.Schema{
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.MultiEnvDefaultFunc([]string{
"AWS_SESSION_TOKEN",
"AWS_SECURITY_TOKEN",
}, ""),
DefaultFunc: func() (interface{}, error) {
once.Do(getCreds)
return credVal.SessionToken, credErr
},
Description: descriptions["token"],
},