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

worried-city-86458

06/14/2021, 12:51 AM
I'm struggling to work out how to pass an output as a helm chart value for external dns...
Copy code
// external dns; <https://github.com/bitnami/charts/tree/master/bitnami/external-dns>
Logger.LogDebug("Installing external dns");
var externalDnsRole = new Role($"{prefix}-external-dns",
    new RoleArgs
    {
        AssumeRolePolicy = IamHelpers.AssumeRoleForServiceAccount(oidcArn, oidcUrl, "kube-system", "external-dns", awsProvider),
        InlinePolicies = { ["policy"] = ReadResource("ExternalDnsPolicy.json") }
    },
    new ComponentResourceOptions { Provider = awsProvider });

new Chart("external-dns",
    new ChartArgs
    {
        Namespace = "kube-system",
        FetchOptions = new ChartFetchArgs { Repo = "<https://charts.bitnami.com/bitnami>" },
        Chart = "external-dns",
        Version = config.ExternalDnsVersion,
        Values =
        {
            ["logLevel"] = "debug",
            ["policy"] = "sync",
            ["provider"] = "aws",
            ["registry"] = "txt",
            ["txtPrefix"] = "k8s.",
            ["serviceAccount.annotations"] = new InputMap<string> { ["<http://eks.amazonaws.com/role-arn|eks.amazonaws.com/role-arn>"] = externalDnsRole.Arn }
        }
    },
    new ComponentResourceOptions { Provider = provider });
The service account never gets the annotations
My bad; you can't use dotted names in chart values. The following still doesn't work though:
Copy code
new Chart("external-dns",
    new ChartArgs
    {
        Namespace = "kube-system",
        FetchOptions = new ChartFetchArgs { Repo = "<https://charts.bitnami.com/bitnami>" },
        Chart = "external-dns",
        Version = config.ExternalDnsVersion,
        Values =
        {
            ["logLevel"] = "debug",
            ["policy"] = "sync",
            ["provider"] = "aws",
            ["registry"] = "txt",
            ["txtPrefix"] = "k8s.",
            ["serviceAccount"] = new InputMap<object>
            {
                ["annotations"] = new InputMap<string>
                {
                    ["<http://eks.amazonaws.com/role-arn|eks.amazonaws.com/role-arn>"] = externalDnsRole.Arn
                }
            }
        }
    },
    new ComponentResourceOptions { Provider = provider });
