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

Ensure we validate credentials correctly #2004

Merged
merged 1 commit into from
Jun 15, 2022
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
4 changes: 2 additions & 2 deletions provider/cmd/pulumi-resource-aws/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@
"skipCredentialsValidation": {
"type": "boolean",
"description": "Skip the credentials validation via STS API. Used for AWS API implementations that do not have STS\navailable/implemented.\n",
"default": true
"default": false
},
"skipGetEc2Platforms": {
"type": "boolean",
Expand Down Expand Up @@ -211399,7 +211399,7 @@
"skipCredentialsValidation": {
"type": "boolean",
"description": "Skip the credentials validation via STS API. Used for AWS API implementations that do not have STS\navailable/implemented.\n",
"default": true
"default": false
},
"skipGetEc2Platforms": {
"type": "boolean",
Expand Down
128 changes: 76 additions & 52 deletions provider/resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,18 @@
package provider

import (
"context"
"fmt"
"math/rand"
"os"
"path/filepath"
"strings"
"unicode"

"github.com/aws/aws-sdk-go-v2/feature/ec2/imds"
awsbase "github.com/hashicorp/aws-sdk-go-base/v2"
awsShim "github.com/hashicorp/terraform-provider-aws/shim"
"github.com/mitchellh/go-homedir"
"github.com/pulumi/pulumi-aws/provider/v5/pkg/version"
"github.com/pulumi/pulumi-terraform-bridge/v3/pkg/tfbridge"
shim "github.com/pulumi/pulumi-terraform-bridge/v3/pkg/tfshim"
Expand Down Expand Up @@ -270,55 +274,78 @@ func stringRef(s string) *string {
// configuration subset of `github.com/terraform-providers/terraform-provider-aws/aws.providerConfigure`. We do this
// before passing control to the TF provider to ensure we can report actionable errors.
func preConfigureCallback(vars resource.PropertyMap, c shim.ResourceConfig) error {
// Don't event attempt any credentialsValidation at all while we get to the bottom of
// https://github.com/pulumi/pulumi-aws/issues/199
return nil
var skipCredentialsValidation bool
if val, ok := vars["skipCredentialsValidation"]; ok {
if val.IsBool() {
skipCredentialsValidation = val.BoolValue()
}
}

// if we skipCredentialsValidation then we don't need to do anything in
// preConfigureCallback as this is an explicit operation
if skipCredentialsValidation {
return nil
}

config := &awsbase.Config{
AccessKey: stringValue(vars, "accessKey", []string{"AWS_ACCESS_KEY_ID"}),
SecretKey: stringValue(vars, "secretKey", []string{"AWS_SECRET_ACCESS_KEY"}),
Profile: stringValue(vars, "profile", []string{"AWS_PROFILE"}),
Token: stringValue(vars, "token", []string{"AWS_SESSION_TOKEN"}),
Region: stringValue(vars, "region", []string{"AWS_REGION", "AWS_DEFAULT_REGION"}),
}

if details, ok := vars["assumeRole"]; ok {
assumeRoleDetails := resource.NewPropertyMap(details)
assumeRole := awsbase.AssumeRole{
RoleARN: stringValue(assumeRoleDetails, "roleArn", []string{}),
ExternalID: stringValue(assumeRoleDetails, "externalId", []string{}),
Policy: stringValue(assumeRoleDetails, "policy", []string{}),
SessionName: stringValue(assumeRoleDetails, "sessionName", []string{}),
}
config.AssumeRole = &assumeRole
}

// By default `skipMetadataApiCheck` is true for Pulumi to speed operations
// if we want to authenticate against the AWS API Metadata Service then the user
// will specify that skipMetadataApiCheck: false
// therefore, if we have skipMetadataApiCheck false, then we are enabling the imds client
config.EC2MetadataServiceEnableState = imds.ClientDisabled
if val, ok := vars["skipMetadataApiCheck"]; ok {
if val.IsBool() && !val.BoolValue() {
config.EC2MetadataServiceEnableState = imds.ClientEnabled
}
}

//var skipCredentialsValidation bool
//if val, ok := vars["skipCredentialsValidation"]; ok {
// if val.IsBool() {
// skipCredentialsValidation = val.BoolValue()
// }
//}
//
//// if we skipCredentialsValidation then we don't need to do anything in
//// preConfigureCallback as this is an explict operation
//if skipCredentialsValidation {
// return nil
//}
//
//config := &awsbase.Config{
// AccessKey: stringValue(vars, "accessKey", []string{"AWS_ACCESS_KEY_ID"}),
// SecretKey: stringValue(vars, "secretKey", []string{"AWS_SECRET_ACCESS_KEY"}),
// Profile: stringValue(vars, "profile", []string{"AWS_PROFILE"}),
// Token: stringValue(vars, "token", []string{"AWS_SESSION_TOKEN"}),
// Region: stringValue(vars, "region", []string{"AWS_REGION", "AWS_DEFAULT_REGION"}),
//}
//
//// By default `skipMetadataApiCheck` is true for Pulumi to speed operations
//// if we want to authenticate against the AWS API Metadata Service then the user
//// will specify that skipMetadataApiCheck: false
//// therefore, if we have skipMetadataApiCheck false, then we are enabling the imds client
//config.EC2MetadataServiceEnableState = imds.ClientDisabled
//if val, ok := vars["skipMetadataApiCheck"]; ok {
// if val.IsBool() && !val.BoolValue() {
// config.EC2MetadataServiceEnableState = imds.ClientEnabled
// }
//}
//
//sharedCredentialsFile := stringValue(vars, "sharedCredentialsFile", []string{"AWS_SHARED_CREDENTIALS_FILE"})
//credsPath, err := homedir.Expand(sharedCredentialsFile)
//if err != nil {
// return err
//}
//config.SharedCredentialsFiles = []string{credsPath}
//
//if _, err := awsbase.GetAwsConfig(context.Background(), config); err != nil {
// return fmt.Errorf("unable to validate AWS AccessKeyID and/or SecretAccessKey " +
// "- see https://pulumi.io/install/aws.html for details on configuration")
//}
//
//return nil
// lastly let's set the sharedCreds and sharedConfig file. If these are not found then let's default to the
// locations that AWS cli will store these values.
sharedCredentialsFile := stringValue(vars, "sharedCredentialsFile", []string{"AWS_SHARED_CREDENTIALS_FILE"})
if sharedCredentialsFile == "" {
sharedCredentialsFile = "~/.aws/credentials"
}
credsPath, err := homedir.Expand(sharedCredentialsFile)
if err != nil {
return err
}

sharedConfigFile := stringValue(vars, "sharedConfigFile", []string{"AWS_SHARED_CONFIG_FILE"})
if sharedConfigFile == "" {
sharedConfigFile = "~/.aws/config"
}
configPath, err := homedir.Expand(sharedConfigFile)
if err != nil {
return err
}

config.SharedCredentialsFiles = []string{credsPath}
config.SharedConfigFiles = []string{configPath}

if _, err := awsbase.GetAwsConfig(context.Background(), config); err != nil {
return fmt.Errorf("unable to validate AWS credentials " +
"- see https://pulumi.io/install/aws.html for details on configuration")
}

return nil
}

// managedByPulumi is a default used for some managed resources, in the absence of something more meaningful.
Expand Down Expand Up @@ -365,10 +392,7 @@ func Provider() tfbridge.ProviderInfo {
// be in a situation where a user can be waiting for a resource
// creation timeout (default up to 30mins) to find out that they
// have not got valid credentials

// this is temporarily skipped while we look at the cause of
// https://github.com/pulumi/pulumi-aws/issues/1995
Value: true,
Value: false,
},
},
"skip_metadata_api_check": {
Expand Down
2 changes: 1 addition & 1 deletion sdk/dotnet/Config/Config.cs
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ public static ImmutableArray<string> SharedCredentialsFiles
set => _sharedCredentialsFiles.Set(value);
}

private static readonly __Value<bool?> _skipCredentialsValidation = new __Value<bool?>(() => __config.GetBoolean("skipCredentialsValidation") ?? true);
private static readonly __Value<bool?> _skipCredentialsValidation = new __Value<bool?>(() => __config.GetBoolean("skipCredentialsValidation") ?? false);
/// <summary>
/// Skip the credentials validation via STS API. Used for AWS API implementations that do not have STS
/// available/implemented.
Expand Down
2 changes: 1 addition & 1 deletion sdk/dotnet/Provider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ public InputList<string> SharedCredentialsFiles
public ProviderArgs()
{
Region = Utilities.GetEnv("AWS_REGION", "AWS_DEFAULT_REGION");
SkipCredentialsValidation = true;
SkipCredentialsValidation = false;
SkipGetEc2Platforms = true;
SkipMetadataApiCheck = true;
SkipRegionValidation = true;
Expand Down
2 changes: 1 addition & 1 deletion sdk/go/aws/config/config.go

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

2 changes: 1 addition & 1 deletion sdk/go/aws/provider.go

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

2 changes: 1 addition & 1 deletion sdk/nodejs/config/vars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ Object.defineProperty(exports, "sharedCredentialsFiles", {
export declare const skipCredentialsValidation: boolean;
Object.defineProperty(exports, "skipCredentialsValidation", {
get() {
return __config.getObject<boolean>("skipCredentialsValidation") ?? true;
return __config.getObject<boolean>("skipCredentialsValidation") ?? false;
},
enumerable: true,
});
Expand Down
2 changes: 1 addition & 1 deletion sdk/nodejs/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ export class Provider extends pulumi.ProviderResource {
resourceInputs["sharedConfigFiles"] = pulumi.output(args ? args.sharedConfigFiles : undefined).apply(JSON.stringify);
resourceInputs["sharedCredentialsFile"] = args ? args.sharedCredentialsFile : undefined;
resourceInputs["sharedCredentialsFiles"] = pulumi.output(args ? args.sharedCredentialsFiles : undefined).apply(JSON.stringify);
resourceInputs["skipCredentialsValidation"] = pulumi.output((args ? args.skipCredentialsValidation : undefined) ?? true).apply(JSON.stringify);
resourceInputs["skipCredentialsValidation"] = pulumi.output((args ? args.skipCredentialsValidation : undefined) ?? false).apply(JSON.stringify);
resourceInputs["skipGetEc2Platforms"] = pulumi.output((args ? args.skipGetEc2Platforms : undefined) ?? true).apply(JSON.stringify);
resourceInputs["skipMetadataApiCheck"] = pulumi.output((args ? args.skipMetadataApiCheck : undefined) ?? true).apply(JSON.stringify);
resourceInputs["skipRegionValidation"] = pulumi.output((args ? args.skipRegionValidation : undefined) ?? true).apply(JSON.stringify);
Expand Down
2 changes: 1 addition & 1 deletion sdk/python/pulumi_aws/config/vars.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ def skip_credentials_validation(self) -> bool:
Skip the credentials validation via STS API. Used for AWS API implementations that do not have STS
available/implemented.
"""
return __config__.get_bool('skipCredentialsValidation') or True
return __config__.get_bool('skipCredentialsValidation') or False

@property
def skip_get_ec2_platforms(self) -> bool:
Expand Down
4 changes: 2 additions & 2 deletions sdk/python/pulumi_aws/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ def __init__(__self__, *,
if shared_credentials_files is not None:
pulumi.set(__self__, "shared_credentials_files", shared_credentials_files)
if skip_credentials_validation is None:
skip_credentials_validation = True
skip_credentials_validation = False
if skip_credentials_validation is not None:
pulumi.set(__self__, "skip_credentials_validation", skip_credentials_validation)
if skip_get_ec2_platforms is None:
Expand Down Expand Up @@ -714,7 +714,7 @@ def _internal_init(__self__,
__props__.__dict__["shared_credentials_file"] = shared_credentials_file
__props__.__dict__["shared_credentials_files"] = pulumi.Output.from_input(shared_credentials_files).apply(pulumi.runtime.to_json) if shared_credentials_files is not None else None
if skip_credentials_validation is None:
skip_credentials_validation = True
skip_credentials_validation = False
__props__.__dict__["skip_credentials_validation"] = pulumi.Output.from_input(skip_credentials_validation).apply(pulumi.runtime.to_json) if skip_credentials_validation is not None else None
if skip_get_ec2_platforms is None:
skip_get_ec2_platforms = True
Expand Down