I'm creating a Workload Identity pool in a separat...
# typescript
e
I'm creating a Workload Identity pool in a separate file and at the bottom, I have these
const
Copy code
export const serviceAccountEmail = serviceAccount.email
export const workloadIdentityPoolId = workloadIdentityPool.workloadIdentityPoolId
export const workloadIdentityProviderId = workloadIdentityProvider.workloadIdentityPoolProviderId
and in the
index.ts
I have this
Copy code
import { serviceAccountEmail, workloadIdentityPoolId, workloadIdentityProviderId } from './resources/iam/gh-federated'

/**
 * GitHub Workflow Identity Provider information
 * check the resources/iam/gh-federated.ts for the full code
 */

console.log('Service Account Email:', serviceAccountEmail)
console.log('Workload Identity Pool ID:', workloadIdentityPoolId)
console.log('Workload Identity Provider ID:', workloadIdentityProviderId)
All the resources are created correctly but in the console I always have this
Copy code
Service Account Email: OutputImpl {
      __pulumiOutput: true,
      resources: [Function (anonymous)],
      allResources: [Function (anonymous)],
      isKnown: Promise { <pending> },
      isSecret: Promise { <pending> },
      promise: [Function (anonymous)],
      toString: [Function (anonymous)],
      toJSON: [Function (anonymous)]
    }
    Workload Identity Pool ID: OutputImpl {
      __pulumiOutput: true,
      resources: [Function (anonymous)],
      allResources: [Function (anonymous)],
      isKnown: Promise { <pending> },
      isSecret: Promise { <pending> },
      promise: [Function (anonymous)],
      toString: [Function (anonymous)],
      toJSON: [Function (anonymous)]
    }
    Workload Identity Provider ID: OutputImpl {
      __pulumiOutput: true,
      resources: [Function (anonymous)],
      allResources: [Function (anonymous)],
      isKnown: Promise { <pending> },
      isSecret: Promise { <pending> },
      promise: [Function (anonymous)],
      toString: [Function (anonymous)],
      toJSON: [Function (anonymous)]
    }
how do I obtain the value that I need?
k
Outputs are a unique and complex type in Pulumi which behave very much like promises.
We cannot check the value of a promise using console.log. https://www.pulumi.com/docs/iac/concepts/inputs-outputs/
e
so I need to change it into something like this?
export const serviceAccountEmail = serviceAccount.email.apply(email => email)
k
so I need to change it into something like this?
export const serviceAccountEmail = serviceAccount.email.apply(email => email)
There should be no need to use apply. Example:
Copy code
const vpcCidr = config.require(KEY_NAME.VPC_CIDR);
export const vpc = new awsNative.ec2.Vpc(strVpc, vpcArgs);

const albSgArgs: awsNative.ec2.SecurityGroupArgs = {
    vpcId: vpc.id,
    groupDescription: 'Allow HTTP and HTTPS traffic',
    securityGroupIngress: [
        { ipProtocol: "tcp", fromPort: 80, toPort: 80, cidrIp: vpcCidr, },
    ],
    tags: createAwsNativeTags({ Name: strAlbSG })
};
e
my code is as follow:
Copy code
const serviceAccount = new gcp.serviceaccount.Account('github-actions-sa', {
  accountId: 'github-actions-sa',
  displayName: 'GitHub Actions Service Account',
  description: 'A service account for use in a GitHub Actions workflow',
})

export const serviceAccountEmail = serviceAccount.email
Then I import it and console.log it in
index.ts
is true that here I don't have any problem with it, as it gets created correctly
Copy code
const workloadIdentityPool = new gcp.iam.WorkloadIdentityPool('github-actions-pool', {
  workloadIdentityPoolId: 'github-actions-pool',
  displayName: 'GitHub Workload Identity Pool',
  description: 'GitHub Workload Identity Pool',
})

// Create a Workload Identity Provider
const workloadIdentityProvider = new gcp.iam.WorkloadIdentityPoolProvider('github-actions-provider', {
  workloadIdentityPoolId: workloadIdentityPool.workloadIdentityPoolId,
  workloadIdentityPoolProviderId: 'github-actions-provider',
  ...
is just the
console.log
in the
index.ts
k
Console.log expects a synchronous value, so when you try to print the value of an output promise, it prints the contents of the promise object.
e
so the
apply
makes sense for this case?
q
You could do something like
serviceAccountEmail.apply(email => console.log(email))
The logging needs to be done within the apply, that callback is executed once the value is resolved
serviceAccount.email.apply(email => email)
would essentially be a noop, because apply returns an
Output
again
e
now I have this
Copy code
Service Account Email: OutputImpl {
      __pulumiOutput: true,
      resources: [Function (anonymous)],
      allResources: [Function (anonymous)],
      isKnown: Promise { <pending> },
      isSecret: Promise { <pending> },
      promise: [Function (anonymous)],
      toString: [Function (anonymous)],
      toJSON: [Function (anonymous)]
    }
    Workload Identity Pool ID: OutputImpl {
      __pulumiOutput: true,
      resources: [Function (anonymous)],
      allResources: [Function (anonymous)],
      isKnown: Promise { <pending> },
      isSecret: Promise { <pending> },
      promise: [Function (anonymous)],
      toString: [Function (anonymous)],
      toJSON: [Function (anonymous)]
    }
    Workload Identity Provider ID: OutputImpl {
      __pulumiOutput: true,
      resources: [Function (anonymous)],
      allResources: [Function (anonymous)],
      isKnown: Promise { <pending> },
      isSecret: Promise { <pending> },
      promise: [Function (anonymous)],
      toString: [Function (anonymous)],
      toJSON: [Function (anonymous)]
    }
    github-actions-pool
    github-actions-sa@my-project.iam.gserviceaccount.com
    github-actions-provider
in the
index.ts
shall I leave the console.log or should I export the main
const
and in
index.ts
doing this
console.log('Service Account Email:', serviceAccount.email.apply((email) => console.log(email)))
?
q
How are you logging it right now? Is it what you added above?
e
in
resources/iam/gh-federated.ts
I have the main code with the export of the above const, in
index.ts
I import them and use
console.log('const-desc', const)
q
You need to wrap the logging in apply, otherwise it's logging the promise-like Output. I.e.
yourConst.apply(c => console.log('desc', c))
e
I see that using this in the
index.ts
works
Copy code
serviceAccount.email.apply((email) => console.log('Service Account Email:', email))
workloadIdentityPool.workloadIdentityPoolId.apply((id) =>
  console.log('Workload Identity Pool ID:', id)
)
workloadIdentityProvider.workloadIdentityPoolProviderId.apply((id) =>
  console.log('Workload Identity Provider ID:', id)
)
and in the other file, I have
export const serviceAccount = new gcp.serviceaccount.Account('github-actions-sa', {..
etc
q
Cool, happy it works!
e
🙂 However, I wonder if I should wrap the content of
resources/iam/gh-federated.ts
inside a function and then call it inside
index.ts
🤔 what would be the best practice here? I see that this is working only because I import those
const
in the main file else it wouldn't run at all
q
A good option would be crafting components: https://www.pulumi.com/docs/iac/concepts/resources/components/ This allows you to bundle resources into reusable blocks Then in your index you could do something like this:
Copy code
const ghFederation = new GithubFederationSetup("name", {...});
ghFederation.email.apply(email => console.log(email));
e
👍 I'll look into it 🙂 TY