Parse AWS partition from ARN.

[Resolves #5307]
This commit is contained in:
Joshua Carp 2016-10-06 23:36:44 -04:00
parent a1d944b70b
commit 1f8c2e4c69
7 changed files with 82 additions and 43 deletions

View File

@ -21,7 +21,7 @@ import (
"github.com/hashicorp/go-cleanhttp" "github.com/hashicorp/go-cleanhttp"
) )
func GetAccountId(iamconn *iam.IAM, stsconn *sts.STS, authProviderName string) (string, error) { func GetAccountInfo(iamconn *iam.IAM, stsconn *sts.STS, authProviderName string) (string, string, error) {
// If we have creds from instance profile, we can use metadata API // If we have creds from instance profile, we can use metadata API
if authProviderName == ec2rolecreds.ProviderName { if authProviderName == ec2rolecreds.ProviderName {
log.Println("[DEBUG] Trying to get account ID via AWS Metadata API") log.Println("[DEBUG] Trying to get account ID via AWS Metadata API")
@ -30,7 +30,7 @@ func GetAccountId(iamconn *iam.IAM, stsconn *sts.STS, authProviderName string) (
setOptionalEndpoint(cfg) setOptionalEndpoint(cfg)
sess, err := session.NewSession(cfg) sess, err := session.NewSession(cfg)
if err != nil { if err != nil {
return "", errwrap.Wrapf("Error creating AWS session: %s", err) return "", "", errwrap.Wrapf("Error creating AWS session: %s", err)
} }
metadataClient := ec2metadata.New(sess) metadataClient := ec2metadata.New(sess)
@ -38,24 +38,24 @@ func GetAccountId(iamconn *iam.IAM, stsconn *sts.STS, authProviderName string) (
if err != nil { if err != nil {
// This can be triggered when no IAM Role is assigned // This can be triggered when no IAM Role is assigned
// or AWS just happens to return invalid response // or AWS just happens to return invalid response
return "", fmt.Errorf("Failed getting EC2 IAM info: %s", err) return "", "", fmt.Errorf("Failed getting EC2 IAM info: %s", err)
} }
return parseAccountIdFromArn(info.InstanceProfileArn) return parseAccountInfoFromArn(info.InstanceProfileArn)
} }
// Then try IAM GetUser // Then try IAM GetUser
log.Println("[DEBUG] Trying to get account ID via iam:GetUser") log.Println("[DEBUG] Trying to get account ID via iam:GetUser")
outUser, err := iamconn.GetUser(nil) outUser, err := iamconn.GetUser(nil)
if err == nil { if err == nil {
return parseAccountIdFromArn(*outUser.User.Arn) return parseAccountInfoFromArn(*outUser.User.Arn)
} }
awsErr, ok := err.(awserr.Error) awsErr, ok := err.(awserr.Error)
// AccessDenied and ValidationError can be raised // AccessDenied and ValidationError can be raised
// if credentials belong to federated profile, so we ignore these // if credentials belong to federated profile, so we ignore these
if !ok || (awsErr.Code() != "AccessDenied" && awsErr.Code() != "ValidationError") { if !ok || (awsErr.Code() != "AccessDenied" && awsErr.Code() != "ValidationError") {
return "", fmt.Errorf("Failed getting account ID via 'iam:GetUser': %s", err) return "", "", fmt.Errorf("Failed getting account ID via 'iam:GetUser': %s", err)
} }
log.Printf("[DEBUG] Getting account ID via iam:GetUser failed: %s", err) log.Printf("[DEBUG] Getting account ID via iam:GetUser failed: %s", err)
@ -63,7 +63,7 @@ func GetAccountId(iamconn *iam.IAM, stsconn *sts.STS, authProviderName string) (
log.Println("[DEBUG] Trying to get account ID via sts:GetCallerIdentity") log.Println("[DEBUG] Trying to get account ID via sts:GetCallerIdentity")
outCallerIdentity, err := stsconn.GetCallerIdentity(&sts.GetCallerIdentityInput{}) outCallerIdentity, err := stsconn.GetCallerIdentity(&sts.GetCallerIdentityInput{})
if err == nil { if err == nil {
return *outCallerIdentity.Account, nil return parseAccountInfoFromArn(*outCallerIdentity.Arn)
} }
log.Printf("[DEBUG] Getting account ID via sts:GetCallerIdentity failed: %s", err) log.Printf("[DEBUG] Getting account ID via sts:GetCallerIdentity failed: %s", err)
@ -73,22 +73,22 @@ func GetAccountId(iamconn *iam.IAM, stsconn *sts.STS, authProviderName string) (
MaxItems: aws.Int64(int64(1)), MaxItems: aws.Int64(int64(1)),
}) })
if err != nil { if err != nil {
return "", fmt.Errorf("Failed getting account ID via 'iam:ListRoles': %s", err) return "", "", fmt.Errorf("Failed getting account ID via 'iam:ListRoles': %s", err)
} }
if len(outRoles.Roles) < 1 { if len(outRoles.Roles) < 1 {
return "", errors.New("Failed getting account ID via 'iam:ListRoles': No roles available") return "", "", errors.New("Failed getting account ID via 'iam:ListRoles': No roles available")
} }
return parseAccountIdFromArn(*outRoles.Roles[0].Arn) return parseAccountInfoFromArn(*outRoles.Roles[0].Arn)
} }
func parseAccountIdFromArn(arn string) (string, error) { func parseAccountInfoFromArn(arn string) (string, string, error) {
parts := strings.Split(arn, ":") parts := strings.Split(arn, ":")
if len(parts) < 5 { if len(parts) < 5 {
return "", fmt.Errorf("Unable to parse ID from invalid ARN: %q", arn) return "", "", fmt.Errorf("Unable to parse ID from invalid ARN: %q", arn)
} }
return parts[4], nil return parts[1], parts[4], nil
} }
// This function is responsible for reading credentials from the // This function is responsible for reading credentials from the

