aws-amplify / amplify-cli

The AWS Amplify CLI is a toolchain for simplifying serverless web and mobile development.
Apache License 2.0
2.81k stars 821 forks source link

Amplify updates lambda CFN templates on each push #3068

Open artyom-melnikov opened 4 years ago

artyom-melnikov commented 4 years ago

When creating lambda functions through amplify function add amplify creates CloudFormation template. This template is meant to be stored in the git repository (because it describes lambda and can have manual changes). The problem is that on each amplify push this file is modified with the following lines:

                "Code": {
                    "S3Bucket": "<bucket-name>",
                    "S3Key": "<build-zip-file-name>"
                }

Later you need to either manually rollback files in git or resolve merge conflicts for those lines which makes no sense.

I propose to not update those files and perform all generation in the temp files

kaustavghosh06 commented 4 years ago

@artyom-melnikov The S3Key and Bucket needs to change whenever there is an update in your src/ code. This needs to change to trigger a build in Cloudformation (For Cloudformation to detect a change) and re-deploy your lambda with a changed source code. Do you see this behavior even when there are no changes to your source code?

artyom-melnikov commented 4 years ago

No i don't see this behavior when code is not changed. I see this when i'm initing new env. My team use amplify end each team member has own dev environment. Therefore each one of us has different S3Key and S3Bucket params and we have issues storing this templates in git because of that

kaustavghosh06 commented 4 years ago

@artyom-melnikov Yes, we're aware of this. This wouldn't cause any issues deploying since the keys are generated dynamically on each push. We are looking at a solution where we build the S3Key based on the hash code of the src code - that way the key is consistent across multiple environments and sandboxes.

cyrfer commented 4 years ago

Any progress? This problem is really annoying!

cyrfer commented 4 years ago

Is there an RFC that would provide guidance to the community if the core dev team is not prioritizing this? @kaustavghosh06

lorengordon commented 4 years ago

A cdk provider for amplify, where the amplify implementation used the fromAsset method of the cdk lambda module would also address this...

cyrfer commented 3 years ago

@renebrandel this needs attention. How about building a docker image of the lambda artifact to know if any change occurred rather than always bundling the lambda for each deploy. Also, the artifact path should be passed to the stack as a parameter, not by modifying the template.

JGillam commented 3 years ago

This continues to be an issue and I believe the fix is straightforward. As the OP mentioned, the problem is the function cloudformation stacks have the following section automatically overwritten on an environment change (i.e. amplify env checkout:

"Code": {
    "S3Bucket": "<bucket-name>",
    "S3Key": "<build-zip-file-name>"
}

Note: this happens even if the function's code is identical in both environments (this is the key annoyance).

The bucket-name, in particular, is different for each environment. It follows the same naming convention as the main stack name, which is something like amplify-${appName}-${env}-${number}-deployment. I'm not sure where that ${number} comes from but it doesn't seem to ever change for a given environment.

I have noticed that the <build-zip-file-name> does NOT change on an environment change if the code is identical. I would expect this to change if the version of code in one environment was different from the version in another.

Solution Going back to the "S3Bucket" format of amplify-${appName}-${env}-${number}-deployment, or rather {$mainStackName}-deployment... why can't the S3Bucket value just be populated using a variable instead of overwritten with the stack name on each environment change? I don't know if this is accurate (I'm still learning cloudformation syntax) but something like:

"Code": {
    "S3Bucket": {
        "Fn::Join":  [
            "",
            {
                "Fn::GetAtt": [
                    "awscloudformation",
                    "Outputs.Name"
                 ]
            },
            "-deployment"
        ]
    },
    "S3Key": "<build-zip-file-name>"
}

The one part I'm not sure about is where I have awscloudformation under Fn::GetAtt. I'm not sure how to get a handle on the main application stack to retrieve its name from within a function stack. Basically that needs to pull in the awscloudformation.StackName value from inside of your team-provider-info.json file.

If the above could be done, I think this would solve the issue because then the only time the stack would need to change is if the code was modified. It would no longer change just because of switching environments.

GeorgeBellTMH commented 3 years ago

As someone who switches environments often, this would speed up deployments.

josefaidt commented 2 years ago

cc @edwardfoyle for multi-env refactor visibility