Is there a way to tell pulumi to update aws tags? ...
# getting-started
c
Is there a way to tell pulumi to update aws tags? It appears that it has identified that there’s a difference in tags, but doesn’t actually do anything about it.
Copy code
updating stack...
Updating (test22):

    pulumi:pulumi:Stack AUTOIAM-TAMTOOL-test22 running
    aws:iam:User test22  [diff: ~tags]
 ~  aws:iam:UserPolicy useast-partner-datafeed updating [diff: ~policy]
 ~  aws:iam:UserPolicy useast-partner-datafeed updated [diff: ~policy]
    pulumi:pulumi:Stack AUTOIAM-TAMTOOL-test22

Resources:
    ~ 1 updated
    2 unchanged
b
can you show me the expanded diff?
c
of the tags? or is that a pulumi option to display an expanded diff?
basically i’m just adding an additional tag to the dictionary and updating the stack
oh i think i found what you’re referring to. we’re using an s3 backend, so i don’t have the expanded diff from the webui
l
You can select "Details" when running from the CLI, or run
pulumi diff
with the detailed option (I forget what it is..)
c
or run
pulumi diff
with the detailed option
It's
--diff
. So
pulumi up --diff
or
pulumi preview --diff
.
c
sorry to make it even more complicated, but i’m using the automation api
let me see if there’s an equivalent command to get the diff
l
The automation-api shouldn't affect things so long as the stack exists in state. You can still run
pulumi preview --diff --stack <stackname>
from the command line. You might need to create a temporary "fake" stack yaml file? Not sure. Ideally, you won't have to...
c
i think i was able to achieve the same thing using
await stack.PreviewAsync(new PreviewOptions() {Diff = true});
i don’t see the iam user tags in the diff at all. this is the policy update that’s also happening.
Copy code
Previewing update (test22):
  pulumi:pulumi:Stack: (same)
    [urn=urn:pulumi:test22::AUTOIAM-TAMTOOL::pulumi:pulumi:Stack::AUTOIAM-TAMTOOL-test22]
    ~ aws:iam/userPolicy:UserPolicy: (update)
        [id=test22:thetradedesk-useast-partner-datafeed]
        [urn=urn:pulumi:test22::AUTOIAM-TAMTOOL::aws:iam/userPolicy:UserPolicy::thetradedesk-useast-partner-datafeed]
        [provider=urn:pulumi:test22::AUTOIAM-TAMTOOL::pulumi:providers:aws::default_5_13_0::288879a8-1da1-4fcb-ac19-7f4d43bc7d7c]
      ~ policy: (json) {
            Id       : "AutoIAM"
          ~ Statement: [
              ~ [0]: {
                        Action   : "s3:ListBucket"
                      ~ Condition: {
                          ~ StringLike: {
                              ~ s3:prefix: [
                                    [0]: "test22/*"
                                    [1]: "test222/*"
                                    [2]: "test2222/*"
                                  + [3]: "test22222/*"
                                ]
                            }
                        }
                        Effect   : "Allow"
                        Resource : "arn:aws:s3:::thetradedesk-useast-partner-datafeed"
                        Sid      : "thetradedeskuseastpartnerdatafeed1"
                    }
              ~ [1]: {
                        Action  : [
                            [0]: "s3:GetObject"
                            [1]: "s3:GetObjectAcl"
                        ]
                        Effect  : "Allow"
                      ~ Resource: [
                            [0]: "arn:aws:s3:::thetradedesk-useast-partner-datafeed/test22/*"
                            [1]: "arn:aws:s3:::thetradedesk-useast-partner-datafeed/test222/*"
                            [2]: "arn:aws:s3:::thetradedesk-useast-partner-datafeed/test2222/*"
                          + [3]: "arn:aws:s3:::thetradedesk-useast-partner-datafeed/test22222/*"
                        ]
                        Sid     : "thetradedeskuseastpartnerdatafeed2"
                    }
                [2]: {
                        Action  : [
                            [0]: "s3:GetBucketLocation"
                            [1]: "s3:GetBucketACL"
                        ]
                        Effect  : "Allow"
                        Resource: "arn:aws:s3:::thetradedesk-useast-partner-datafeed"
                        Sid     : "thetradedeskuseastpartnerdatafeed3"
                    }
            ]
            Version  : "2012-10-17"
        }
Resources:
    ~ 1 to update
    2 unchanged
l
Hmm. Odd. How have you updated the tags? Is it by changing defaultTags? Afaik, those updates only happen when resources are also changed for other reasons. But if you've changed tags, then it should work...
c
No. I’m passing a dictionary that has 1 new tag in addition to the old tag.
Ok I think I figured it out. The tag can’t have an empty string as a value or pulumi seems to ignore it. I was adding a tag with POO-111 as the key and “” as the value.
when I put value = “1” it shows up in the diff
Copy code
Previewing update (test22):
  pulumi:pulumi:Stack: (same)
    [urn=urn:pulumi:test22::AUTOIAM-TAMTOOL::pulumi:pulumi:Stack::AUTOIAM-TAMTOOL-test22]
    ~ aws:iam/user:User: (update)
        [id=test22]
        [urn=urn:pulumi:test22::AUTOIAM-TAMTOOL::aws:iam/user:User::test22]
        [provider=urn:pulumi:test22::AUTOIAM-TAMTOOL::pulumi:providers:aws::default_5_13_0::288879a8-1da1-4fcb-ac19-7f4d43bc7d7c]
      ~ tags: {
          + POO-1111: "1"
        }
