9

I want to allow Lambda service to create a deployment inside my VPC, thus I have subnet ids array of type Output<string>[] that I want to put into role policy as follows:

export const createNetworkInterfacePolicy = new aws.iam.RolePolicy(
  "network-interface-policy-2",
  {
    policy: pulumi.interpolate `{
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": ["ec2:CreateNetworkInterfacePermission"],
          "Resource": [
            "arn:aws:ec2:${region}:${callerIdentity.accountId}:network-interface/*"
          ],
          "Condition": {
            "StringEquals": {
              "ec2:Subnet": ${JSON.stringify(vpc.vpcPrivateSubnetIds.map(item => item.apply(JSON.stringify)))},
              "ec2:AuthorizedService": "lambda.amazonaws.com"
            }
          }
        }
      ]
    }`,
    role: deploymentRole
  }
);

Unfortunately what I end up with is:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:CreateNetworkInterfacePermission"
            ],
            "Resource": [
                "arn:aws:ec2:us-east-2:removedAccountId:network-interface/*"
            ],
            "Condition": {
                "StringEquals": {
                    "ec2:Subnet": [
                        "Calling [toJSON] on an [Output<T>] is not supported.\n\nTo get the value of an Output as a JSON value or JSON string consider either:\n    1: o.apply(v => v.toJSON())\n    2: o.apply(v => JSON.stringify(v))\n\nSee https://pulumi.io/help/outputs for more details.\nThis function may throw in a future version of @pulumi/pulumi.",
                        "Calling [toJSON] on an [Output<T>] is not supported.\n\nTo get the value of an Output as a JSON value or JSON string consider either:\n    1: o.apply(v => v.toJSON())\n    2: o.apply(v => JSON.stringify(v))\n\nSee https://pulumi.io/help/outputs for more details.\nThis function may throw in a future version of @pulumi/pulumi."
                    ],
                    "ec2:AuthorizedService": "lambda.amazonaws.com"
                }
            }
        }
    ]
}

I tried many combinations but none of them work. How do I generate JSON array from Output<string>[]?

pbn
  • 2,406
  • 2
  • 26
  • 39

1 Answers1

13

Sometimes it's easiest to wrap an apply around the entire creation of another resource. In this case appTaskPolicy becomes an OutputInstance<aws.iam.Policy> which you can then feed into other parts of your program using it's own Outputs.

You'll need to import * as pulumi from '@pulumi/pulumi'; if you haven't already for this to work

const vpc = awsx.Network.getDefault();
const appTaskPolicyName = named('app-task-policy');

const appTaskPolicy = pulumi.all(vpc.publicSubnetIds).apply(([...subnetIds]) => {
    return new aws.iam.Policy(appTaskPolicyName, {
        policy: {
            Version: '2012-10-17',
            Statement: [
                {
                    Action: ['sqs:GetQueueUrl', 'sqs:SendMessage'],
                    Resource: [
                        'someresourcearn'
                    ],
                    Effect: 'Allow',
                    Condition: {
                        StringEquals: {
                            'ec2:Subnet': subnetIds,
                            'ec2:AuthorizedService': 'lambda.amazonaws.com'
                        }
                    }
                }
            ]
        }
    });
});
Jesse Carter
  • 20,062
  • 7
  • 64
  • 101
  • @pbn Were you able to check to see if this solution worked for you – Jesse Carter Oct 15 '19 at 14:26
  • This worked for me - thanks so much. I have exported an array of strings from another stack, and it was so hard to find out how to import back on the next stack as an array of strings and not as an output :| – Jose Alban Oct 29 '20 at 17:38
  • This same workaround worked for me with the Python pulumi API. Thanks! – aylr Oct 11 '21 at 18:53
  • If you take a look at `.apply()` method there is a statement that you are not allowed to create resources inside it. – Vladimir Prudnikov Dec 21 '22 at 19:06
  • Interesting... I've used this technique in the past with great success. I'm not sure if something changed that would make it unsafe to use now – Jesse Carter Dec 21 '22 at 21:41