pulumi / pulumi-aws

An Amazon Web Services (AWS) Pulumi resource package, providing multi-language access to AWS
Apache License 2.0
466 stars 157 forks source link

aws.iam.RolePoliciesExclusive does not take effect in Pulumi until refresh #4766

Open t0yv0 opened 1 week ago

t0yv0 commented 1 week ago

Describe what happened

aws.iam.RolePoliciesExclusive does not take effect in Pulumi (does not restrict RolePolicy from being added to a Role) until Pulumi is called with refresh. This problem exists upstream but is worse in Pulumi as in Terraform it is sufficient to keep terraform apply to reach the steady state, where in Pulumi one has to run pulumi up --refresh.

Sample program

Sample program:


import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
import * as awsx from "@pulumi/awsx";
import * as inputs from "@pulumi/aws/types/input";

const exampleRole = new aws.iam.Role("exampleRole", {
    assumeRolePolicy: {
        Version: "2012-10-17",
        Statement: [
            {
                Action: "sts:AssumeRole",
                Effect: "Allow",
                Sid: "",
                Principal: {
                    Service: "ec2.amazonaws.com"
                }
            },
        ]
    },
});

const rolePolicy1 = new aws.iam.RolePolicy("rolePolicy1", {
    role: exampleRole.id,
    policy: JSON.stringify({
        Version: "2012-10-17",
        Statement: [
            {
                Action: ["ec2:Describe*"],
                Effect: "Allow",
                Resource: "*",
            },
        ]
    })
});

const rolePolicy2 = new aws.iam.RolePolicy("rolePolicy2", {
    role: exampleRole.id,
    policy: JSON.stringify({
        Version: "2012-10-17",
        Statement: [
            {
                Action: ["iam:Describe*"],
                Effect: "Allow",
                Resource: "*",
            },
        ]
    })
})

const rolePolicy3 = new aws.iam.RolePolicy("rolePolicy3", {
    role: exampleRole.id,
    policy: JSON.stringify({
        Version: "2012-10-17",
        Statement: [
            {
                Action: ["sqs:Describe*"],
                Effect: "Allow",
                Resource: "*",
            },
        ]
    })
})

const exclusiveRolePolicySet = new aws.iam.RolePoliciesExclusive("rolePoliciesExclusive", {
    roleName: exampleRole.name,
    policyNames: [rolePolicy1.name, rolePolicy2.name],
})

Do a pulumi up without rolePolicy3, then add rolePolicy3 and do a pulumi up and it will be created. IN fact according to AWS CLI all the policies are attached to the role:

$ aws iam list-role-policies --role-name sample_role
{
    "PolicyNames": [
        "policy1",
        "policy2",
        "policy3"
    ]
}

Subsequent pulumi up shows no changes. This means that the aws.iam.RolePoliciesExclusive fails to restrict the policy names to two in Pulumi.

Log output

No response

Affected Resource(s)

No response

Output of pulumi about

CLI          
Version      3.130.0
Go Version   go1.22.6
Go Compiler  gc

Plugins
KIND      NAME    VERSION
resource  aws     6.59.0
resource  awsx    2.17.0
resource  docker  4.5.7
resource  docker  3.6.1
language  nodejs  unknown

Host     
OS       darwin
Version  14.6.1
Arch     arm64

This project is written in nodejs: executable='/Users/anton/bin/node' version='v20.15.1'

Current Stack: anton-pulumi-corp/puexclusivemgmtresources/dev

TYPE                                                 URN
pulumi:pulumi:Stack                                  urn:pulumi:dev::puexclusivemgmtresources::pulumi:pulumi:Stack::puexclusivemgmtresources-dev
pulumi:providers:aws                                 urn:pulumi:dev::puexclusivemgmtresources::pulumi:providers:aws::default_6_59_0
aws:iam/role:Role                                    urn:pulumi:dev::puexclusivemgmtresources::aws:iam/role:Role::exampleRole
aws:iam/rolePolicy:RolePolicy                        urn:pulumi:dev::puexclusivemgmtresources::aws:iam/rolePolicy:RolePolicy::rolePolicy2
aws:iam/rolePolicy:RolePolicy                        urn:pulumi:dev::puexclusivemgmtresources::aws:iam/rolePolicy:RolePolicy::rolePolicy1
aws:iam/rolePoliciesExclusive:RolePoliciesExclusive  urn:pulumi:dev::puexclusivemgmtresources::aws:iam/rolePoliciesExclusive:RolePoliciesExclusive::rolePoliciesExclusive
aws:iam/rolePolicy:RolePolicy                        urn:pulumi:dev::puexclusivemgmtresources::aws:iam/rolePolicy:RolePolicy::rolePolicy3

Found no pending operations associated with dev

Backend        
Name           pulumi.com
URL            https://app.pulumi.com/anton-pulumi-corp
User           anton-pulumi-corp
Organizations  anton-pulumi-corp, moolumi, demo, pulumi
Token type     personal

Dependencies:
NAME            VERSION
typescript      5.6.3
@pulumi/aws     6.59.0
@pulumi/awsx    2.17.0
@pulumi/pulumi  3.138.0
@types/node     18.19.64

Pulumi locates its logs in /var/folders/gd/3ncjb1lj5ljgk8xl5ssn_gvc0000gn/T/com.apple.shortcuts.mac-helper// by default

Additional context

It is possible that the difference between Pulumi and Terraform in this case is that Pulumi does not refresh by default, when Terraform does.

Contributing

Vote on this issue by adding a 👍 reaction. To contribute a fix for this issue, leave a comment (and link to your pull request, if you've opened one already).

t0yv0 commented 1 week ago

In fact this bug reproduces in Terraform with terraform apply -refresh=false. The behavior is identical. So I believe this is strong evidence that opting out of refresh is the root cause here. We need to consider enabling default refresh on per resource basis. https://github.com/pulumi/pulumi-terraform-bridge/issues/1754

t0yv0 commented 1 week ago

https://github.com/pulumi/pulumi-aws/issues/4654 other Exclusive resources would be suspect here as well.