Hi, does anyone have any tips how I can dynamicall...
# typescript
r
Hi, does anyone have any tips how I can dynamically get the AWS account ID and pass it to a function to use to generate a JSON snippet?
d
Inside a pulumi script or elsewhere? In Typescript we do:
Copy code
import * as aws from '@pulumi/aws'

const current = aws.getCallerIdentity({})
const accountId = current.then((current) => current.accountId)
👍 1
in lambdas we do:
Copy code
import { GetCallerIdentityCommand, STSClient } from '@aws-sdk/client-sts'
  
  const client = new STSClient({ region })
  const { Account: accountId } = await client.send(new GetCallerIdentityCommand({}))
r
Sorry, in pulumi. I've tried the top one, but it returns a Promise<string>, so when I pass it to the function and run pulumi up, I get [Promise: Object] instead of the account number...
Copy code
const accountId: Promise<string>
Argument of type 'Promise<string>' is not assignable to parameter of type 'string | number'.
  Type 'Promise<string>' is not assignable to type 'number'.ts(2345)
Okta_Default_Roles.ts(18, 34): Did you forget to use 'await'?
d
oh yes we then use interpolation
Copy code
const sqsQueueUrl = interpolate`<https://sqs>.${region}.<http://amazonaws.com/${accountId}/link-medmeme-migration-sqs-${env}|amazonaws.com/${accountId}/link-medmeme-migration-sqs-${env}>`
r
This is the separate function that account id is passed to:
Copy code
export function setPolicyDocument(accountId: any): string {
  return `{
    \"Version\":\"2012-10-17\",
    \"Statement\": [
        {
            \"Effect\":\"Allow\",
            \"Principal\":{
                \"Federated\":\"arn:aws:iam::${accountId}:saml-provider/sgn.okta-emea.com\"
            },
            \"Action\":\"sts:AssumeRoleWithSAML\",
            \"Condition\": {
                \"StringEquals\":{
                    \"SAML:aud\":\"<https://signin.aws.amazon.com/saml>\"
                    }
                }
            }
        ]
    }`;
}
I'm changing the
any
just trying to get it to work first!
d
yep we do something similar, but use interpolate which resolves promises
Copy code
accessPolicies: pulumi.interpolate`{
        "Statement": [
          {
            "Action": "es:*",
            "Effect": "Allow",
            "Principal": { "AWS": "${this.cognito.authenticatedRole.arn}" },
            "Resource": "arn:aws:es:${region}:${accountId}:domain/link-${env}-*/*"
          }
        ],
        "Version": "2012-10-17"
      }`,
r
keep getting this error, @damp-school-17708
Copy code
pulumi:pulumi:Stack (Okta_AWS_Setup-dev):
    error: Running program 'C:\SGN_Patterns\Okta_AWS_Setup\application' failed with an unhandled exception:
    Error: invocation of aws:index/getCallerIdentity:getCallerIdentity returned an error: could not validate provider configuration: 1 error occurred:
        * Invalid or unknown key
d
We do have a section in our Pulumi configs
Copy code
config:
  aws:region: us-east-1
Maybe is that?
I assume btw you use aws, I have no idea on other cloud providers
r
I am using AWS. Think i've sorted it. As per normal it was something simple, I had double quotes inside my pulumi.<stack>.yaml file. But the pulumi.interpolate also helped 🙂 Thank you kindly for your help.
l
Aside: there is the
aws.iam.PolicyDocument
class that creates the JSON for you. You don't need to do anything special, sometimes you can even avoid interpolation:
Copy code
new aws.iam.Policy(name, {
  policy: {
    Version: "2012-10-17",
    Statement": [
        {
            Effect: "Allow",
            "Principal": { "AWS": this.cognito.authenticatedRole.arn },
            "Resource": pulumi.interpololate`arn:aws:es:${region}:${accountId}:domain/link-${env}-*/*`
        }
    ]
  } as aws.iam.PolicyDocument
  // ...
}
r
That looks cleaner, thank you @little-cartoon-10569
c
i would remove the
as aws.iam.PolicyDocument
casting since it removes type-safety in this scenario and is not necessary for it to compile
l
Yes, it was added to show where the class is in the code. It's best not to have it.