https://pulumi.com logo
#dotnet
Title
s

straight-flower-13757

02/27/2020, 5:32 PM
Hi, I came back with another question: I have a stack that consists of a
ComponentResource
like
Copy code
public class EcsService : ComponentResource
    {
        public EcsService(string name, EcsServiceResourceOptions options)
            : base("foo:pulumi:ecs", name, options)
        {
             ...
             var parameters = new List<Pulumi.Aws.Ssm.Parameter>();

            foreach (KeyValuePair<string, string> variable in options.EnvironmentVariables) // EnvironmentVariables is InputMap<string>
            {
                var Parameter = new Pulumi.Aws.Ssm.Parameter(variable.Key, 
                ...
                , new CustomResourceOptions { Parent = this });
                parameters.Add(Parameter);
            }
            ...
         }
     }
I’m trying to use this component like:
Copy code
class Program
    {
        static Task<int> Main()
        {
            return Deployment.RunAsync(() =>
            {
                var config = new Config();

                var environmentVariables = new InputMap<string>();

                foreach (var item in config.RequireObject<JsonElement>("environmentVariables").EnumerateObject()) //those environmentVariables are inserted as pulumi config set --path environmentVariables.foo val .. etc
                    environmentVariables.Add(item.Name, item.Value.GetString());

                var service = new EcsService(config.Require("name"), new EcsServiceResourceOptions
                {
                    ...
                    EnvironmentVariables = environmentVariables,
                    ...
                });
      }
I’m getting the following exception:
Copy code
error: Running program '....' failed with an unhandled exception:
    System.NotSupportedException: A Pulumi.InputMap`1[[System.String, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]] cannot be synchronously enumerated. Use GetAsyncEnumerator instead.
But I can’t await the foreach in the constructor of
EcsService
, any advice ? And what you think around the way I’m importing multiple key/value pairs from config into an InputMap<string>, is there better way ?
t

tall-librarian-49374

02/28/2020, 7:27 AM
Yes, you can’t enumarate
InputMap
because it may contain unresolved values.
EcsServiceResourceOptions
is a class of yours, right? If so, you could make
EnvironmentVariables
just a normal C# dictionary and iterate through it. Alternatively, you’d need to use
Apply
on
InputMap
and do the processing inside. However, creating resources inside
Apply
should generally be avoided.
s

straight-flower-13757

02/28/2020, 8:12 AM
for
EcsServiceResourceOptions
correct, it’s mine Thanks for the suggestion on using dictionary
If I want to create a policy document that needs to insert all
arn
of the
ssm parameter
like:
Copy code
public class EcsService : ComponentResource
    {
        public EcsService(string name, EcsServiceResourceOptions options)
            : base("foo:pulumi:ecs", name, options)
        {
             ...
             var parameters = new List<Pulumi.Aws.Ssm.Parameter>();
            foreach (var variable in options.EnvironmentVariables)
            {
                var Parameter = new Pulumi.Aws.Ssm.Parameter(variable.Key, 
                ...
                , new CustomResourceOptions { Parent = this });
                parameters.Add(Parameter);
            }
            ...
            var taskInlineRoleDocument = Pulumi.Aws.Iam.Invokes.GetPolicyDocument(new Pulumi.Aws.Iam.GetPolicyDocumentArgs
            {
                Statements = {
                    new Pulumi.Aws.Iam.Inputs.GetPolicyDocumentStatementsArgs {
                        Effect = "Allow",
                        Resources = parameters.Select(_=>_.Arn.Apply(arn => arn)).ToList(), //what to do here to await all parameters to be created, and then extract their arns ?
                        Actions = { "ssm:GetParameters", "ssm:GetParameter" }
                    }
                  }
                }
            });
            ...
         }
     }
I’m finding it hard to create dynamic resources, can we have more examples were we create multiple resources and then feed them into another resource like the above example Thank in advance !
t

tall-librarian-49374

02/29/2020, 8:53 PM
.Apply(arn => arn)
does nothing. You can’t await outputs. Instead, you could convert a list of outputs to an output of list with
Output.All
, however this means that you have to make your
GetPolicyDocument
call inside an
Apply
.
s

straight-flower-13757

03/02/2020, 8:05 AM
@tall-librarian-49374, the Output.All accepts a list of Inputs, not Outputs. Am I missing something ?
t

tall-librarian-49374

03/02/2020, 8:33 AM
Each Output is assignable to Input. I guess we may need to add an overload for list of outputs.
s

straight-flower-13757

03/02/2020, 9:15 AM
The final taskInlineRoleDocument would look like
Copy code
var taskInlineRoleDocument = Output.All<string>(parameters.Select(_ => _.Arn).Cast<Input<string>>().ToArray())
            .Apply(async list =>
            {
                return await Pulumi.Aws.Iam.Invokes.GetPolicyDocument(new Pulumi.Aws.Iam.GetPolicyDocumentArgs
                {
                    Statements =
                    {
                        new Pulumi.Aws.Iam.Inputs.GetPolicyDocumentStatementsArgs {
                            Effect = "Allow",
                            Resources = list.ToList(),
                            Actions = { "ssm:GetParameters", "ssm:GetParameter" }
                        },
                    }
                });
            });
But I’m getting `System.InvalidCastException: Unable to cast object of type ‘Pulumi.Output`1[System.String]’ to type ’Pulumi.Input`1[System.String]. ` my understanding that assignable should mean castable.
let me know if I should open an Issue on Github, so you can track.
somehow this one works
Output.All<string>(parameters.Select(_ => (Input<string>)_.Arn).ToArray())
t

tall-librarian-49374

03/02/2020, 9:42 AM
Feel free to open an issue to support
Output.All(outputs)
s

straight-flower-13757

03/02/2020, 9:50 AM
Thank @tall-librarian-49374, great work ! I will give it a shot with a PR, let me try contribute 😄