Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

code property on aws.lambda.Function forces replacement #7

Closed
lukehoban opened this issue Jul 27, 2017 · 1 comment
Closed

code property on aws.lambda.Function forces replacement #7

lukehoban opened this issue Jul 27, 2017 · 1 comment
Assignees

Comments

@lukehoban
Copy link
Member

It looks like changes to the code property on an aws.lambda.Function are forcing it to be replaced. This causes a lot of churn as many things are keyed off of the function identity, and should not be necessary.

If you deploy this:

import {timer} from "@lumi/platform";
timer.interval("foobar", {minutes: 1}, async () => {
    console.log("hello");
});

and then change "hello" to "goodbye", you would expect to see just an in-place update of the function object. Instead, you see a replace followed by lots of create/deletes for dependent objects.

(Note - the error at the end is presumably an unrelated bug that I'm investigating now).

Applying step #1 [replace] (part of a replacement change)
+-aws:lambda/function:Function:
      [id=foobar-697d9b8fe508772267e2579706a3362694f81b2e]
      [urn=urn:lumi:test::integration:index::aws:lambda/function:Function::foobar]
    - code            : archive {
    -     "index.js": asset {
    -         "exports.handler = __5b28b23dd0f4eca7c8ded1f6335aeb995c70882f;"
    -         ""
    -         "function __5b28b23dd0f4eca7c8ded1f6335aeb995c70882f() {"
    -         "  var _this;"
    -         "  with({ handler: __7988284d11819f2f843419db36b9bd51127e9a58 }) {"
    -         "    return (function() {"
    -         ""
    -         "return function (ev, ctx, cb) {"
    -         "    handler().then(function () { cb(null, null); })["catch"](function (err) { cb(err, null); });"
    -         "};"
    -         ""
    -         "    }).apply(_this).apply(undefined, arguments);"
    -         "  }"
    -         "}"
    -         ""
    -         "function __7988284d11819f2f843419db36b9bd51127e9a58() {"
    -         "  var _this;"
    -         "  with({ }) {"
    -         "    return (function() {"
    -         ""
    -         "var _this = this;"
    -         "return function () { return __awaiter(_this, void 0, void 0, function () {"
    -         "    return __generator(this, function (_a) {"
    -         "        console.log("hello");"
    -         "        return [2 /*return*/];"
    -         "    });"
    -         "}); };"
    -         ""
    -         "    }).apply(_this).apply(undefined, arguments);"
    -         "  }"
    -         "}"
    -         ""
    -         ""
    -         "function __awaiter(thisArg, _arguments, P, generator) {"
    -         "    return new (P || (P = Promise))(function (resolve, reject) {"
    -         "        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }"
    -         "        function rejected(value) { try { step(generator.throw(value)); } catch (e) { reject(e); } }"
    -         "        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }"
    -         "        step((generator = generator.apply(thisArg, _arguments || [])).next());"
    -         "    });"
    -         "}"
    -         ""
    -         "function __generator(thisArg, body) {"
    -         "    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;"
    -         "    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;"
    -         "    function verb(n) { return function (v) { return step([n, v]); }; }"
    -         "    function step(op) {"
    -         "        if (f) throw new TypeError("Generator is already executing.");"
    -         "        while (_) try {"
    -         "            if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;"
    -         "            if (y = 0, t) op = [0, t.value];"
    -         "            switch (op[0]) {"
    -         "                case 0: case 1: t = op; break;"
    -         "                case 4: _.label++; return { value: op[1], done: false };"
    -         "                case 5: _.label++; y = op[1]; op = [0]; continue;"
    -         "                case 7: op = _.ops.pop(); _.trys.pop(); continue;"
    -         "                default:"
    -         "                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }"
    -         "                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }"
    -         "                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }"
    -         "                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }"
    -         "                    if (t[2]) _.ops.pop();"
    -         "                    _.trys.pop(); continue;"
    -         "            }"
    -         "            op = body.call(thisArg, _);"
    -         "        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }"
    -         "        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };"
    -         "    }"
    -         "}"
    -         ""
    -     }
    -     "node_modules": asset { file://node_modules }
    - }
    + code            : archive {
    +     "index.js": asset {
    +         "exports.handler = __5b28b23dd0f4eca7c8ded1f6335aeb995c70882f;"
    +         ""
    +         "function __5b28b23dd0f4eca7c8ded1f6335aeb995c70882f() {"
    +         "  var _this;"
    +         "  with({ handler: __00d4974954f1a4c25e29fbe9fe90f6b621605185 }) {"
    +         "    return (function() {"
    +         ""
    +         "return function (ev, ctx, cb) {"
    +         "    handler().then(function () { cb(null, null); })["catch"](function (err) { cb(err, null); });"
    +         "};"
    +         ""
    +         "    }).apply(_this).apply(undefined, arguments);"
    +         "  }"
    +         "}"
    +         ""
    +         "function __00d4974954f1a4c25e29fbe9fe90f6b621605185() {"
    +         "  var _this;"
    +         "  with({ }) {"
    +         "    return (function() {"
    +         ""
    +         "var _this = this;"
    +         "return function () { return __awaiter(_this, void 0, void 0, function () {"
    +         "    return __generator(this, function (_a) {"
    +         "        console.log("goodbye");"
    +         "        return [2 /*return*/];"
    +         "    });"
    +         "}); };"
    +         ""
    +         "    }).apply(_this).apply(undefined, arguments);"
    +         "  }"
    +         "}"
    +         ""
    +         ""
    +         "function __awaiter(thisArg, _arguments, P, generator) {"
    +         "    return new (P || (P = Promise))(function (resolve, reject) {"
    +         "        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }"
    +         "        function rejected(value) { try { step(generator.throw(value)); } catch (e) { reject(e); } }"
    +         "        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }"
    +         "        step((generator = generator.apply(thisArg, _arguments || [])).next());"
    +         "    });"
    +         "}"
    +         ""
    +         "function __generator(thisArg, body) {"
    +         "    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;"
    +         "    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;"
    +         "    function verb(n) { return function (v) { return step([n, v]); }; }"
    +         "    function step(op) {"
    +         "        if (f) throw new TypeError("Generator is already executing.");"
    +         "        while (_) try {"
    +         "            if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;"
    +         "            if (y = 0, t) op = [0, t.value];"
    +         "            switch (op[0]) {"
    +         "                case 0: case 1: t = op; break;"
    +         "                case 4: _.label++; return { value: op[1], done: false };"
    +         "                case 5: _.label++; y = op[1]; op = [0]; continue;"
    +         "                case 7: op = _.ops.pop(); _.trys.pop(); continue;"
    +         "                default:"
    +         "                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }"
    +         "                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }"
    +         "                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }"
    +         "                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }"
    +         "                    if (t[2]) _.ops.pop();"
    +         "                    _.trys.pop(); continue;"
    +         "            }"
    +         "            op = body.call(thisArg, _);"
    +         "        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }"
    +         "        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };"
    +         "    }"
    +         "}"
    +         ""
    +     }
    +     "node_modules": asset { file://node_modules }
    + }
      deadLetterConfig: [
          [0]: {
                   targetArn: "arn:aws:sns:us-east-2:153052954103:unhandled-error-topic-377290b8389ac3ddc4f240c08de5c6802147e089"
               }
      ]
      handler         : "index.handler"
      name            : "foobar"
      role            : "arn:aws:iam::153052954103:role/foobar-iamrole-719f4cf975e79b59952844317fbc58145a92ea24"
      runtime         : "nodejs6.10"
      timeout         : 180
info: Setting Lambda foobar-98691711c59cd888b8e77a55264a254aa5d4d88c VPC config []map[string]interface {}(nil) from API
Applying step #2 [replace] (part of a replacement change)
+-aws:cloudwatch/logGroup:LogGroup:
      [id=/aws/lambda/foobar-697d9b8fe508772267e2579706a3362694f81b2e]
      [urn=urn:lumi:test::integration:index::aws:cloudwatch/logGroup:LogGroup::foobar]
    - logGroupName   : "/aws/lambda/foobar-697d9b8fe508772267e2579706a3362694f81b2e"
    + logGroupName   : "/aws/lambda/foobar-98691711c59cd888b8e77a55264a254aa5d4d88c"
      name           : "foobar"
      retentionInDays: 1
info: CloudWatch Log Group created
Applying step #3 [replace] (part of a replacement change)
+-aws:cloudwatch/logSubscriptionFilter:LogSubscriptionFilter:
      [id=cwlsf-1506378676]
      [urn=urn:lumi:test::integration:index::aws:cloudwatch/logSubscriptionFilter:LogSubscriptionFilter::foobar]
      destinationArn: "arn:aws:lambda:us-east-2:153052954103:function:pulumi-app-log-collector-b43b2ad077b90ce2f629dada2d5f400df2b4758"
      filterPattern : ""
    - logGroup      : "/aws/lambda/foobar-697d9b8fe508772267e2579706a3362694f81b2e"
    + logGroup      : "/aws/lambda/foobar-98691711c59cd888b8e77a55264a254aa5d4d88c"
      name          : "foobar"
Applying step #4 [update]
~ aws:cloudwatch/eventTarget:EventTarget:
      [id=foobar-1d4607eef0758ce43610c38acebde2ea21566cf8-terraform-00de914977c8c7f5504533a6c4]
      [urn=urn:lumi:test::integration:index::aws:cloudwatch/eventTarget:EventTarget::foobar]
    - arn : "arn:aws:lambda:us-east-2:153052954103:function:foobar-697d9b8fe508772267e2579706a3362694f81b2e"
    + arn : "arn:aws:lambda:us-east-2:153052954103:function:foobar-98691711c59cd888b8e77a55264a254aa5d4d88c"
      name: "foobar"
      rule: "foobar-1d4607eef0758ce43610c38acebde2ea21566cf8"
error LUMI2003: Plan apply failed: rpc error: code = Unknown desc = Error applying aws:cloudwatch/eventTarget:EventTarget update: Updating CloudWatch Event Target failed: InvalidParameter: 1 validation error(s) found.
- minimum field size of 1, PutTargetsInput.Targets[0].Id.

Step #4 failed [update]: this failure was catastrophic and the provider cannot guarantee recovery
info: 3 deployed changes:
    +-3 resources replaced
Deployment duration: 9.785868681s
A catastrophic error occurred; resources states may be unknown
error: rpc error: code = Unknown desc = Error applying aws:cloudwatch/eventTarget:EventTarget update: Updating CloudWatch Event Target failed: InvalidParameter: 1 validation error(s) found.
- minimum field size of 1, PutTargetsInput.Targets[0].Id.
@joeduffy joeduffy self-assigned this Jul 31, 2017
@joeduffy
Copy link
Member

I know why this is happening, however it unfortunately turned up quite a number of problems.

The root cause is that we regenerate function_name in the default calculation logic in the bridge, as part of the whole auto-naming scheme. This is interpreted as a change in state and, because a change to function_name implies replacement, the provider happily replaces it.

I've filed pulumi/pulumi-terraform#17 to track working around this.

Longer term, we need to do a bit of surgery on diffing in general here. We don't treat defaults the right way in general, when it comes to diffs, and we need to let the bridge get in on the game.

joeduffy added a commit that referenced this issue Aug 1, 2017
This ingests fixes in

    pulumi/pulumi@5fb014e

and

    pulumi/pulumi-terraform@f2eb1a2

which fixes the problem with Lambdas being erroenously replaced
in #7.
@joeduffy joeduffy closed this as completed Aug 1, 2017
corymhall added a commit that referenced this issue Jul 11, 2024
# This is the 1st commit message:

Fix import resources with provider default tags

We have special logic around applying default provider tags to
resources. This logic only applied to the `Check` call which means it
was not applied when you were importing resources. This PR extends that
logic to also run during the `Read` call.

fix #4030, fix 4080

# This is the commit message #2:

skip test

# This is the commit message #3:

fixing test

# This is the commit message #4:

Adding more tests

# This is the commit message #5:

Upgrade pulumi-terraform-bridge to v3.86.0 (#4160)

This PR was generated via `$ upgrade-provider pulumi/pulumi-aws
--kind=bridge --pr-reviewers=guineveresaenger`.

Fixes #4091
Fixes #4137

---

- Upgrading pulumi-terraform-bridge from v3.85.0 to v3.86.0.
- Upgrading pulumi-terraform-bridge/pf from v0.38.0 to v0.39.0.
# This is the commit message #6:

chore: run upstream provider-lint (#4120)

This adds a step for running the upstream `provider-lint` make target.

As part of this I had to fix some of the patches which violated some
lint rules.

**0009-Add-ECR-credentials_data_source.patch**
- `ForceNew` does not apply to data sources

**0032-DisableTagSchemaCheck-for-PF-provider.patch**
- Schema have to have a `Type`
- Also needed to add a ignore for `S013` which forces `Computed`,
  `Optional` or `Required` to be set. Looks like it can't recognize the
  `tagsComputed` var

**0034-Fail-fast-when-PF-resources-are-dropped.patch**
- Added a lint ignore for a rule which doesn't allow panics

**0050-Normalize-retentionDays-in-aws_controltower_landing_.patch**
- This test doesn't actually need a region or partition so replacing
  with a placeholder

closes #4110
# This is the commit message #7:

fix: CVE-2024-24791 (#4175)

Fixes #4163

Upgrades minimally required Go versions to those unaffected by
CVE-2024-24791.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants