feat(project): implement safe CDK deployment - #2058
Conversation
e34662d to
c843d80
Compare
c76b638 to
8ea3f87
Compare
8fc3679 to
f3c270c
Compare
f3c270c to
9168096
Compare
9168096 to
9d9e7f6
Compare
9d9e7f6 to
c715bfd
Compare
8484de4 to
1ab4382
Compare
1ab4382 to
a04f19b
Compare
| ); | ||
| } | ||
|
|
||
| yield* this.build(project); |
There was a problem hiding this comment.
Could we do the identity setup before synthesizing here? The generated CDK app reads agentcore/.cli/deployed-state.json during synth to resolve configured credential names to provider ARNs, but this path never creates or updates those providers, syncs their secrets, or writes the target state. On a first deploy, payment projects fail synthesis because the ARN is missing, and other resources can carry a name for a provider that does not exist. We need to provision the configured credentials and persist their target state before calling build().
There was a problem hiding this comment.
you are correct but the intention was to keep it out of this PR as to not inflate it for ease of review.
it will be done in a follow up right after this is merged. would you rather me do an interim fix that fails fast on specs containing creds?
There was a problem hiding this comment.
Nopem, good for now. I would structure it as a post-deploy hook. Credentials are now created by CDK so the post-deploy hook will simply update the credential.
…emplate loadBootstrapTemplate() returned undefined both when there is nothing embedded and when the embed is missing from a standalone binary. The first case is fine: scripts and the npm bundle have node_modules, so the Toolkit reads the template from its own package. The second is not. A binary has no node_modules, and the Toolkit resolves its package directory from a __dirname that Bun rewrote to the build machine's path, so the user sees "Unable to find package manifest" rather than anything about bootstrapping. Treat other embedded files as proof this is a binary and fail with a message that names the missing file.
Bun appends .exe to a Windows executable whose outfile carries no extension, so the emitted path was never the one we asked for. The embed assertion then read the extensionless path and failed with ENOENT, which is what turned the Windows build red. The CI smoke test already expects agentcore-windows-x64.exe, so build.ts was the only place disagreeing. Derived from the target rather than hardcoded, since `bun run compile` also builds windows-arm64, which CI does not smoke test.
1819c84 to
04663bf
Compare
tejaskash
left a comment
There was a problem hiding this comment.
Approving with the credentials followup
| @@ -104,7 +195,7 @@ export async function performCdkOperation( | |||
| // deletion a successful deploy. | |||
| if (result.stacks.length !== 1) { | |||
There was a problem hiding this comment.
We're running this check after toolkit.deploy() deletes an existing stack with no resources. Should we validate the template has resources before invoking toolkit deploy?
There was a problem hiding this comment.
I think it does, good catch. let me check to see if i can recreate this. if i can, lemme push in a fix here itself
|
good comments, I am raising a follow up addressing the 3 comments |
Two review findings from #2058, both cases of deploy trusting something it had not checked. A synthesized template with no resources makes the CDK Toolkit *delete* an existing stack of that name and return as though it deployed. #2058 caught that after the fact, by which point the stack was already gone. Check the resource count before handing the assembly to the Toolkit instead. Stack selection matched on the target-name tag alone, never on the account and region the artifact was synthesized for. Those derive from the same target today and so cannot disagree, but nothing enforced it, and the Toolkit deploys where the artifact's environment points rather than where the tag says. Both fields were also being stripped on read, since the manifest schema declared neither. stackArtifactIdForTarget becomes stackArtifactForTarget, returning the template path alongside the id so the resource check needs no second read of the manifest.
Two review findings from #2058, both cases of deploy trusting something it had not checked. A synthesized template with no resources makes the CDK Toolkit *delete* an existing stack of that name and return as though it deployed. #2058 caught that after the fact, by which point the stack was already gone. Check the resource count before handing the assembly to the Toolkit instead. Stack selection matched on the target-name tag alone, never on the account and region the artifact was synthesized for. Those derive from the same target today and so cannot disagree, but nothing enforced it, and the Toolkit deploys where the artifact's environment points rather than where the tag says. Both fields were also being stripped on read, since the manifest schema declared neither. stackArtifactIdForTarget becomes stackArtifactForTarget, returning the template path alongside the id so the resource check needs no second read of the manifest.
Two review findings from #2058, both cases of deploy trusting something it had not checked. A synthesized template with no resources makes the CDK Toolkit *delete* an existing stack of that name and return as though it deployed. #2058 caught that after the fact, by which point the stack was already gone. Check the resource count before handing the assembly to the Toolkit instead. Stack selection matched on the target-name tag alone, never on the account and region the artifact was synthesized for. Those derive from the same target today and so cannot disagree, but nothing enforced it, and the Toolkit deploys where the artifact's environment points rather than where the tag says. Both fields were also being stripped on read, since the manifest schema declared neither. stackArtifactIdForTarget becomes stackArtifactForTarget, returning the template path alongside the id so the resource check needs no second read of the manifest.
Two review findings from #2058, both cases of deploy trusting something it had not checked. A synthesized template with no resources makes the CDK Toolkit *delete* an existing stack of that name and return as though it deployed. #2058 caught that after the fact, by which point the stack was already gone. Check the resource count before handing the assembly to the Toolkit instead. Stack selection matched on the target-name tag alone, never on the account and region the artifact was synthesized for. Those derive from the same target today and so cannot disagree, but nothing enforced it, and the Toolkit deploys where the artifact's environment points rather than where the tag says. Both fields were also being stripped on read, since the manifest schema declared neither. stackArtifactIdForTarget becomes stackArtifactForTarget, returning the template path alongside the id so the resource check needs no second read of the manifest.
Summary
Known gap: projects that declare credentials
This PR deploys the stack; it does not run the pre-deploy identity setup, so it does
not write
agentcore/.cli/deployed-state.json. Nothing onrefactorwrites that filetoday, so this is a gap being carried forward rather than a regression, but it is worth
stating rather than leaving implied:
credentialsand nopaymentsdeploy correctly.credentialsisread as
undefinedby the vended app (src/assets/cdk/bin/cdk.ts:150), which is thesame value it sees today.
but the declaration is silently dropped: no credential resource appears in the template
and no provider is created. Measured on a real deploy from this branch — the deploy
exits 0, the template contains only the runtime, role, policy, metadata and SSM
parameter, and
identity api-key-credential-provider getanswersApiKeyCredentialProvider not found. Sincecredentialsisundefinedonrefactortoo, this is inherited behavior, not something this PR introduces.
app requires a
credentialProviderArnper connector (cdk.ts:177-186). Its errormessage also names
agentcore deploy, which does not exist on this branch.Provisioning credential providers, syncing their client secrets, and writing that state
file is a change of comparable size to this PR and lands next to two open provider
lifecycle bugs (#1673, #2022), so it is the immediate follow-up rather than part of the
deploy spine. That follow-up is now open as #2089, which turns the silent drop into a
created provider and the payment case into an accurate error, verified end-to-end against
a real account.
Stack
This is PR 4 of 4 decomposing #2001 and is the first PR in the stack that activates deployment. Review and merge bottom-up.
Follow-ups
Pre-deploy identity setup: create or update api-key and OAuth2 credential providers, sync client secrets, and writeOpen as feat(project): tear down the stack on a deploy of an empty project, behind --yes #2089, stacked on this PR.agentcore/.cli/deployed-state.jsonbefore synth. Also fixes the staleagentcore deployguidance insrc/assets/cdk/bin/cdk.ts:184.createCustomerMasterKey: truebootstrap policy, including recurring KMS cost and security rationale. This PR preserves the shipped CLI behavior.CDKToolkitstacks, including externally managed bootstrap infrastructure tracked by Hard-codedCDKToolkitstack name causes false bootstrap prompt #1799.typecheck, lint, format, test all pass
did npm bundle and standalone executable smoke tests