Skip to content

Commit

Permalink
When using IAM roles or STS, you can't use iam.GetUser(nil) to retrie…
Browse files Browse the repository at this point in the history
…ve the account ID. The good news is that the STS api has been updated to include GetCallerIdentity which can do this.
  • Loading branch information
bigkraig committed Apr 28, 2016
1 parent 9f2a4a8 commit cb9873b
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 55 deletions.
27 changes: 10 additions & 17 deletions builtin/providers/aws/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ import (
"github.com/aws/aws-sdk-go/service/s3"
"github.com/aws/aws-sdk-go/service/sns"
"github.com/aws/aws-sdk-go/service/sqs"
"github.com/aws/aws-sdk-go/service/sts"
)

type Config struct {
Expand Down Expand Up @@ -95,6 +96,7 @@ type AWSClient struct {
s3conn *s3.S3
sqsconn *sqs.SQS
snsconn *sns.SNS
stsconn *sts.STS
redshiftconn *redshift.Redshift
r53conn *route53.Route53
region string
Expand Down Expand Up @@ -201,6 +203,9 @@ func (c *Config) Client() (interface{}, error) {
log.Println("[INFO] Initializing SNS connection")
client.snsconn = sns.New(sess)

log.Println("[INFO] Initializing STS connection")
client.stsconn = sts.New(sess)

log.Println("[INFO] Initializing RDS Connection")
client.rdsconn = rds.New(sess)

Expand All @@ -211,7 +216,7 @@ func (c *Config) Client() (interface{}, error) {
log.Println("[INFO] Initializing Elastic Beanstalk Connection")
client.elasticbeanstalkconn = elasticbeanstalk.New(sess)

authErr := c.ValidateAccountId(client.iamconn)
authErr := c.ValidateAccountId(client.stsconn)
if authErr != nil {
errs = append(errs, authErr)
}
Expand Down Expand Up @@ -334,30 +339,18 @@ func (c *Config) ValidateCredentials(iamconn *iam.IAM) error {

// 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(iamconn *iam.IAM) error {
func (c *Config) ValidateAccountId(stsconn *sts.STS) error {
if c.AllowedAccountIds == nil && c.ForbiddenAccountIds == nil {
return nil
}

log.Printf("[INFO] Validating account ID")

out, err := iamconn.GetUser(nil)

resp, err := stsconn.GetCallerIdentity(&sts.GetCallerIdentityInput{})
if err != nil {
awsErr, _ := err.(awserr.Error)
if awsErr.Code() == "ValidationError" {
log.Printf("[WARN] ValidationError with iam.GetUser, assuming its an IAM profile")
// User may be an IAM instance profile, so fail silently.
// If it is an IAM instance profile
// validating account might be superfluous
return nil
} else {
return fmt.Errorf("Failed getting account ID from IAM: %s", err)
// return error if the account id is explicitly not authorised
}
return err
}

account_id := strings.Split(*out.User.Arn, ":")[4]
account_id := *resp.Account

if c.ForbiddenAccountIds != nil {
for _, id := range c.ForbiddenAccountIds {
Expand Down
12 changes: 5 additions & 7 deletions builtin/providers/aws/resource_aws_db_event_subscription.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@ package aws
import (
"fmt"
"log"
"strings"
"time"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/service/iam"
"github.com/aws/aws-sdk-go/service/rds"
"github.com/aws/aws-sdk-go/service/sts"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
)
Expand Down Expand Up @@ -315,15 +314,14 @@ func resourceAwsDbEventSubscriptionRefreshFunc(
}

func buildRDSEventSubscriptionARN(identifier string, meta interface{}) (string, error) {
iamconn := meta.(*AWSClient).iamconn
stsconn := meta.(*AWSClient).stsconn
region := meta.(*AWSClient).region
// An zero value GetUserInput{} defers to the currently logged in user
resp, err := iamconn.GetUser(&iam.GetUserInput{})

resp, err := stsconn.GetCallerIdentity(&sts.GetCallerIdentityInput{})
if err != nil {
return "", err
}
userARN := *resp.User.Arn
accountID := strings.Split(userARN, ":")[4]
accountID := *resp.Account
arn := fmt.Sprintf("arn:aws:rds:%s:%s:es:%s", region, accountID, identifier)
return arn, nil
}
11 changes: 5 additions & 6 deletions builtin/providers/aws/resource_aws_db_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import (

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/service/iam"
"github.com/aws/aws-sdk-go/service/rds"
"github.com/aws/aws-sdk-go/service/sts"

"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
Expand Down Expand Up @@ -973,15 +973,14 @@ func resourceAwsDbInstanceStateRefreshFunc(
}

func buildRDSARN(identifier string, meta interface{}) (string, error) {
iamconn := meta.(*AWSClient).iamconn
stsconn := meta.(*AWSClient).stsconn
region := meta.(*AWSClient).region
// An zero value GetUserInput{} defers to the currently logged in user
resp, err := iamconn.GetUser(&iam.GetUserInput{})

resp, err := stsconn.GetCallerIdentity(&sts.GetCallerIdentityInput{})
if err != nil {
return "", err
}
userARN := *resp.User.Arn
accountID := strings.Split(userARN, ":")[4]
accountID := *resp.Account
arn := fmt.Sprintf("arn:aws:rds:%s:%s:db:%s", region, accountID, identifier)
return arn, nil
}
11 changes: 5 additions & 6 deletions builtin/providers/aws/resource_aws_db_parameter_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import (

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/service/iam"
"github.com/aws/aws-sdk-go/service/rds"
"github.com/aws/aws-sdk-go/service/sts"
)

func resourceAwsDbParameterGroup() *schema.Resource {
Expand Down Expand Up @@ -272,15 +272,14 @@ func resourceAwsDbParameterHash(v interface{}) int {
}

func buildRDSPGARN(d *schema.ResourceData, meta interface{}) (string, error) {
iamconn := meta.(*AWSClient).iamconn
stsconn := meta.(*AWSClient).stsconn
region := meta.(*AWSClient).region
// An zero value GetUserInput{} defers to the currently logged in user
resp, err := iamconn.GetUser(&iam.GetUserInput{})

resp, err := stsconn.GetCallerIdentity(&sts.GetCallerIdentityInput{})
if err != nil {
return "", err
}
userARN := *resp.User.Arn
accountID := strings.Split(userARN, ":")[4]
accountID := *resp.Account
arn := fmt.Sprintf("arn:aws:rds:%s:%s:pg:%s", region, accountID, d.Id())
return arn, nil
}
12 changes: 5 additions & 7 deletions builtin/providers/aws/resource_aws_db_security_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@ import (
"bytes"
"fmt"
"log"
"strings"
"time"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/service/iam"
"github.com/aws/aws-sdk-go/service/rds"
"github.com/aws/aws-sdk-go/service/sts"
"github.com/hashicorp/go-multierror"
"github.com/hashicorp/terraform/helper/hashcode"
"github.com/hashicorp/terraform/helper/resource"
Expand Down Expand Up @@ -345,15 +344,14 @@ func resourceAwsDbSecurityGroupStateRefreshFunc(
}

func buildRDSSecurityGroupARN(d *schema.ResourceData, meta interface{}) (string, error) {
iamconn := meta.(*AWSClient).iamconn
stsconn := meta.(*AWSClient).stsconn
region := meta.(*AWSClient).region
// An zero value GetUserInput{} defers to the currently logged in user
resp, err := iamconn.GetUser(&iam.GetUserInput{})

resp, err := stsconn.GetCallerIdentity(&sts.GetCallerIdentityInput{})
if err != nil {
return "", err
}
userARN := *resp.User.Arn
accountID := strings.Split(userARN, ":")[4]
accountID := *resp.Account
arn := fmt.Sprintf("arn:aws:rds:%s:%s:secgrp:%s", region, accountID, d.Id())
return arn, nil
}
11 changes: 5 additions & 6 deletions builtin/providers/aws/resource_aws_db_subnet_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import (

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/service/iam"
"github.com/aws/aws-sdk-go/service/rds"
"github.com/aws/aws-sdk-go/service/sts"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
)
Expand Down Expand Up @@ -225,15 +225,14 @@ func resourceAwsDbSubnetGroupDeleteRefreshFunc(
}

func buildRDSsubgrpARN(d *schema.ResourceData, meta interface{}) (string, error) {
iamconn := meta.(*AWSClient).iamconn
stsconn := meta.(*AWSClient).stsconn
region := meta.(*AWSClient).region
// An zero value GetUserInput{} defers to the currently logged in user
resp, err := iamconn.GetUser(&iam.GetUserInput{})

resp, err := stsconn.GetCallerIdentity(&sts.GetCallerIdentityInput{})
if err != nil {
return "", err
}
userARN := *resp.User.Arn
accountID := strings.Split(userARN, ":")[4]
accountID := *resp.Account
arn := fmt.Sprintf("arn:aws:rds:%s:%s:subgrp:%s", region, accountID, d.Id())
return arn, nil
}
Expand Down
11 changes: 5 additions & 6 deletions builtin/providers/aws/resource_aws_elasticache_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/service/elasticache"
"github.com/aws/aws-sdk-go/service/iam"
"github.com/aws/aws-sdk-go/service/sts"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
)
Expand Down Expand Up @@ -619,15 +619,14 @@ func cacheClusterStateRefreshFunc(conn *elasticache.ElastiCache, clusterID, give
}

func buildECARN(d *schema.ResourceData, meta interface{}) (string, error) {
iamconn := meta.(*AWSClient).iamconn
stsconn := meta.(*AWSClient).stsconn
region := meta.(*AWSClient).region
// An zero value GetUserInput{} defers to the currently logged in user
resp, err := iamconn.GetUser(&iam.GetUserInput{})

resp, err := stsconn.GetCallerIdentity(&sts.GetCallerIdentityInput{})
if err != nil {
return "", err
}
userARN := *resp.User.Arn
accountID := strings.Split(userARN, ":")[4]
accountID := *resp.Account
arn := fmt.Sprintf("arn:aws:elasticache:%s:%s:cluster:%s", region, accountID, d.Id())
return arn, nil
}

0 comments on commit cb9873b

Please sign in to comment.