Copy code
[15:29:53 ERR] (Deployment) Pulumi.ResourceException: A Pulumi.InputMap`1[[System.Object, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]] cannot be synchronously enumerated. Use GetAsyncEnumerator instead. Path: $.Values.
   at Pulumi.Kubernetes.Helm.V3.Chart(string releaseName, Union<ChartArgs, LocalChartArgs> args, ComponentResourceOptions options)+(ValueTuple<Union<ChartArgsUnwrap, LocalChartArgsUnwrap>, ImmutableHashSet<Resource>> values) => { } [1] in /_/sdk/dotnet/Helm/V3/Chart.cs:line 265
   at async Task<OutputData<U>> Pulumi.Output<T>.ApplyHelperAsync<U>(Task<OutputData<T>> dataTask, Func<T, Output<U>> func) in /_/sdk/dotnet/Pulumi/Core/Output.cs:line 263
   at async void Pulumi.Deployment+Runner+<>c__DisplayClass10_0.<WhileRunningAsync>g__HandleCompletion|0(?)+HandleCompletion(?) in /_/sdk/dotnet/Pulumi/Deployment/Deployment.Runner.cs:line 137
   at async Task<int> Pulumi.Deployment+Runner.WhileRunningAsync() in /_/sdk/dotnet/Pulumi/Deployment/Deployment.Runner.cs:line 177
The following has the same exception:
Copy code
["serviceAccount"] = new Dictionary<string, object>
{
    ["annotations"] = new InputMap<string>
    {
        ["<http://eks.amazonaws.com/role-arn|eks.amazonaws.com/role-arn>"] = externalDnsRole.Arn
    }
}
The following has a different exception:
Copy code
["serviceAccount"] = new Dictionary<string, object>
{
    ["annotations"] = new Dictionary<string, Output<string>>
    {
        ["<http://eks.amazonaws.com/role-arn|eks.amazonaws.com/role-arn>"] = externalDnsRole.Arn
    }
}
Copy code
[15:43:21 ERR] (Deployment) Running program 'D:\Devel\Mps\devops-gemini-pulumi\Gemini\bin\Debug\gemini.dll' failed with an unhandled exception:
Grpc.Core.RpcException: Status(StatusCode="Unknown", Detail="invocation of kubernetes:helm:template returned an error: failed to generate YAML for specified Helm chart: failed to create chart from template: YAML parse error on external-dns/templates/serviceaccount.yaml: error unmarshaling JSON: while decoding JSON: json: cannot unmarshal object into Go struct field .metadata.annotations of type string", DebugException="Grpc.Core.Internal.CoreErrorDetailException: {"created":"@1623642200.924000000","description":"Error received from peer ipv4:127.0.0.1:1119","file":"..\..\..\src\core\lib\surface\<http://call.cc|call.cc>","file_line":1068,"grpc_message":"invocation of kubernetes:helm:template returned an error: failed to generate YAML for specified Helm chart: failed to create chart from template: YAML parse error on external-dns/templates/serviceaccount.yaml: error unmarshaling JSON: while decoding JSON: json: cannot unmarshal object into Go struct field .metadata.annotations of type string","grpc_status":2}")
   at async Task<InvokeResponse> Pulumi.GrpcMonitor.InvokeAsync(InvokeRequest request) in /_/sdk/dotnet/Pulumi/Deployment/GrpcMonitor.cs:line 26
   at async Task<Struct> Pulumi.Deployment.InvokeRawAsync(string token, InvokeArgs args, InvokeOptions options) in /_/sdk/dotnet/Pulumi/Deployment/Deployment_Invoke.cs:line 52
   at async Task<T> Pulumi.Deployment.InvokeAsync<T>(string token, InvokeArgs args, InvokeOptions options, bool convertResult) in /_/sdk/dotnet/Pulumi/Deployment/Deployment_Invoke.cs:line 22
   at async Task<OutputData<U>> Pulumi.Output<T>.ApplyHelperAsync<U>(Task<OutputData<T>> dataTask, Func<T, Output<U>> func) x 2 in /_/sdk/dotnet/Pulumi/Core/Output.cs:line 254
   at async Task<OutputData<U>> Pulumi.Output<T>.ApplyHelperAsync<U>(Task<OutputData<T>> dataTask, Func<T, Output<U>> func) in /_/sdk/dotnet/Pulumi/Core/Output.cs:line 269
   at async void Pulumi.Deployment+Runner+<>c__DisplayClass10_0.<WhileRunningAsync>g__HandleCompletion|0(?)+HandleCompletion(?) in /_/sdk/dotnet/Pulumi/Deployment/Deployment.Runner.cs:line 137
   at async Task<OutputData<object>> Pulumi.Output<T>.Pulumi.IOutput.GetDataAsync() in /_/sdk/dotnet/Pulumi/Core/Output.cs:line 164
   at async Task<object> Pulumi.Serialization.Serializer.SerializeAsync(string ctx, object prop, bool keepResources) in /_/sdk/dotnet/Pulumi/Serialization/Serializer.cs:line 138
   at async Task<int> Pulumi.Deployment+Runner.WhileRunningAsync() in /_/sdk/dotnet/Pulumi/Deployment/Deployment.Runner.cs:line 177
   at async Task<SerializationResult> Pulumi.Deployment.SerializeFilteredPropertiesAsync(string label, IDictionary<string, object> args, Predicate<string> acceptKey, bool keepResources) in /_/sdk/dotnet/Pulumi/Deployment/Deployment_Serialization.cs:line 53
   at async Task<Struct> Pulumi.Deployment.SerializeAllPropertiesAsync(string label, IDictionary<string, object> args, bool keepResources) in /_/sdk/dotnet/Pulumi/Deployment/Deployment_Serialization.cs:line 32
   at async Task Pulumi.Deployment.RegisterResourceOutputsAsync(Resource resource, Output<IDictionary<string, object>> outputs) in /_/sdk/dotnet/Pulumi/Deployment/Deployment_RegisterResourceOutputs.cs:line 31
   at async void Pulumi.Deployment+Runner+<>c__DisplayClass10_0.<WhileRunningAsync>g__HandleCompletion|0(?)+HandleCompletion(?) in /_/sdk/dotnet/Pulumi/Deployment/Deployment.Runner.cs:line 137
The only option left is to use
externalDnsRole.Arn.Apply
and create the chart inside apply, which is not desirable. Surely, with
Values
being of type
InputMap<object>
means I should be able to use an output value in the map.
t

tall-librarian-49374

06/14/2021, 5:53 AM
🍺 1
w

worried-city-86458

06/14/2021, 6:07 AM
Thanks, @tall-librarian-49374! I can't believe I missed that I could move the "apply boundary" to just the values input map:
Copy code
new Chart("external-dns",
    new ChartArgs
    {
        Namespace = "kube-system",
        FetchOptions = new ChartFetchArgs { Repo = "<https://charts.bitnami.com/bitnami>" },
        Chart = "external-dns",
        Version = config.ExternalDnsVersion,
        Values = externalDnsRole.Arn.Apply(roleArn => new Dictionary<string, object>
        {
            ["logLevel"] = "debug",
            ["policy"] = "sync",
            ["provider"] = "aws",
            ["registry"] = "txt",
            ["txtPrefix"] = "k8s.",
            ["serviceAccount"] = new { annotations = new Dictionary<string, string> { ["<http://eks.amazonaws.com/role-arn|eks.amazonaws.com/role-arn>"] = roleArn } }
        })
    },
    new ComponentResourceOptions { Provider = provider });
Also note, re https://github.com/pulumi/pulumi/issues/7050, every time I got an exception while working through this, it wanted to tear the rest of the k8s stack down!
That is a really serious problem
t

tall-librarian-49374

06/14/2021, 6:49 AM
That must be an automation problem then 😞 we need to solve it there
What is the program exit code when it fails for you?
I guess it’s hard to say…
4 Views