aws / aws-extensions-for-dotnet-cli

Extensions to the dotnet CLI to simplify the process of building and publishing .NET Core applications to AWS services
Apache License 2.0
369 stars 86 forks source link

Allow setting msbuild parameters in CloudFormation template #213

Open normj opened 2 years ago

normj commented 2 years ago

Describe the feature

When deploying a function straight to the Lambda service using the dotnet lambda deploy-function command users can specific additional MSBuild parameters passing in the --msbuild-parameters switch. When deploying via CloudFormation the project being built is being decided via the location of the project specified in the template via the Code properties. In this context there is not hook for the user to specify additional MSBuild parameters.

Use Case

For projects that need to pass in additional MSBuild configuration to build correctly for their Lambda deployments.

Proposed Solution

When building container based functions the Lambda function's metadata in the template contains docker build information.

"Function": {
    "Type": "AWS::Serverless::Function",
    "Properties": {
    "PackageType": "Image",
...
    },
    "Metadata": {
      "Dockerfile": "Dockerfile",
      "DockerContext": ".",
      "DockerTag": ""
    }
}

We should follow a similar pattern for producing the .NET zip bundle. Something like the following.

"Function": {
    "Type": "AWS::Serverless::Function",
    "Properties": {

...
    },
    "Metadata": {
      "BuildConfiguration": "CustomRelease",
      "MSBuildParameters": "/p:SpecialLambdaOptization=true"
    }
}

Other Information

No response

Acknowledgements

Targeted .NET platform

Any version the tool supports

CLI extension version

No response

Environment details (OS name and version, etc.)

Any

paul-michalik commented 2 years ago

I would support that. Currently, if you are using sam build I have not found a way to provide alternative parameters such as temporary folder location or optimization flags to the underlying dotnet lambda package . The consequence is that you can't use sam build at all. If someone knows how to make sam build to pickup an existing aws-lambda-tools-defaults.json, or how to pass it custom parameters for the msbuild-parameters option when using sam, I'll be happy to use it.

chrisoverzero commented 1 year ago

@paul-michalik sam build calls dotnet lambda package under the hood, so it will read "aws-lambda-tools-defaults.json" files in the project directory.

paul-michalik commented 1 year ago

@chrisoverzero No, it does not. Trying with v1.55, it happily ignores the "aws-lambda-tools-defaults.json" in the project directory or in the global solution directory, no matter where I put it.

chrisoverzero commented 1 year ago

Ah, I think I see the confusion. It does pick up that file in those locations with many of its settings, as I've confirmed from testing, but it doesn't read the "msbuild-parameters" setting upon sam build. As you saw in #122, there's some subtlety to which parameters are used in which commands, and I haven't entirely internalized it.

paul-michalik commented 1 year ago

Hm, but the settings are only useful for "sam build", afterwards they are irrelevant. Which settings are picked during "sam build"? There seems to be a plenty which could be useful.

chrisoverzero commented 1 year ago

Unless the architecture has changed since I last looked, sam build calls dotnet lambda package under the hood, traversing each CodeUri in the SAM template. I recall from #122 that there are some settings contingent on whether the SAM template and the project file are siblings – that is, whether they’re in the same directory. For teams with which I’m associated at my company, we’ve put common MSBuild settings (Determinstic, PublishReadyToRun) in a Directory.Build.props file, though even that has its mismatches with dotnet lambda’s expectations. Could that work for some of the settings for your use case?

All that aside, I really like this proposal!

paul-michalik commented 1 year ago

Yes, I use "Directory.Build.Props" too, in order to set common properties for all projects in a common "devkit", which typically is a solution container (I often share projects across solutions). Dotnet tooling respects this if you invoke dotnet commands or MSBuild according to common rules. However, "sam build" does not play by my rules, and I don't see many possibilities to tweak it, except: 1) add makefile metadata to the CloudFormation template 2) package the code myself and only reference the resulting zip file in the CodeUri in the temple, which works although it is not a documented behavior therefore I don't want to rely on it. I'll debug through the "sam build" in order to see how exactly they invoke "dotnet lambda". The actual problem is the "dotnet publish" invocation which somehow completely ignores the project settings and even my custom targets from .props files. This is only possible, if they invoke it from a custom working directory which prevents MSBuild tooling to search for . props.