https://pulumi.com logo
Title
l

lively-needle-84406

11/16/2022, 7:22 PM
I am attempting to create a policy that includes some metadata of a newly created eks cluster: importing the created eks cluster into my policy creation file-> accessing the
cluster.core.cluster.name
within the policy json, but Typescript is complaining that cluster is undefined at runtime. How can I ensure that the cluster is defined to remove the typescript compilation error? (I have already added a dependsOn to the Policy resource, with no luck)
l

little-cartoon-10569

11/16/2022, 7:32 PM
Add
!
after whichever property has
| undefined
in its type.
l

lively-needle-84406

11/16/2022, 8:12 PM
@little-cartoon-10569 Currently, every property has proper typing, with no Typescript errors before compilation. Here is my current policy I am creating:
import { aws } from "../../../lib";
import { cluster } from "../../eks";

export const clusterAutoscalerPolicy = new aws.iam.Policy(`clusterAutoscalerPolicy`, {
    policy: `{
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "VisualEditor0",
                "Effect": "Allow",
                "Action": [
                    "autoscaling:SetDesiredCapacity",
                    "autoscaling:TerminateInstanceInAutoScalingGroup"
                ],
                "Resource": "*",
                "Condition": {
                    "StringEquals": {
                        "aws:ResourceTag/k8s.io/cluster-autoscaler/${cluster.core.cluster.name}": "owned"
                    }
                }
            },
            {
                "Sid": "VisualEditor1",
                "Effect": "Allow",
                "Action": [
                    "autoscaling:DescribeAutoScalingInstances",
                    "autoscaling:DescribeAutoScalingGroups",
                    "ec2:DescribeLaunchTemplateVersions",
                    "autoscaling:DescribeTags",
                    "autoscaling:DescribeLaunchConfigurations"
                ],
                "Resource": "*"
            }
        ]
    }`
}, {
    dependsOn: [cluster]
});
Basically, cluster is undefined at this point and is throwing an error. But, I use
cluster
similarly when creating other resources and never have this issue...
l

little-cartoon-10569

11/16/2022, 8:12 PM
This cannot work:
"aws:ResourceTag/k8s.io/cluster-autoscaler/${cluster.core.cluster.name}": "owned"
Try this:
pulumi.interpolate`aws:ResourceTag/k8s.io/cluster-autoscaler/${cluster.core.cluster.name}`: "owned"
There is no interpolation in quoted-strings. You need template strings (backticks). And you need Pulumi to do the interpolation if there are outputs involved.
l

lively-needle-84406

11/16/2022, 8:24 PM
The backticks are actually encompassing the entire
policy
property. I have attempted the pulumi.interpolate, but this has the same outcome:
import { aws, pulumi } from "../../../lib";
import { cluster } from "../../eks";

export const clusterAutoscalerPolicy = new aws.iam.Policy("clusterAutoscalerPolicy", {
    policy: `{
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "VisualEditor0",
                "Effect": "Allow",
                "Action": [
                    "autoscaling:SetDesiredCapacity",
                    "autoscaling:TerminateInstanceInAutoScalingGroup"
                ],
                "Resource": "*",
                "Condition": {
                    "StringEquals": {
                        ${pulumi.interpolate`aws:ResourceTag/k8s.io/cluster-autoscaler/${cluster.core.cluster.name}: "owned"`}
                    }
                }
            },
            {
                "Sid": "VisualEditor1",
                "Effect": "Allow",
                "Action": [
                    "autoscaling:DescribeAutoScalingInstances",
                    "autoscaling:DescribeAutoScalingGroups",
                    "ec2:DescribeLaunchTemplateVersions",
                    "autoscaling:DescribeTags",
                    "autoscaling:DescribeLaunchConfigurations"
                ],
                "Resource": "*"
            }
        ]
    }`
}, {
    dependsOn: [cluster]
});
Error:
TypeError: Cannot read properties of undefined (reading 'core')
l

little-cartoon-10569

