https://pulumi.com logo
#python
Title
# python
k

kind-jelly-61624

10/03/2022, 6:10 PM
Has anyone created IAM policies with pulumi - how did you substitute aws regions / resource arns within the policy document? I’m using python - do I need to make my own jinja magic or is there something built into pulumi that can handle this sort of thing? I see in the docs a reference to {{aws::username}} but that only works if I substitute the value myself. Something like the !Sub ${AWS::Region} function that cloudformation has
s

stocky-restaurant-98004

10/03/2022, 6:11 PM
getRegion
will give you the current region: https://www.pulumi.com/registry/packages/aws/api-docs/getregion/
If you need to supply values that are not immediately known, like ARNs you want to pass to an IAM policy, you need to use Apply. Here's a quick example:
Copy code
bucket_policy = aws.s3.BucketPolicy(
    "my-website-bucket-policy",
    bucket=bucket.id,
    policy=bucket.arn.apply(
        lambda arn: json.dumps({
            "Version": "2012-10-17",
            "Statement": [{
                "Effect": "Allow",
                "Principal": "*",
                "Action": [
                    "s3:GetObject"
                ],
                "Resource": [
                    f"{arn}/*"
                ]
            }]
        })),
)
We have a self-guided workshop that might be helpful to use a reference. (That's where I got the above code from.) https://pulumi.awsworkshop.io/20_cloud_engineering_python.html
And here's the docs page that gives a deeper explanation on Pulumi inputs and outputs: https://www.pulumi.com/docs/intro/concepts/inputs-outputs/ Note that if you're using the output of one resource directly as the input of another, you do not need to use Apply. However, when you need the concrete value of a resource (like it's ARN) to formulate the input of another resource (like an S3 bucket policy), you do need to use Apply.
k

kind-jelly-61624

10/03/2022, 6:16 PM
Thanks @stocky-restaurant-98004! my question was more - once I have the region and the account_id - how can I substitute that in a policy without needing to create my own jinja function. So say there’s a policy like this I need:
Copy code
Statement:
        - Effect: Allow
          Action:
            - "glue:*"
          Resource:
              - arn:aws:glue:{{aws::region}}:{{aws::account_id}}:trigger/*
              - arn:aws:glue:{{aws::region}}:{{aws::account_id}}:connection/*
In cfn - i would use the substiture function and it would automagically replace the region and account_id with the right placeholders. I know Typescript has the interpolate function but I couldn’t find the same equivalent for the python sdk
s

stocky-restaurant-98004

10/03/2022, 6:17 PM
The Inputs and Outputs page should have all the info you need for Python. LMK if there are other places you expected to find that info and did not.
k

kind-jelly-61624

10/03/2022, 6:19 PM
let me try to explain better- I understand that inputs and outputs are promises, however say you are deploying multiple policies. Defining each policy within your python code isn’t ideal. You would likely have a yaml file with each policy defined and placeholders like ${AWS::Region} / ${AWS:AccountID} to substitute the value where needed. Does pulumi provide a way for that substitution to happen?
s

stocky-restaurant-98004

10/03/2022, 6:23 PM
Why wouldn't defining each policy in code be ideal?
k

kind-jelly-61624

10/03/2022, 6:27 PM
so ground zero we have about 30 policies , this number will only grow larger and having it defined in code won’t scale well. plus having them defined in code would mean we’d need to replicate them for each new account we want to deploy into as opposed to having one place for the policy documents that multiple account stacks could read from
also defining them in code takes away easy readability - it would be hard to audit which policy enforces which permissions
b

billowy-army-68599

10/03/2022, 7:04 PM
@kind-jelly-61624 it seems like creating a function or component resource that takes the region and account id as an input and then building
json.dumps
to interpolate the variables would be much much easier than using jinja templating
s

stocky-restaurant-98004

10/03/2022, 7:06 PM
@kind-jelly-61624 Creating a new stack should only add an additional stack-specific config file. You shouldn't be adding any additional code (resources) to deploy a stack to a new region/account.
k

kind-jelly-61624

10/03/2022, 7:13 PM
@stocky-restaurant-98004 we’ll be using a project per account so we’ll have stacks per account as well. We don’t want to reuse the same project across multiple accounts, trying to make this as modular as possible.
@billowy-army-68599 haha true, i just figured if I’m going down the component resource path might as well make this a super generic module that can reused for any interpolation down the road - like even in userdata
b

billowy-army-68599

10/03/2022, 7:17 PM
structured data is always likely to be easier to manipulate. there’s no built in jinja templating but you can definitely go down that path!
s

stocky-restaurant-98004

10/03/2022, 7:43 PM
@kind-jelly-61624 If you're deploying the same resources (give or take a few parameters), then the idiomatic way to do that is to use stacks to represent different regions/accounts.
👍 1
b

billowy-army-68599

10/04/2022, 2:12 AM
you still have to render them into a policy document…
p

polite-zoo-26802

10/04/2022, 2:13 AM
Wouldn’t stack config variables be more applicable here ?
Ahh got it..