pulumi / pulumi-aws-native

AWS Native Provider for Pulumi
Apache License 2.0
94 stars 17 forks source link

Lambda Function update fails #277

Closed mikhailshilkov closed 1 year ago

mikhailshilkov commented 2 years ago

Given the following resource deployed

const ping = new awsnative.lambda.Function("ping", {
  role: role.arn,
  runtime: "nodejs14.x",
  handler: "index.handler",
  code: {
      zipFile: `
      exports.handler = function(event, context, callback){
        callback(null, "TODO");
      };`,
    },
  functionName: "ping-name2",
});

I then try changing the handler property and update the resource. The update fails though:

CloudControl: UpdateResource, https response error StatusCode: 400, RequestID: 6912f4f9-211b-4620-9834-0670b25ae58e, api error ValidationException: Model validation failed (#: required key [Code] not found)

Our patch package looks like this:

{
  "ClientToken": "3e99641d-2608-4ef2-9640-f1d8bfe3140e",
  "Identifier": "ping-name2",
  "PatchDocument": "[{\"op\":\"replace\",\"path\":\"/Handler\",\"value\":\"index.handler2\"}]",
  "TypeName": "AWS::Lambda::Function"
}

which looks reasonable to me.

I tried changing code as well, but then I get a different error:

CloudControl: UpdateResource, https response error StatusCode: 400, RequestID: 76597d5c-93b5-472b-b48f-e6990eadb2fc, api error ValidationException: [REPLACE Operation] noSuchPath in source, path provided : //Code

Our patch has /Code not //Code:

{
  "ClientToken": "cd2e711f-02e6-4f0c-8fc8-fe867abbbd4b",
  "Identifier": "ping-name2",
  "PatchDocument": "[{\"op\":\"replace\",\"path\":\"/Code\",\"value\":{\"ZipFile\":\"\\n      exports.handler = function(event, context, callback){\\n        callback(null, \\\"TODO2\\\");\\n      };\"}}]",
  "TypeName": "AWS::Lambda::Function"
}

Is that an upstream issue or is the provider doing something wrong?

mikhailshilkov commented 2 years ago

AWS:

There are certain combinations of schema attributes that can make patching complicated.
Since Code is modeled as a write-only property, you should use ADD rather than REPLACE as the patch action. When doing an update, Cloud Control is doing a read, applying the JSON patch to that, and using that resulting resource model. That resource model needs to conform to the schema, and for Lambda, Code is both required and write-only. The error for the missing property was because the property is required but not returned by the read operation because it's write-only; it was therefore missing in the final model. The second error was because the JSON patch itself failed; since the property wasn't returned by the read, it's effectively an add rather than a replace.

ashevtsov-wawa commented 2 years ago

Wondering if a workaround would be implemented for such cases in AWS Native provider? I ran into a similar issue with Synthetics Canary. I can open a separate issue but these two seem related

error: operation error CloudControl: UpdateResource, https response error StatusCode: 400, RequestID: 30e921ee-f8ee-447f-8b4a-e9d238ac89fd, api error ValidationException: Model validation failed (#: required key [StartCanaryAfterCreation] not found)
jkodroff commented 1 year ago

I am also seeing this issue with the following program:

const bucket = new aws.s3.Bucket("bucket", {
  versioning: {
    enabled: true,
  }
});

const functionCode = new aws.s3.BucketObject("function-code", {
  bucket: bucket.bucket,
  source: new pulumi.asset.FileAsset("../lambda/blogPost/target/blogPost-1.0-SNAPSHOT.jar"),
});

const func = new awsNative.lambda.Function("my-func", {
  code: {
    s3Bucket: functionCode.bucket,
    s3Key: functionCode.key,
    s3ObjectVersion: functionCode.versionId,
  },
  role: role.arn,
  runtime: "java11",
  handler: "com.pulumi.blogPostHandler",
});

Error message:

    error: operation error CloudControl: UpdateResource, https response error StatusCode: 400, RequestID: 89fbdb54-daf5-4aa3-81ce-c51f08431a6c, api error ValidationException: [REPLACE Operation] noSuchPath in source, path provided : //Code