Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

provider: Authentication updates for Terraform AWS Provider v3.0.0 #14077

Merged
merged 3 commits into from
Jul 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 33 additions & 24 deletions aws/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,14 @@ type Config struct {
Region string
MaxRetries int

AssumeRoleARN string
AssumeRoleExternalID string
AssumeRoleSessionName string
AssumeRolePolicy string
AssumeRoleARN string
AssumeRoleDurationSeconds int
AssumeRoleExternalID string
AssumeRolePolicy string
AssumeRolePolicyARNs []string
AssumeRoleSessionName string
AssumeRoleTags map[string]string
AssumeRoleTransitiveTagKeys []string

AllowedAccountIds []string
ForbiddenAccountIds []string
Expand Down Expand Up @@ -365,26 +369,31 @@ func (c *Config) Client() (interface{}, error) {
}
}

log.Println("[INFO] Building AWS auth structure")
awsbaseConfig := &awsbase.Config{
AccessKey: c.AccessKey,
AssumeRoleARN: c.AssumeRoleARN,
AssumeRoleExternalID: c.AssumeRoleExternalID,
AssumeRolePolicy: c.AssumeRolePolicy,
AssumeRoleSessionName: c.AssumeRoleSessionName,
CredsFilename: c.CredsFilename,
DebugLogging: logging.IsDebugOrHigher(),
IamEndpoint: c.Endpoints["iam"],
Insecure: c.Insecure,
MaxRetries: c.MaxRetries,
Profile: c.Profile,
Region: c.Region,
SecretKey: c.SecretKey,
SkipCredsValidation: c.SkipCredsValidation,
SkipMetadataApiCheck: c.SkipMetadataApiCheck,
SkipRequestingAccountId: c.SkipRequestingAccountId,
StsEndpoint: c.Endpoints["sts"],
Token: c.Token,
AccessKey: c.AccessKey,
AssumeRoleARN: c.AssumeRoleARN,
AssumeRoleDurationSeconds: c.AssumeRoleDurationSeconds,
AssumeRoleExternalID: c.AssumeRoleExternalID,
AssumeRolePolicy: c.AssumeRolePolicy,
AssumeRolePolicyARNs: c.AssumeRolePolicyARNs,
AssumeRoleSessionName: c.AssumeRoleSessionName,
AssumeRoleTags: c.AssumeRoleTags,
AssumeRoleTransitiveTagKeys: c.AssumeRoleTransitiveTagKeys,
CallerDocumentationURL: "https://registry.terraform.io/providers/hashicorp/aws",
CallerName: "Terraform AWS Provider",
CredsFilename: c.CredsFilename,
DebugLogging: logging.IsDebugOrHigher(),
IamEndpoint: c.Endpoints["iam"],
Insecure: c.Insecure,
MaxRetries: c.MaxRetries,
Profile: c.Profile,
Region: c.Region,
SecretKey: c.SecretKey,
SkipCredsValidation: c.SkipCredsValidation,
SkipMetadataApiCheck: c.SkipMetadataApiCheck,
SkipRequestingAccountId: c.SkipRequestingAccountId,
StsEndpoint: c.Endpoints["sts"],
Token: c.Token,
UserAgentProducts: []*awsbase.UserAgentProduct{
{Name: "APN", Version: "1.0"},
{Name: "HashiCorp", Version: "1.0"},
Expand All @@ -395,7 +404,7 @@ func (c *Config) Client() (interface{}, error) {

sess, accountID, partition, err := awsbase.GetSessionWithAccountIDAndPartition(awsbaseConfig)
if err != nil {
return nil, err
return nil, fmt.Errorf("error configuring Terraform AWS Provider: %w", err)
}

if accountID == "" {
Expand Down
138 changes: 91 additions & 47 deletions aws/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/helper/mutexkv"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/terraform"
homedir "github.com/mitchellh/go-homedir"

"github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags"
)
Expand Down Expand Up @@ -1017,18 +1016,6 @@ func init() {
"i.e., http://s3.amazonaws.com/BUCKET/KEY. By default, the S3 client will\n" +
"use virtual hosted bucket addressing when possible\n" +
"(http://BUCKET.s3.amazonaws.com/KEY). Specific to the Amazon S3 service.",

"assume_role_role_arn": "The ARN of an IAM role to assume prior to making API calls.",

"assume_role_session_name": "The session name to use when assuming the role. If omitted," +
" no session name is passed to the AssumeRole call.",

"assume_role_external_id": "The external ID to use when assuming the role. If omitted," +
" no external ID is passed to the AssumeRole call.",

"assume_role_policy": "The permissions applied when assuming a role. You cannot use," +
" this policy to grant further permissions that are in excess to those of the, " +
" role that is being assumed.",
}

endpointServiceNames = []string{
Expand Down Expand Up @@ -1183,6 +1170,7 @@ func providerConfigure(d *schema.ResourceData, terraformVersion string) (interfa
Profile: d.Get("profile").(string),
Token: d.Get("token").(string),
Region: d.Get("region").(string),
CredsFilename: d.Get("shared_credentials_file").(string),
Endpoints: make(map[string]string),
MaxRetries: d.Get("max_retries").(int),
IgnoreTagsConfig: expandProviderIgnoreTags(d.Get("ignore_tags").([]interface{})),
Expand All @@ -1196,32 +1184,68 @@ func providerConfigure(d *schema.ResourceData, terraformVersion string) (interfa
terraformVersion: terraformVersion,
}

// Set CredsFilename, expanding home directory
credsPath, err := homedir.Expand(d.Get("shared_credentials_file").(string))
if err != nil {
return nil, err
}
config.CredsFilename = credsPath

assumeRoleList := d.Get("assume_role").([]interface{})
if len(assumeRoleList) == 1 {
if assumeRoleList[0] != nil {
assumeRole := assumeRoleList[0].(map[string]interface{})
config.AssumeRoleARN = assumeRole["role_arn"].(string)
config.AssumeRoleSessionName = assumeRole["session_name"].(string)
config.AssumeRoleExternalID = assumeRole["external_id"].(string)

if v := assumeRole["policy"].(string); v != "" {
config.AssumeRolePolicy = v
if l, ok := d.Get("assume_role").([]interface{}); ok && len(l) > 0 && l[0] != nil {
m := l[0].(map[string]interface{})

if v, ok := m["duration_seconds"].(int); ok && v != 0 {
config.AssumeRoleDurationSeconds = v
}

if v, ok := m["external_id"].(string); ok && v != "" {
config.AssumeRoleExternalID = v
}

if v, ok := m["policy"].(string); ok && v != "" {
config.AssumeRolePolicy = v
}

if policyARNSet, ok := m["policy_arns"].(*schema.Set); ok && policyARNSet.Len() > 0 {
for _, policyARNRaw := range policyARNSet.List() {
policyARN, ok := policyARNRaw.(string)

if !ok {
continue
}

config.AssumeRolePolicyARNs = append(config.AssumeRolePolicyARNs, policyARN)
}
}

if v, ok := m["role_arn"].(string); ok && v != "" {
config.AssumeRoleARN = v
}

if v, ok := m["session_name"].(string); ok && v != "" {
config.AssumeRoleSessionName = v
}

if tagMapRaw, ok := m["tags"].(map[string]interface{}); ok && len(tagMapRaw) > 0 {
config.AssumeRoleTags = make(map[string]string)

for k, vRaw := range tagMapRaw {
v, ok := vRaw.(string)

if !ok {
continue
}

config.AssumeRoleTags[k] = v
}
}

if transitiveTagKeySet, ok := m["transitive_tag_keys"].(*schema.Set); ok && transitiveTagKeySet.Len() > 0 {
for _, transitiveTagKeyRaw := range transitiveTagKeySet.List() {
transitiveTagKey, ok := transitiveTagKeyRaw.(string)

if !ok {
continue
}

log.Printf("[INFO] assume_role configuration set: (ARN: %q, SessionID: %q, ExternalID: %q, Policy: %q)",
config.AssumeRoleARN, config.AssumeRoleSessionName, config.AssumeRoleExternalID, config.AssumeRolePolicy)
} else {
log.Printf("[INFO] Empty assume_role block read from configuration")
config.AssumeRoleTransitiveTagKeys = append(config.AssumeRoleTransitiveTagKeys, transitiveTagKey)
}
}
} else {
log.Printf("[INFO] No assume_role block read from configuration")

log.Printf("[INFO] assume_role configuration set: (ARN: %q, SessionID: %q, ExternalID: %q)", config.AssumeRoleARN, config.AssumeRoleSessionName, config.AssumeRoleExternalID)
}

endpointsSet := d.Get("endpoints").(*schema.Set)
Expand Down Expand Up @@ -1258,28 +1282,48 @@ func assumeRoleSchema() *schema.Schema {
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"role_arn": {
"duration_seconds": {
Type: schema.TypeInt,
Optional: true,
Description: "Seconds to restrict the assume role session duration.",
},
"external_id": {
Type: schema.TypeString,
Optional: true,
Description: descriptions["assume_role_role_arn"],
Description: "Unique identifier that might be required for assuming a role in another account.",
},

"session_name": {
"policy": {
Type: schema.TypeString,
Optional: true,
Description: descriptions["assume_role_session_name"],
Description: "IAM Policy JSON describing further restricting permissions for the IAM Role being assumed.",
},

"external_id": {
"policy_arns": {
Type: schema.TypeSet,
Optional: true,
Description: "Amazon Resource Names (ARNs) of IAM Policies describing further restricting permissions for the IAM Role being assumed.",
Elem: &schema.Schema{Type: schema.TypeString},
},
"role_arn": {
Type: schema.TypeString,
Optional: true,
Description: descriptions["assume_role_external_id"],
Description: "Amazon Resource Name of an IAM Role to assume prior to making API calls.",
},

"policy": {
"session_name": {
Type: schema.TypeString,
Optional: true,
Description: descriptions["assume_role_policy"],
Description: "Identifier for the assumed role session.",
},
"tags": {
Type: schema.TypeMap,
Optional: true,
Description: "Assume role session tags.",
Elem: &schema.Schema{Type: schema.TypeString},
},
"transitive_tag_keys": {
Type: schema.TypeSet,
Optional: true,
Description: "Assume role session tag keys to pass to any subsequent sessions.",
Elem: &schema.Schema{Type: schema.TypeString},
},
},
},
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ require (
github.com/bflad/tfproviderlint v0.14.0
github.com/client9/misspell v0.3.4
github.com/golangci/golangci-lint v1.26.0
github.com/hashicorp/aws-sdk-go-base v0.4.0
github.com/hashicorp/aws-sdk-go-base v0.5.0
github.com/hashicorp/go-cleanhttp v0.5.1
github.com/hashicorp/go-multierror v1.1.0
github.com/hashicorp/go-version v1.2.1
Expand Down
5 changes: 3 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM=
github.com/aws/aws-sdk-go v1.25.3/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.31.9/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
github.com/aws/aws-sdk-go v1.32.12 h1:l/djCeLI4ggBFWLlYUGTqkHraoLnVMubNlLXPdEtoYc=
github.com/aws/aws-sdk-go v1.32.12/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
github.com/beevik/etree v1.1.0 h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs=
Expand Down Expand Up @@ -217,8 +218,8 @@ github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.m
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/aws-sdk-go-base v0.4.0 h1:zH9hNUdsS+2G0zJaU85ul8D59BGnZBaKM+KMNPAHGwk=
github.com/hashicorp/aws-sdk-go-base v0.4.0/go.mod h1:eRhlz3c4nhqxFZJAahJEFL7gh6Jyj5rQmQc7F9eHFyQ=
github.com/hashicorp/aws-sdk-go-base v0.5.0 h1:fk7ID0v3PWL/KNL8FvkBPu8Sm93EPUCCmtZCiTXLySE=
github.com/hashicorp/aws-sdk-go-base v0.5.0/go.mod h1:2fRjWDv3jJBeN6mVWFHV6hFTNeFBx2gpDLQaZNxUVAY=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.0 h1:wvCrVc9TjDls6+YGAF2hAifE1E5U1+b4tH6KdvN3Gig=
Expand Down
7 changes: 7 additions & 0 deletions vendor/github.com/hashicorp/aws-sdk-go-base/.golangci.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 0 additions & 20 deletions vendor/github.com/hashicorp/aws-sdk-go-base/.travis.yml

This file was deleted.

22 changes: 22 additions & 0 deletions vendor/github.com/hashicorp/aws-sdk-go-base/CHANGELOG.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading