jsii icon indicating copy to clipboard operation
jsii copied to clipboard

Amazon.CDK.AWS.ElasticBeanstalk.CfnEnvironment: CfnEnvironmentProps.OptionSettings requires primitive array

Open ikirkpat opened this issue 2 years ago • 1 comments

Describe the bug

CDK language: C# .NET Core Amazon.CDK.Lib Nuget Version: 2.23.0

I was trying to deploy an Elastic Beanstalk environment using the CDK. I had a collection of OptionSettings defined as an IEnumerable<OptionSettingProperty> which I was building using C# Linq. When I ran cdk synth, I found that the options I was passing in weren't showing up. When I was debugging, I found that if I converted it to a primitive array, it did show up in CDK synth.

This took me quite a few hours to find and I only happened to find it as I stumbled upon it when trying to hard code values to debug. The CDK library doesn't make this clear because the CfnEnvironmentProps.OptionSettings is defined as an object?. There's no type definition and nothing in documentation to explain this. It's also quite counter intuitive for a strongly typed language like C#. I would expect the definition to be some sort of Union type if it can indeed be multiple types... something more than just object? cause it can't actually be any object? type... or if it can, it doesn't work.

Expected Behavior

I would expect one of two things:

  1. The library to be updated with an actual type that restricts what you can pass in. Rather than the definition be public object? OptionSettings { get; set; }, it should be something like OptionSettingProperty[] OptionSettings { get; set; }. That way, developers know it can't be any collection type; it has to be a primitive array.

OR

  1. If it truely does accept any object type, the library should in fact allow any object type... whatever that means. If it's defined as object?, It should handle something like OptionSettings = new List<OptionSettingProperty>() { ... }.Concat(new List<OptionSetingProperty>() { ... }) (the Concat is C# Linq which produces some implementation of IEnumerable).

Current Behavior

I had a collection of OptionSettings defined as an IEnumerable<OptionSettingProperty> which I was building using C# Linq (using .Concat calls on the list). When I ran cdk synth, I found that the options I was passing in weren't showing up. When I was debugging, I found that if I converted it to a primitive array, it did show up in CDK synth.

Reproduction Steps

CfnEnvironment environment = new CfnEnvironment(
  this.scope,
  "BackendHost",
  new CfnEnvironmentProps()
  {
    ApplicationName = hostArguments.ElasticBeanstalkApplicationName,
    EnvironmentName = hostArguments.ElasticBeanstalkEnvironmentName,
    Description = hostArguments.Description ?? hostArguments.ElasticBeanstalkEnvironmentName,
    PlatformArn = hostArguments.PlatformArn,
    VersionLabel = "...",
    Tier = new {
      Name = "WebServer",
      Type = "Standard"
    },
    OptionSettings = new OptionSettingProperty[]
    {
      new OptionSettingProperty()
      {
      ... // doesn't matter what options are defined
      }
    }.Concat(hostArguments.LoadBalancerListeners.SelectMany(listener =>
      new OptionSettingProperty[]
      {
        //build options
      })) // Adding .ToArray() here makes this work. Leaving it out makes it fail in that cdk synth doesn't pick up the options.
});

Possible Solution

No response

Additional Information/Context

No response

CDK CLI Version

2.23.0

Framework Version

netcoreapp3.1

Node.js Version

netcoreapp3.1

OS

Ubuntu 20.04.4

Language

.NET

Language Version

No response

Other information

No response

ikirkpat avatar Jun 01 '22 14:06 ikirkpat

Thanks for reporting this @ikirkpat, I'm going to transfer this to the jsii repository since this seems related to jsii 🙂

peterwoodworth avatar Jun 02 '22 01:06 peterwoodworth