Copy code
pulumi:pulumi:Stack AUTOIAM-TAMTOOL-test22 running
 ~  aws:iam:User test22 updating [diff: ~tags]
 ~  aws:iam:User test22 updated [diff: ~tags]
is this intentional? seems like a bug. aws allows empty values.
Copy code
The tag key must be a minimum of 1 and a maximum of 128 Unicode characters in UTF-8.
The tag value must be a minimum of 0 and a maximum of 256 Unicode characters in UTF-8.
l
Don't know. It may be a map implementation issue, and JS' idea of falsy including the empty string.
When you say you're adding it to a dictionary, do you mean you're using the Map class? Or are you using Record / object (
{[key: string]: string}
)? If you're just doing
tags: { 'POO-111': "" }
and it's not working, then I'd say that's a bug.
c
yes basically map class. I’m using C# dotnet, so it’s the Dictionary class. so basically it went from
{{"SomeOriginalTag", "SomeValue"}}
to
{{"SomeOriginalTag","SomeValue"}, {"POO-111", ""}}
and that didn’t work with the value as an empty string, which is a valid tag according to aws
I’m able to work around this by assigning a non-empty value, but I feel that pulumi’s behavior should match what AWS says is a valid tag.
Any idea if this is an issue in pulumi? or the pulumi aws provider? I can open an issue on github, but not sure which repo.
l
Yes it should. There is a bug: that should work. I don't know how it works under the hood, but if the problem is with falsy values and empty strings (seems unlikely, I don't think "" is falsy in C#?), then you might try using the C# equivalent of
pulumi.output("")
? Since it's a "real" object, it might get around the "there's no object here, I'm skipping this" problem; but Pulumi still resolves it to the empty string.
I can't find the C# version. This is the TS/JS function I'm referring to: https://www.pulumi.com/docs/reference/pkg/nodejs/pulumi/pulumi/#output Maybe in C# you can just call
new Output("")
?
c
it doesn’t look like I can do that since UserArgs accepts tags as a Dictionary<string,string> as referenced here if you click on C# https://www.pulumi.com/registry/packages/aws/api-docs/iam/user/#inputs
not sure if there’s any point in doing
Pulumi.Output.Create("").ToString()
l
I'm pretty confident that the docs mean Input<string> when they say string. Look in the real API. The docs are simplified for readability.
I'm also pretty confident that Output.ToString() is never the answer.
c
it appears that Tags takes an InputMap<string>. A dictionary<string,string> seems to be automatically converted. I created an InputMap<string> object and passed that instead, but results are the same maybe because it’s still using string. I’m not really seeing a way to pass in Input<string> or Output<string>.
l
Have you tried
Pulumi.Output.Create("")
? Without the ToString(), that'd be wrong.
c
I did but inputmap<string> won’t take an output object
l
I don't know about the C# implementation. In Typescript, Outputs are Inputs; is that the same in C#? Or do you have to wrap an output to make it into an input?
c
I think the string is the input. The InputMap<string> takes strings, not Inputs. I could be misunderstanding how this works though.
l
It should take Input<string>, which (in Typescript) is a union of string and Output<string>. Everything in Pulumi that takes a string can also take an Output<string>.
c
Ok, so I created an InputMap<string> object and saw that .Add() takes a string and an Input<string>. I was able to do an Output.Create(“”) and pass that in for an Input<string> like you said. I then passed this object instead of the dictionary. The end result is the same. Tag difference identified and no action.
Copy code
var inputmap = new InputMap<string>();
inputmap.Add("AutoIAMCreated", "true");
inputmap.Add("test",Output.Create(""));
Copy code
updating stack...
Updating (test22):

    pulumi:pulumi:Stack AUTOIAM-TAMTOOL-test22 running
    aws:iam:User test22  [diff: ~tags]
    aws:iam:UserPolicy thetradedesk-useast-partner-datafeed
    pulumi:pulumi:Stack AUTOIAM-TAMTOOL-test22

Resources:
    3 unchanged
l
😞
Comment in that issue says:
IN general I have a suspicion that Pulumi data model that's communicated between the user program and Pulumi Engine, providers, etc, does not support map entries with null values (considers them to be equivalent to omitting the key from the map)
c
yeah that looks pretty similar. their dictionary is <string,object> but mine was <string,string>. InputMap is a Pulumi class.
l
Vote for the issue then, add some notes / MCVE, and watch it 🙂
c
set a slack reminder for tomorrow morning. heading home. glad it wasn’t just me.