What is the best way to reach out and perform an A...
# general
a
What is the best way to reach out and perform an AWS action in the midst of my Pulumi code?
my use case was:
create a KMS key, and then call out to KMS to encrypt a Pulumi secret config key and then take that value and set that as an environment variable on a lambda function
(my implementation language is go, in case that makes a difference)
I got this error when running `pulumi up`:
Copy code
NoCredentialProviders: no valid providers in chain.
which I think means that the credentials that Pulumi is using were not available to my code
m
That's odd.
Oh--yes, that is accurate, though
w.r.t. the credentials
That's interesting, though. How are your credentials configured?
a
is there a way to get access to the credentials under which Pulumi is running?
environment variables
m
And you're linking in the Azure SDK for Go?
a
the AWS sdk for go
m
yeah, my mistake
a
m
That's what the Pulumi AWS provider uses internally, so it's surprising that it's not picking up the same credentials
a
here's my (admittedly hacky) code:
Copy code
func encrypt(arn, value string) (string, error) {
	sess, err := session.NewSession(&aws.Config{
		Region: aws.String("us-east-1"),
	})
	if err != nil {
		return "", err
	}

	kmsSvc := awskms.New(sess)

	result, err := kmsSvc.Encrypt(&awskms.EncryptInput{
		KeyId:     aws.String(arn),
		Plaintext: []byte(value),
	})
	if err != nil {
		return "", err
	}

	return string(result.CiphertextBlob), nil
}
m
(and I don't think that those envvars are specific to the Pulumi AWS provider)
Yeah, that's exactly what I would write
a
I was thinking about manually setting the creds as pulumi config values
m
That should certainly work.
a
but that seemed like an incorrect way to do it
heh
m
Can you try setting
CredentialsChainVerboseErrors
to
aws.Bool(true)
in the
aws.Config
value you're building?
Might give us a bit more context
a
yes, one second
Copy code
Diagnostics:
  pulumi:pulumi:Stack: billing-billing-dev
    info: error: program failed: 1 error occurred:
        * marshaling properties: awaiting input property environment: NoCredentialProviders: no valid providers in chain
    caused by: EnvAccessKeyNotFound: failed to find credentials in the environment.
    SharedCredsLoad: failed to load profile, .
    EC2RoleRequestError: no EC2 instance role found
    caused by: RequestError: send request failed
    caused by: Get <http://169.254.169.254/latest/meta-data/iam/security-credentials/>: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)

  pulumi:pulumi:Stack: billing-billing-dev
    error: an unhandled error occurred: program exited with non-zero exit code: 1
yeah, looks like it tried several ways of finding credentials
m
Yeah, and it does look like it couldn't find anything in the environment.
Just to be absolutely sure, you're setting
AWS_ACCESS_KEY_ID
and
AWS_SECRET_ACCESS_KEY
, right?
a
I think what may be happening is that pulumi is not executing the program and passing the environment along
yeah
those are the ones
m
pulumi is not executing the program and passing the environment along
This would be very surprising, but it's certainly possible
a
I think I might be slightly unique in that I don't usually have a
~/.aws
directory. I have a way of managing my keys as just env vars and so I rely on that
lemme see if I can pull out what variables it is passing
m
So the resource plugins and the Go binary should be executed with the same envvars
But it should be easy enough to dump the set of envvars your program is getting using
os.Environ
a
[PULUMI_PROJECT=billing PULUMI_STACK=billing-dev PULUMI_CONFIG={"aws:region":"us-east-1","slack:webhook":"[secret]"} PULUMI_DRY_RUN=true PULUMI_PARALLEL=10 PULUMI_MONITOR=127.0.0.1:43596 PULUMI_ENGINE=127.0.0.1:34309]
is what the language plugin is sending
m
That... is surprising
a
I verified that the aws vars aren't getting passed
doing a quick mod to see if passing them through will do the trick
m
Hah, this is a bug in the Go language runner specifically
It's overwriting the entire env rather than appending to it 🙄
a
yes
I've run into this issue before in other situations
we could just take os.Environ() and append the vars we need to append
that would work
m
yeah
something like
Copy code
diff --git a/sdk/go/pulumi-language-go/main.go b/sdk/go/pulumi-language-go/main.go
index 505d130..50ebc02 100644
--- a/sdk/go/pulumi-language-go/main.go
+++ b/sdk/go/pulumi-language-go/main.go
@@ -179,7 +179,7 @@ func (host *goLanguageHost) constructEnv(req *pulumirpc.RunRequest) ([]string, e
                return nil, err
        }

-       var env []string
+       env = append(nil, os.Environ()...)
        maybeAppendEnv := func(k, v string) {
                if v != "" {
                        env = append(env, fmt.Sprintf("%s=%s", k, v))
(but with
env :=
rather than
env =
)
a
yup
that works
I'll submit a PR
there are security implications to hoisting the entire env through, but that can be discussed there
m
Thanks!
a
you're welcome, thanks for working through it with me.