aws / aws-cdk

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code
https://aws.amazon.com/cdk
Apache License 2.0
11.5k stars 3.85k forks source link

[aws-eks] addManifest should accept `Record<string, any>[]` instead of `any[]` since it must actually be a JSON map #11483

Closed kishoreallwynraj closed 3 years ago

kishoreallwynraj commented 3 years ago

Reproduction Steps

I am trying to apply a simple K8s manifest to create a namespace in the Fargate cluster, but while execution it fails to apply

var nsManifest = "{\"apiVersion\": \"v1\", \"kind\": \"Namespace\", \"metadata\": { \"name\": \"examples\"}}";
cluster.AddManifest("ns", nsManifest);

What did you expect to happen?

Provided manifest gets applies to the cluster and a new namespace gets created.

What actually happened?

Received below error while running the cdk deploy step

Custom::AWSCDK-EKS-KubernetesResource | eks-ew1-examples-dev/manifest-ns/Resource/Default (eksew1examplesdevmanifestns550D618B) Failed to create resource. Error: b'error: error validating "/tmp/manifest.yaml": error validating data: invalid object to validate; if you choose to ignore these errors, turn validation off with --validate=false\n'

On checking the generated template fragment, i see the manifest is created with extra backslashes like below.

"Manifest": "[\"{\\\"apiVersion\\\": \\\"v1\\\", \\\"kind\\\": \\\"Namespace\\\", \\\"metadata\\\": { \\\"name\\\": \\\"examples\\\"}}\"]",

Environment

Other

I also tried to create custom structs and tried to apply it instead of passing the manifest json as string like below

 cluster.AddManifest("ns", new K8sManifest
{
    ApiVersion = "v1",
    Kind = "Namespace",
    Metadata = new Metadata
    {
        Name = "examples"
     }
});

public struct K8sManifest
{
   public string ApiVersion { get; set; }
   public string Kind { get; set; }
   public Metadata Metadata { get; set; }
}

public struct Metadata
{
    public string Name { get; set; }
}

But the cdk synth process fails with below error

Unhandled exception. System.ArgumentException: Could not infer JSII type for .NET type 'K8sManifest' (Parameter 'type') at Amazon.JSII.Runtime.Services.Converters.FrameworkToJsiiConverter.InferType(IReferenceMap referenceMap, Type type)


This is :bug: Bug Report

iliapolo commented 3 years ago

@kishoreallwynraj the manifest should be passed as an array of Dictionary<string, Object>, not a string. Each dictionary representing a different resource.

The reason the string is accepted is because the typescript method signature uses any[], which translates to Object[] in C# (and Java as well).

I'm repurposing this issue to change the signature to accept a Record<string, any>[].

Thanks!

kishoreallwynraj commented 3 years ago

Thanks @iliapolo .. i am able to add the manifest now by using the approach you mentioned like below

var nsManifest = new Dictionary<string, object> {
                { "apiVersion", "v1" },
                { "kind", "Namespace" },
                { "metadata", new Dictionary<string, string> { { "name", "examples" } } }
            };
cluster.AddManifest("ns", nsManifest);
github-actions[bot] commented 3 years ago

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see. If you need more assistance, please either tag a team member or open a new issue that references this one. If you wish to keep having a conversation with other community members under this issue feel free to do so.

oliverdavidnoguerasanmartin commented 1 year ago

With this issue brokes when you passed a object, I undertand you want to have map, but with data object now doesn't work