View File

@ -21,7 +21,7 @@ import (
"github.com/aws/aws-sdk-go/service/sts" "github.com/aws/aws-sdk-go/service/sts"
) )
func TestAWSGetAccountId_shouldBeValid_fromEC2Role(t *testing.T) { func TestAWSGetAccountInfo_shouldBeValid_fromEC2Role(t *testing.T) {
resetEnv := unsetEnv(t) resetEnv := unsetEnv(t)
defer resetEnv() defer resetEnv()
// capture the test server's close method, to call after the test returns // capture the test server's close method, to call after the test returns
@ -32,18 +32,23 @@ func TestAWSGetAccountId_shouldBeValid_fromEC2Role(t *testing.T) {
ts, iamConn, stsConn := getMockedAwsIamStsApi(iamEndpoints) ts, iamConn, stsConn := getMockedAwsIamStsApi(iamEndpoints)
defer ts() defer ts()
id, err := GetAccountId(iamConn, stsConn, ec2rolecreds.ProviderName) part, id, err := GetAccountInfo(iamConn, stsConn, ec2rolecreds.ProviderName)
if err != nil { if err != nil {
t.Fatalf("Getting account ID from EC2 metadata API failed: %s", err) t.Fatalf("Getting account ID from EC2 metadata API failed: %s", err)
} }
expectedPart := "aws"
if part != expectedPart {
t.Fatalf("Expected partition: %s, given: %s", expectedPart, part)
}
expectedAccountId := "123456789013" expectedAccountId := "123456789013"
if id != expectedAccountId { if id != expectedAccountId {
t.Fatalf("Expected account ID: %s, given: %s", expectedAccountId, id) t.Fatalf("Expected account ID: %s, given: %s", expectedAccountId, id)
} }
} }
func TestAWSGetAccountId_shouldBeValid_EC2RoleHasPriority(t *testing.T) { func TestAWSGetAccountInfo_shouldBeValid_EC2RoleHasPriority(t *testing.T) {
resetEnv := unsetEnv(t) resetEnv := unsetEnv(t)
defer resetEnv() defer resetEnv()
// capture the test server's close method, to call after the test returns // capture the test server's close method, to call after the test returns
@ -59,18 +64,23 @@ func TestAWSGetAccountId_shouldBeValid_EC2RoleHasPriority(t *testing.T) {
ts, iamConn, stsConn := getMockedAwsIamStsApi(iamEndpoints) ts, iamConn, stsConn := getMockedAwsIamStsApi(iamEndpoints)
defer ts() defer ts()
id, err := GetAccountId(iamConn, stsConn, ec2rolecreds.ProviderName) part, id, err := GetAccountInfo(iamConn, stsConn, ec2rolecreds.ProviderName)
if err != nil { if err != nil {
t.Fatalf("Getting account ID from EC2 metadata API failed: %s", err) t.Fatalf("Getting account ID from EC2 metadata API failed: %s", err)
} }
expectedPart := "aws"
if part != expectedPart {
t.Fatalf("Expected partition: %s, given: %s", expectedPart, part)
}
expectedAccountId := "123456789013" expectedAccountId := "123456789013"
if id != expectedAccountId { if id != expectedAccountId {
t.Fatalf("Expected account ID: %s, given: %s", expectedAccountId, id) t.Fatalf("Expected account ID: %s, given: %s", expectedAccountId, id)
} }
} }
func TestAWSGetAccountId_shouldBeValid_fromIamUser(t *testing.T) { func TestAWSGetAccountInfo_shouldBeValid_fromIamUser(t *testing.T) {
iamEndpoints := []*iamEndpoint{ iamEndpoints := []*iamEndpoint{
{ {
Request: &iamRequest{"POST", "/", "Action=GetUser&Version=2010-05-08"}, Request: &iamRequest{"POST", "/", "Action=GetUser&Version=2010-05-08"},
@ -81,18 +91,23 @@ func TestAWSGetAccountId_shouldBeValid_fromIamUser(t *testing.T) {
ts, iamConn, stsConn := getMockedAwsIamStsApi(iamEndpoints) ts, iamConn, stsConn := getMockedAwsIamStsApi(iamEndpoints)
defer ts() defer ts()
id, err := GetAccountId(iamConn, stsConn, "") part, id, err := GetAccountInfo(iamConn, stsConn, "")
if err != nil { if err != nil {
t.Fatalf("Getting account ID via GetUser failed: %s", err) t.Fatalf("Getting account ID via GetUser failed: %s", err)
} }
expectedPart := "aws"
if part != expectedPart {
t.Fatalf("Expected partition: %s, given: %s", expectedPart, part)
}
expectedAccountId := "123456789012" expectedAccountId := "123456789012"
if id != expectedAccountId { if id != expectedAccountId {
t.Fatalf("Expected account ID: %s, given: %s", expectedAccountId, id) t.Fatalf("Expected account ID: %s, given: %s", expectedAccountId, id)
} }
} }
func TestAWSGetAccountId_shouldBeValid_fromGetCallerIdentity(t *testing.T) { func TestAWSGetAccountInfo_shouldBeValid_fromGetCallerIdentity(t *testing.T) {
iamEndpoints := []*iamEndpoint{ iamEndpoints := []*iamEndpoint{
{ {
Request: &iamRequest{"POST", "/", "Action=GetUser&Version=2010-05-08"}, Request: &iamRequest{"POST", "/", "Action=GetUser&Version=2010-05-08"},
@ -106,18 +121,23 @@ func TestAWSGetAccountId_shouldBeValid_fromGetCallerIdentity(t *testing.T) {
ts, iamConn, stsConn := getMockedAwsIamStsApi(iamEndpoints) ts, iamConn, stsConn := getMockedAwsIamStsApi(iamEndpoints)
defer ts() defer ts()
id, err := GetAccountId(iamConn, stsConn, "") part, id, err := GetAccountInfo(iamConn, stsConn, "")
if err != nil { if err != nil {
t.Fatalf("Getting account ID via GetUser failed: %s", err) t.Fatalf("Getting account ID via GetUser failed: %s", err)
} }
expectedPart := "aws"
if part != expectedPart {
t.Fatalf("Expected partition: %s, given: %s", expectedPart, part)
}
expectedAccountId := "123456789012" expectedAccountId := "123456789012"
if id != expectedAccountId { if id != expectedAccountId {
t.Fatalf("Expected account ID: %s, given: %s", expectedAccountId, id) t.Fatalf("Expected account ID: %s, given: %s", expectedAccountId, id)
} }
} }
func TestAWSGetAccountId_shouldBeValid_fromIamListRoles(t *testing.T) { func TestAWSGetAccountInfo_shouldBeValid_fromIamListRoles(t *testing.T) {
iamEndpoints := []*iamEndpoint{ iamEndpoints := []*iamEndpoint{
{ {
Request: &iamRequest{"POST", "/", "Action=GetUser&Version=2010-05-08"}, Request: &iamRequest{"POST", "/", "Action=GetUser&Version=2010-05-08"},
@ -135,18 +155,23 @@ func TestAWSGetAccountId_shouldBeValid_fromIamListRoles(t *testing.T) {
ts, iamConn, stsConn := getMockedAwsIamStsApi(iamEndpoints) ts, iamConn, stsConn := getMockedAwsIamStsApi(iamEndpoints)
defer ts() defer ts()
id, err := GetAccountId(iamConn, stsConn, "") part, id, err := GetAccountInfo(iamConn, stsConn, "")
if err != nil { if err != nil {
t.Fatalf("Getting account ID via ListRoles failed: %s", err) t.Fatalf("Getting account ID via ListRoles failed: %s", err)
} }
expectedPart := "aws"
if part != expectedPart {
t.Fatalf("Expected partition: %s, given: %s", expectedPart, part)
}
expectedAccountId := "123456789012" expectedAccountId := "123456789012"
if id != expectedAccountId { if id != expectedAccountId {
t.Fatalf("Expected account ID: %s, given: %s", expectedAccountId, id) t.Fatalf("Expected account ID: %s, given: %s", expectedAccountId, id)
} }
} }
func TestAWSGetAccountId_shouldBeValid_federatedRole(t *testing.T) { func TestAWSGetAccountInfo_shouldBeValid_federatedRole(t *testing.T) {
iamEndpoints := []*iamEndpoint{ iamEndpoints := []*iamEndpoint{
{ {
Request: &iamRequest{"POST", "/", "Action=GetUser&Version=2010-05-08"}, Request: &iamRequest{"POST", "/", "Action=GetUser&Version=2010-05-08"},
@ -160,18 +185,23 @@ func TestAWSGetAccountId_shouldBeValid_federatedRole(t *testing.T) {
ts, iamConn, stsConn := getMockedAwsIamStsApi(iamEndpoints) ts, iamConn, stsConn := getMockedAwsIamStsApi(iamEndpoints)
defer ts() defer ts()
id, err := GetAccountId(iamConn, stsConn, "") part, id, err := GetAccountInfo(iamConn, stsConn, "")
if err != nil { if err != nil {
t.Fatalf("Getting account ID via ListRoles failed: %s", err) t.Fatalf("Getting account ID via ListRoles failed: %s", err)
} }
expectedPart := "aws"
if part != expectedPart {
t.Fatalf("Expected partition: %s, given: %s", expectedPart, part)
}
expectedAccountId := "123456789012" expectedAccountId := "123456789012"
if id != expectedAccountId { if id != expectedAccountId {
t.Fatalf("Expected account ID: %s, given: %s", expectedAccountId, id) t.Fatalf("Expected account ID: %s, given: %s", expectedAccountId, id)
} }
} }
func TestAWSGetAccountId_shouldError_unauthorizedFromIam(t *testing.T) { func TestAWSGetAccountInfo_shouldError_unauthorizedFromIam(t *testing.T) {
iamEndpoints := []*iamEndpoint{ iamEndpoints := []*iamEndpoint{
{ {
Request: &iamRequest{"POST", "/", "Action=GetUser&Version=2010-05-08"}, Request: &iamRequest{"POST", "/", "Action=GetUser&Version=2010-05-08"},
@ -185,29 +215,37 @@ func TestAWSGetAccountId_shouldError_unauthorizedFromIam(t *testing.T) {
ts, iamConn, stsConn := getMockedAwsIamStsApi(iamEndpoints) ts, iamConn, stsConn := getMockedAwsIamStsApi(iamEndpoints)
defer ts() defer ts()
id, err := GetAccountId(iamConn, stsConn, "") part, id, err := GetAccountInfo(iamConn, stsConn, "")
if err == nil { if err == nil {
t.Fatal("Expected error when getting account ID") t.Fatal("Expected error when getting account ID")
} }
if part != "" {
t.Fatalf("Expected no partition, given: %s", part)
}
if id != "" { if id != "" {
t.Fatalf("Expected no account ID, given: %s", id) t.Fatalf("Expected no account ID, given: %s", id)
} }
} }
func TestAWSParseAccountIdFromArn(t *testing.T) { func TestAWSParseAccountInfoFromArn(t *testing.T) {
validArn := "arn:aws:iam::101636750127:instance-profile/aws-elasticbeanstalk-ec2-role" validArn := "arn:aws:iam::101636750127:instance-profile/aws-elasticbeanstalk-ec2-role"
expectedPart := "aws"
expectedId := "101636750127" expectedId := "101636750127"
id, err := parseAccountIdFromArn(validArn) part, id, err := parseAccountInfoFromArn(validArn)
if err != nil { if err != nil {
t.Fatalf("Expected no error when parsing valid ARN: %s", err) t.Fatalf("Expected no error when parsing valid ARN: %s", err)
} }
if part != expectedPart {
t.Fatalf("Parsed part doesn't match with expected (%q != %q)", part, expectedPart)
}
if id != expectedId { if id != expectedId {
t.Fatalf("Parsed id doesn't match with expected (%q != %q)", id, expectedId) t.Fatalf("Parsed id doesn't match with expected (%q != %q)", id, expectedId)
} }
invalidArn := "blablah" invalidArn := "blablah"
id, err = parseAccountIdFromArn(invalidArn) part, id, err = parseAccountInfoFromArn(invalidArn)
if err == nil { if err == nil {
t.Fatalf("Expected error when parsing invalid ARN (%q)", invalidArn) t.Fatalf("Expected error when parsing invalid ARN (%q)", invalidArn)
} }

View File

@ -118,6 +118,7 @@ type AWSClient struct {
stsconn *sts.STS stsconn *sts.STS
redshiftconn *redshift.Redshift redshiftconn *redshift.Redshift
r53conn *route53.Route53 r53conn *route53.Route53
partition string
accountid string accountid string
region string region string
rdsconn *rds.RDS rdsconn *rds.RDS
@ -226,8 +227,9 @@ func (c *Config) Client() (interface{}, error) {
} }
if !c.SkipRequestingAccountId { if !c.SkipRequestingAccountId {
accountId, err := GetAccountId(client.iamconn, client.stsconn, cp.ProviderName) partition, accountId, err := GetAccountInfo(client.iamconn, client.stsconn, cp.ProviderName)
if err == nil { if err == nil {
client.partition = partition
client.accountid = accountId client.accountid = accountId
} }
} }

View File

@ -693,7 +693,7 @@ func resourceAwsDbInstanceRead(d *schema.ResourceData, meta interface{}) error {
// list tags for resource // list tags for resource
// set tags // set tags
conn := meta.(*AWSClient).rdsconn conn := meta.(*AWSClient).rdsconn
arn, err := buildRDSARN(d.Id(), meta.(*AWSClient).accountid, meta.(*AWSClient).region) arn, err := buildRDSARN(d.Id(), meta.(*AWSClient).partition, meta.(*AWSClient).accountid, meta.(*AWSClient).region)
if err != nil { if err != nil {
name := "<empty>" name := "<empty>"
if v.DBName != nil && *v.DBName != "" { if v.DBName != nil && *v.DBName != "" {
@ -976,7 +976,7 @@ func resourceAwsDbInstanceUpdate(d *schema.ResourceData, meta interface{}) error
} }
} }
if arn, err := buildRDSARN(d.Id(), meta.(*AWSClient).accountid, meta.(*AWSClient).region); err == nil { if arn, err := buildRDSARN(d.Id(), meta.(*AWSClient).partition, meta.(*AWSClient).accountid, meta.(*AWSClient).region); err == nil {
if err := setTagsRDS(conn, d, arn); err != nil { if err := setTagsRDS(conn, d, arn); err != nil {
return err return err
} else { } else {
@ -1052,11 +1052,10 @@ func resourceAwsDbInstanceStateRefreshFunc(
} }
} }
func buildRDSARN(identifier, accountid, region string) (string, error) { func buildRDSARN(identifier, partition, accountid, region string) (string, error) {
if accountid == "" { if accountid == "" {
return "", fmt.Errorf("Unable to construct RDS ARN because of missing AWS Account ID") return "", fmt.Errorf("Unable to construct RDS ARN because of missing AWS Account ID")
} }
arn := fmt.Sprintf("arn:aws:rds:%s:%s:db:%s", region, accountid, identifier) arn := fmt.Sprintf("arn:%s:rds:%s:%s:db:%s", partition, region, accountid, identifier)
return arn, nil return arn, nil
} }

View File

@ -350,7 +350,7 @@ func testAccCheckAWSDBInstanceSnapshot(s *terraform.State) error {
} }
} else { // snapshot was found, } else { // snapshot was found,
// verify we have the tags copied to the snapshot // verify we have the tags copied to the snapshot
instanceARN, err := buildRDSARN(snapshot_identifier, testAccProvider.Meta().(*AWSClient).accountid, testAccProvider.Meta().(*AWSClient).region) instanceARN, err := buildRDSARN(snapshot_identifier, testAccProvider.Meta().(*AWSClient).partition, testAccProvider.Meta().(*AWSClient).accountid, testAccProvider.Meta().(*AWSClient).region)
// tags have a different ARN, just swapping :db: for :snapshot: // tags have a different ARN, just swapping :db: for :snapshot:
tagsARN := strings.Replace(instanceARN, ":db:", ":snapshot:", 1) tagsARN := strings.Replace(instanceARN, ":db:", ":snapshot:", 1)
if err != nil { if err != nil {

View File

@ -467,7 +467,7 @@ func resourceAwsRDSClusterRead(d *schema.ResourceData, meta interface{}) error {
} }
// Fetch and save tags // Fetch and save tags
arn, err := buildRDSClusterARN(d.Id(), meta.(*AWSClient).accountid, meta.(*AWSClient).region) arn, err := buildRDSClusterARN(d.Id(), meta.(*AWSClient).partition, meta.(*AWSClient).accountid, meta.(*AWSClient).region)
if err != nil { if err != nil {
log.Printf("[DEBUG] Error building ARN for RDS Cluster (%s), not setting Tags", *dbc.DBClusterIdentifier) log.Printf("[DEBUG] Error building ARN for RDS Cluster (%s), not setting Tags", *dbc.DBClusterIdentifier)
} else { } else {
@ -536,7 +536,7 @@ func resourceAwsRDSClusterUpdate(d *schema.ResourceData, meta interface{}) error
} }
} }
if arn, err := buildRDSClusterARN(d.Id(), meta.(*AWSClient).accountid, meta.(*AWSClient).region); err == nil { if arn, err := buildRDSClusterARN(d.Id(), meta.(*AWSClient).partition, meta.(*AWSClient).accountid, meta.(*AWSClient).region); err == nil {
if err := setTagsRDS(conn, d, arn); err != nil { if err := setTagsRDS(conn, d, arn); err != nil {
return err return err
} else { } else {
@ -625,12 +625,12 @@ func resourceAwsRDSClusterStateRefreshFunc(
} }
} }
func buildRDSClusterARN(identifier, accountid, region string) (string, error) { func buildRDSClusterARN(identifier, partition, accountid, region string) (string, error) {
if accountid == "" { if accountid == "" {
return "", fmt.Errorf("Unable to construct RDS Cluster ARN because of missing AWS Account ID") return "", fmt.Errorf("Unable to construct RDS Cluster ARN because of missing AWS Account ID")
} }
arn := fmt.Sprintf("arn:aws:rds:%s:%s:cluster:%s", region, accountid, identifier) arn := fmt.Sprintf("arn:%s:rds:%s:%s:cluster:%s", partition, region, accountid, identifier)
return arn, nil return arn, nil
} }

View File

@ -245,7 +245,7 @@ func resourceAwsRDSClusterInstanceRead(d *schema.ResourceData, meta interface{})
} }
// Fetch and save tags // Fetch and save tags
arn, err := buildRDSARN(d.Id(), meta.(*AWSClient).accountid, meta.(*AWSClient).region) arn, err := buildRDSARN(d.Id(), meta.(*AWSClient).partition, meta.(*AWSClient).accountid, meta.(*AWSClient).region)
if err != nil { if err != nil {
log.Printf("[DEBUG] Error building ARN for RDS Cluster Instance (%s), not setting Tags", *db.DBInstanceIdentifier) log.Printf("[DEBUG] Error building ARN for RDS Cluster Instance (%s), not setting Tags", *db.DBInstanceIdentifier)
} else { } else {
@ -322,7 +322,7 @@ func resourceAwsRDSClusterInstanceUpdate(d *schema.ResourceData, meta interface{
} }
if arn, err := buildRDSARN(d.Id(), meta.(*AWSClient).accountid, meta.(*AWSClient).region); err == nil { if arn, err := buildRDSARN(d.Id(), meta.(*AWSClient).partition, meta.(*AWSClient).accountid, meta.(*AWSClient).region); err == nil {
if err := setTagsRDS(conn, d, arn); err != nil { if err := setTagsRDS(conn, d, arn); err != nil {
return err return err
} }