11/16/2022, 8:25 PM
You can't do that, either. You'd need to create the entire policy JSON in an
apply()
.
It would be easier to use aws.iam.PolicyDocument.
Remove the backticks from the policy value, and it will change from a string to a PolicyDocument. Then change all the keys from strings to symbols. Then the interpolate will work.
When you can, use PolicyDocument. It's a much friendlier interface. It isn't always implemented (e.g. KMS key policies don't support it yet), but when it is supported, use it.
l

lively-needle-84406

11/16/2022, 9:09 PM
Appreciate all of the info @little-cartoon-10569 Looks like I am still not getting this 100% correct. Getting the same undefined error with the following:
import { aws, pulumi } from "../../../lib";
import { cluster } from "../../eks";

export const clusterAutoscalerPolicy = new aws.iam.Policy("clusterAutoscalerPolicy", {
    policy: {
        Version: "2012-10-17",
        Statement: [
            {
                Sid: "VisualEditor0",
                Effect: "Allow",
                Action: [
                    "autoscaling:SetDesiredCapacity",
                    "autoscaling:TerminateInstanceInAutoScalingGroup"
                ],
                Resource: "*",
                Condition: {
                    StringEquals: {
                        [`${pulumi.interpolate`aws:ResourceTag/k8s.io/cluster-autoscaler/${cluster.core.cluster.name}`}`]: "owned"
                    }
                }
            },
            {
                Sid: "VisualEditor1",
                Effect: "Allow",
                Action: [
                    "autoscaling:DescribeAutoScalingInstances",
                    "autoscaling:DescribeAutoScalingGroups",
                    "ec2:DescribeLaunchTemplateVersions",
                    "autoscaling:DescribeTags",
                    "autoscaling:DescribeLaunchConfigurations"
                ],
                Resource: "*"
            }
        ]
    }
});
Not sure how else to make the key the dynamic value here
l

little-cartoon-10569

11/16/2022, 9:16 PM
What's undefined? I think the Condition should be more like this:
Condition: {
                    StringEquals: {
                        pulumi.interpolate`aws:ResourceTag/k8s.io/cluster-autoscaler/${cluster.core.cluster.name}`: "owned"
                    }
                }
l

lively-needle-84406

11/16/2022, 9:18 PM
Here is the error I get when using the above Condition:
Type 'typeof import("/Users/jacobbaker/veryable/cloud/disaster-recovery/node_modules/@pulumi/pulumi/index")' is not assignable to type 'Input<string> | Input<Input<string>[]>'.
  Type 'typeof import("/Users/jacobbaker/veryable/cloud/disaster-recovery/node_modules/@pulumi/pulumi/index")' is missing the following properties from type 'Input<string>[]': length, pop, push, join, and 25 more.ts(2322)
documents.d.ts(127, 5): The expected type comes from this index signature.
In my previous example,
core
was undefined:
TypeError: Cannot read properties of undefined (reading 'core')
I logged
cluster
and it has the type of
OutputImpl
which I am assuming means that
core
does not exist on this object.
But it is listed as an output object in the documentation
l

little-cartoon-10569

11/16/2022, 9:31 PM
Are you confident that the error applies to that line? The error text suggests that you're doing something like this:
import pulumi from "@pulumi/pulumi"
Instead of
import * as pulumi from "@pulumi/pulumi"
l

lively-needle-84406

11/16/2022, 9:36 PM
My import (where pulumi is being imported from) is exporting like:
export * as pulumi from '@pulumi/pulumi';
I have tried to import pulumi as you mentioned above, directly in the file:
import * as pulumi from "@pulumi/pulumi"
But, receiving the same type error
l

little-cartoon-10569

11/16/2022, 9:38 PM
I don't know about that export syntax. I know that the error message says you're trying to use the entire pulumi index file as an object:
Type 'typeof import("/Users/jacobbaker/veryable/cloud/disaster-recovery/node_modules/@pulumi/pulumi/index")' is not assignable to type 'Input<string> | Input<Input<string>[]>'.
Is there anywhere in your code that is trying to use
typeof import("/Users/jacobbaker/veryable/cloud/disaster-recovery/node_modules/@pulumi/pulumi/index")'
? That'll be the problem.
l

lively-needle-84406

11/16/2022, 9:47 PM
Not using typeof anywhere in the codebase. Got this error to go away with some impromptu typing, but at runtime, I am still getting the
core
is undefined, even with the pulumi.interpolate 😕
l

little-cartoon-10569

11/16/2022, 9:49 PM
I see that
cluster
is defined like this:
import { cluster } from "../../eks";
Is it a static object with a
core
property? Is it a module with a
core
static object? It looks like you're using it as a variable, but it's not...
l

lively-needle-84406

11/16/2022, 9:51 PM
cluster
is the output of an
eks.Cluster
, so my assumption was that whatever I am importing from this output, I could access directly. (I am able to access the cluster object properties in other places with no issues)
l

little-cartoon-10569

11/16/2022, 9:53 PM
I don't think you can import an object from another file.. it's not something I've ever tried though. Essentially you're asking Typescript to run the code on import: normally, the pattern is to provide definitions on import, and run things from the importing file. Can you change your code to export a function that creates the cluster? Then call that function?