Use AWS access key in operations prvider when available (#697)

If the stack config specifies AWS credentials, these should be used in the operations provider instead of ambient credentials.  This is necessary to ensure that we have access to resources in the target account.

Fixes pulumi/pulumi-service#389
This commit is contained in:
Luke Hoban 2017-12-11 15:40:39 -08:00 committed by GitHub
parent 9bc9ce1505
commit 3b461ffcb3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -9,6 +9,7 @@ import (
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/cloudwatchlogs"
"github.com/golang/glog"
@ -31,7 +32,17 @@ func AWSOperationsProvider(
return nil, errors.New("no AWS region found")
}
awsConnection, err := getAWSConnection(awsRegion)
// If provided, also pass along the access and secret keys so that we have permission to access operational data on
// resources in the target account.
//
// [pulumi/pulumi#608]: We are only approximating the actual logic that the AWS provider (via
// terraform-provdider-aws) uses to turn config into a valid AWS connection. We should find some way to unify these
// as part of moving this code into a separate process on the other side of an RPC boundary.
awsAccessKey := config[accessKey]
awsSecretKey := config[secretKey]
awsToken := config[token]
awsConnection, err := getAWSConnection(awsRegion, awsAccessKey, awsSecretKey, awsToken)
if err != nil {
return nil, err
}
@ -53,6 +64,9 @@ var _ Provider = (*awsOpsProvider)(nil)
const (
// AWS config keys
regionKey = "aws:config:region"
accessKey = "aws:config:accessKey"
secretKey = "aws:config:secretKey" // nolint: gas
token = "aws:config:token"
// AWS resource types
awsFunctionType = tokens.Type("aws:lambda/function:Function")
@ -100,13 +114,19 @@ type awsConnection struct {
var awsConnectionCache = map[string]*awsConnection{}
var awsConnectionCacheMutex = sync.RWMutex{}
func getAWSConnection(awsRegion string) (*awsConnection, error) {
func getAWSConnection(awsRegion, awsAccessKey, awsSecretKey, token string) (*awsConnection, error) {
awsConnectionCacheMutex.RLock()
connection, ok := awsConnectionCache[awsRegion]
awsConnectionCacheMutex.RUnlock()
if !ok {
awsConfig := aws.NewConfig()
awsConfig.Region = aws.String(awsRegion)
if awsAccessKey != "" || awsSecretKey != "" {
awsConfig.Credentials = credentials.NewStaticCredentials(awsAccessKey, awsSecretKey, token)
glog.V(5).Infof("Using credentials from stack config for AWS operations provider.")
} else {
glog.V(5).Infof("Using ambient credentials for AWS operations provider.")
}
sess, err := session.NewSession(awsConfig)
if err != nil {
return nil, errors.Wrap(err, "failed to create AWS session")