https://pulumi.com logo
#general
Title
# general
f

famous-kite-69533

03/26/2020, 7:14 PM
Hi. Quick question. I have this code:
Copy code
const s3AccessKeyIdSecret = args.s3AccessKeyId || config.getSecret('s3AccessKeyId')
    const s3SecretAccessKeySecret = args.s3SecretAccessKey || config.getSecret('s3SecretAccessKey')

    const s3AccessKeyId = pulumi.all([s3AccessKeyIdSecret]).apply(([id]) => id)  
    const s3SecretAccessKey = pulumi.all([s3SecretAccessKeySecret]).apply(([secret]) => secret)
How can I simplify this? I just want to get the secrets from Pulumi secrets if I don't specify them in the class. I am new to Typescript. Also, I am using these secrets in two objects, but for some reason the variables are not "empty" only when accessed the first time for the first object. When accessed for the second object the variables yield no values - I can see this in the config map that is created without those keys only for the second object; the objects are defined in the same scope and the keys that use these secrets are the same. Why aren't the variables working properly when used the second time? Thanks!
w

white-balloon-205

03/26/2020, 7:43 PM
If I understand what you are trying to do - I believe this is equivalent to what you shared:
Copy code
const s3AccessKeyId = pulumi.output(args.s3AccessKeyId || config.getSecret('s3AccessKeyId'))
const s3SecretAccessKey = pulumi.output(args.s3SecretAccessKey || config.getSecret('s3SecretAccessKey'))
Depends a bit on what type you gave to
args.s3AccessKeyId
.
f

famous-kite-69533

03/26/2020, 7:47 PM
Trying now - I am reading from Pulumi secrets now, ignoring the args
Weird, same thing. I have this besides the code you suggested:
Copy code
let walRestoreConfig = {}

    const walBackupConfig = {
      "BACKUP_SCHEDULE": walBackupSchedule,
      "USE_WALG_BACKUP": String(enableWalBackups),
      "BACKUP_NUM_TO_RETAIN": walBackupsToRetain,
      "WAL_S3_BUCKET": s3Bucket,
      "AWS_ACCESS_KEY_ID": s3AccessKeyId,
      "AWS_SECRET_ACCESS_KEY": s3SecretAccessKey,
      "AWS_ENDPOINT": s3Endpoint,
      "AWS_REGION": s3Region,
      "WALG_DISABLE_S3_SSE": "true"
    }

    if (clone) {
      walRestoreConfig = {
        "USEWALG_RESTORE": "true",
        "CLONE_METHOD": "CLONE_WITH_WALE",
        "CLONE_AWS_ACCESS_KEY_ID": s3AccessKeyId,
        "CLONE_AWS_SECRET_ACCESS_KEY": s3SecretAccessKey,
        "CLONE_AWS_ENDPOINT": s3Endpoint,
        "CLONE_AWS_REGION": s3Region,
        "CLONE_WAL_S3_BUCKET": s3Bucket,
        "CLONE_WAL_BUCKET_SCOPE_SUFFIX": `/${cloneClusterID}`,
        "CLONE_TARGET_TIME": cloneTargetTime,
        "CLONE_SCOPE": cloneClusterName
      }
    }
then I am merging the two objects as data for the config map.
s3AccessKeyId
and
s3SecretAccessKey
are rendered fine in
AWS_ACCESS_KEY_ID
and
AWS_SECRET_ACCESS_KEY
but not in
CLONE_AWS_ACCESS_KEY_ID
and
CLONE_AWS_SECRET_ACCESS_KEY
. The last two are empty or something, causing the config map to be created without those keys
Actually no, with that change all of those 4 keys are missing now
Oops. I think I know why the values were missing for the second object 😄
config
is defined this way
Copy code
const config: pulumi.Config = new pulumi.Config(`${appName}-cluster`)
and I forgot to set those secrets for the second cluster, which has empty values. I'll fix that and try again
w

white-balloon-205

03/26/2020, 7:58 PM
The last two are empty or something, causing the config map to be created without those keys
How are you populating the configmap? Note that
s3AccessKeyId
will be an
Output<string>
so you'll need to make sure whereever you are using it understands how to serialize that. If its passed as an input to a Pulumi resource, that will happen automatically. If you are trying to further process it - you will need to use
.apply
. See https://www.pulumi.com/docs/intro/concepts/programming-model/#outputs.
f

famous-kite-69533

03/26/2020, 8:00 PM
I am confused as to what changes to make besides what you suggested earlier 🙂
w

white-balloon-205

03/26/2020, 8:00 PM
How are you populating the configmap?
f

famous-kite-69533

03/26/2020, 8:00 PM
The config map is as follows:
Copy code
const configMap = new k8s.core.v1.ConfigMap(`${appName}-config-map`, 
      {
        metadata: {
          name: podConfigMapName,
          namespace: namespace
        },
        data: {...walBackupConfig, ...walRestoreConfig}
      },
      {
        parent: this,
        dependsOn: [
          ns
        ]
      }
    );
But now it complains about what I am assigning to
data
I get
Copy code
Data contains the configuration data. Each key must consist of alphanumeric characters, '-', '_' or '.'. Values with non-UTF-8 byte sequences must use the BinaryData field. The keys stored in Data must not overlap with the keys in the BinaryData field, this is enforced during validation process.
I wasn't getting this before
Interesting, if I replace the variables names with strings that error disappears
How do I use apply with the code you suggested earlier?
I have tried appending
.apply(v => v)
but it doesn't work... I'm confused
w

white-balloon-205

03/26/2020, 8:08 PM
I must be missing something about what the full code looks like. Morally - I understand you to be doing something like this - which works as expected for me:
Copy code
const configmap = new k8s.core.v1.ConfigMap("map", {
    data: {
        "a": pulumi.secret("hello"),
    },
});
It might help to add
pulumi.output({...walBackupConfig, ...walRestoreConfig}).apply(console.log)
to print out what the value you are trying to pass actually looks like.
f

famous-kite-69533

03/26/2020, 8:12 PM
The console.log shows the following:
Copy code
AWS_ACCESS_KEY_ID: '[secret]',
      AWS_SECRET_ACCESS_KEY: '[secret]',
The other values are set correctly
w

white-balloon-205

03/26/2020, 8:19 PM
Ah - that's actually because we are blinding the values in the console output for you 🙂. I honestly can't tell without seeing your full code - nothing looks wrong that you've shown me. This example seems to have all the same things you are doing - and works fine:
Copy code
const config = new pulumi.Config();
const s = config.requireSecret('secret');

const data = {
    s: s,
}

const configmap = new k8s.core.v1.ConfigMap("map", {
    data:  { ...data},
});

export const configmapdata = configmap.data;
f

famous-kite-69533

03/26/2020, 8:21 PM
Working! 😄 It didn't like the syntax I was using to merge the two objects for some reason. Or so it seems 😄 I am now setting a different object with some or all the config settings in the if/else and it's working. I can see the secrets just fine now in the configmap (don't ask me why secrets in a configmap... it's the way the Zalando operator for Postgres works). Thanks a lot!
👍 1