Enable db commands for externally-managed databases - #173
Conversation
|
I think we can do this without any confirmation changes by inspecting
`DATABASE_URL` if a database isn’t connected.
…On Tuesday, August 11, 2026, Brendan Smith ***@***.***> wrote:
Closes #146 <#146>.
Adds --external-database <postgres|mysql> to apppack create app, which
sets a new ExternalDatabaseEngine CloudFormation parameter so db shell/db
dump/db load can target an externally-managed database (Neon, Crunchy,
etc.) reachable via the app's DATABASE_URL config variable. Also adds a
matching interactive prompt in AskForDatabase (for apppack modify app),
client-side validation (mutually exclusive with --addon-database/--addon-
database-name, engine must be postgres or mysql), and replaces the
unhelpful "unknown database engine " error with a targeted message pointing
users at either apppack modify app/--external-database or apppack create
database.
*Depends on the formations change (apppack-backend) landing and being
released first* — until formations emits dbutils.engine for
externally-configured apps, setting this flag has no effect.
*Caveat carried over from the spec:* apppack db load's load-from-s3.sh
script likely does a DROP/CREATE of the target database, which some managed
providers (e.g. Neon) may not permit for the app's role. db shell and db
dump are the confident wins here; db load may not reach full parity even
after this lands.
Happy path (DBShellTaskInfo/DBDumpLocation/DBDumpLoadFamily, isPostgres
in cmd/db.go) is unchanged.
Want a Test Plan section added, or is this concise enough as-is?
------------------------------
You can view, comment on, or merge this pull request online at:
#173
Commit Summary
- 85333e4
<85333e4>
Add --external-database flag for externally-managed databases
File Changes
(5 files <https://github.com/apppackio/apppack/pull/173/files>)
- *M* app/app.go
<https://github.com/apppackio/apppack/pull/173/files#diff-0f1d2976054440336a576d47a44a37b80cdf6701dd9113012bce0e3c425819b7>
(53)
- *A* app/db_test.go
<https://github.com/apppackio/apppack/pull/173/files#diff-0b83ab9ace3cef740a068338080411c0dbf6939f6312fa859e21eecdba4ba7cf>
(55)
- *M* cmd/create.go
<https://github.com/apppackio/apppack/pull/173/files#diff-e52f1f4fa0c533e3287cbe2ef0436582b5ca471a3fddcdf1f49fecd1ec0c7d13>
(1)
- *M* stacks/app_pipeline.go
<https://github.com/apppackio/apppack/pull/173/files#diff-4d723cfd1f5868b91d58c87c8889fe5876308ca123e662b4dfd1d92b886539a6>
(162)
- *M* stacks/app_pipeline_test.go
<https://github.com/apppackio/apppack/pull/173/files#diff-8896a004e806c4fd2a86ad540f059d01b03bbfc77d6d4b8e78488a5751db8f8e>
(124)
Patch Links:
- https://github.com/apppackio/apppack/pull/173.patch
- https://github.com/apppackio/apppack/pull/173.diff
—
Reply to this email directly, view it on GitHub
<#173?email_source=notifications&email_token=AACN5NAMWYT6CG26WRO62UD5JN737A5CNFSNUABEM5UWIORPF5TWS5BNNB2WEL2QOVWGYUTFOF2WK43UF42DENJWG43TANJTGGTHEZLBONXW5KTTOVRHGY3SNFRGKZFFMV3GK3TUVRTG633UMVZF6Y3MNFRWW>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AACN5NFYIIMRRSSFGCMONXD5JN737AVCNFSNUABFKJSXA33TNF2G64TZHMZTCOJXGM2TENBVHNEXG43VMU5TKMJSGQZTQNZWHE4KC5QC>
.
Triage notifications, keep track of coding agent tasks and review pull
requests on the go with GitHub Mobile for iOS
<https://github.com/notifications/mobile/ios/AACN5NF5N7GLMFI26QSEAPL5JN737A5CNFSNUABEM5UWIORPF5TWS5BNNB2WEL2QOVWGYUTFOF2WK43UF42DENJWG43TANJTGGTHEZLBONXW5KTTOVRHGY3SNFRGKZFFMV3GK3TUVJTG633UMVZF62LPOM>
and Android
<https://github.com/notifications/mobile/android/AACN5NBOHZEBM7PTHYPEJIL5JN737A5CNFSNUABEM5UWIORPF5TWS5BNNB2WEL2QOVWGYUTFOF2WK43UF42DENJWG43TANJTGGTHEZLBONXW5KTTOVRHGY3SNFRGKZFFMV3GK3TUVZTG633UMVZF6YLOMRZG62LE>.
Download it today!
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
|
ipmb reviewed #173 and pointed out the user should never have to type the database engine -- it's inferable from the DATABASE_URL scheme. Delete --external-database and both interactive prompts; SetInternalFields now auto-detects the engine from the app's DATABASE_URL config variable via SSM, for both `create app` and `modify app`. A managed AppPack database and pipelines/review apps always force the field back to "", so this is idempotent no matter how many times `modify app` runs. Any SSM/parse failure is silent (the common case, since `create app` runs before the app exists); an unrecognized scheme still gets one warning line, since there's no longer a flag to fall back on. The formations-side CloudFormation parameter and condition are unchanged -- every db-utils resource is still gated on DatabaseEnabled, and there is no task definition to run for an external DB without it.
|
Pushed an update that addresses your review: A managed AppPack database ( On the "no CloudFormation changes" half of your comment: that part isn't achievable. Every db-utils resource (task definitions, execution/task roles, log group, S3 bucket) is gated behind One tradeoff worth flagging: since there's no flag anymore, there's also no escape hatch for a DATABASE_URL with a scheme we don't recognize -- we print one warning and leave |
|
Could we special-case `apppack config set DATABASE_URL=...` (and `apppack
config import`) to provide additional instructions on how they can modify
the app to allow db shell/dump/load commands to work?
…On Wed, Aug 19, 2026 at 2:34 PM Brendan Smith ***@***.***> wrote:
*blsmth* left a comment (apppackio/apppack#173)
<#173 (comment)>
Pushed an update that addresses your review: --external-database and both
interactive prompts (enable? / which engine?) are gone. SetInternalFields
now infers ExternalDatabaseEngine from the app's DATABASE_URL config
variable (read from SSM), comparing only the URL scheme -- postgres/
postgresql/pgsql/psql -> postgres, mysql/mysql2/mariadb -> mysql. This
runs for both create app and modify app, so the resulting workflow is:
apppack create app ...
apppack config set DATABASE_URL=...
apppack modify app <name> # picks up the engine automatically
A managed AppPack database (--addon-database/--addon-database-name)
always wins and forces the field back to "", and pipelines/review apps
are excluded, since the CloudFormation condition requires IsApp -- so
detection is idempotent no matter how many times modify app runs.
On the "no CloudFormation changes" half of your comment: that part isn't
achievable. Every db-utils resource (task definitions, execution/task
roles, log group, S3 bucket) is gated behind DatabaseEnabled, and
app.StartTask only ever does DescribeTaskDefinition -> RunTask -- there's
no task-definition family to run against for an external DB without the
formations change. That half of the PR is unchanged.
One tradeoff worth flagging: since there's no flag anymore, there's also
no escape hatch for a DATABASE_URL with a scheme we don't recognize -- we
print one warning and leave db shell/db dump disabled rather than failing
the deploy. Happy to add --external-database back as a hidden override
for that case if you'd rather have one. Let me know.
—
Reply to this email directly, view it on GitHub
<#173?email_source=notifications&email_token=AACN5NDVIBT5OXKBBPU7JS35KYFOFA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKMZUG43DOOBZGM22M4TFMFZW63VHMNXW23LFNZ2KKZLWMVXHJLDGN5XXIZLSL5RWY2LDNM#issuecomment-5347678935>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AACN5NHBUQZUKGJ5S6JCD335KYFOFAVCNFSNUABFKJSXA33TNF2G64TZHMZTCOJXGM2TENBVHNEXG43VMU5TKMJSGQZTQNZWHE4KC5QC>
.
Triage notifications, keep track of coding agent tasks and review pull
requests on the go with GitHub Mobile for iOS
<https://github.com/notifications/mobile/ios/AACN5NEFQRYALLIQ5OCVZ2T5KYFOFA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKMZUG43DOOBZGM22M4TFMFZW63VHMNXW23LFNZ2KKZLWMVXHJKTGN5XXIZLSL5UW64Y>
and Android
<https://github.com/notifications/mobile/android/AACN5NDBWJ7Z7VVR766M2ML5KYFOFA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKMZUG43DOOBZGM22M4TFMFZW63VHMNXW23LFNZ2KKZLWMVXHJLTGN5XXIZLSL5QW4ZDSN5UWI>.
Download it today!
You are receiving this because you commented.Message ID:
***@***.***>
|
Registers ExternalDatabaseEngine as a CloudFormation parameter on apppack create app (postgres|mysql), validates it is mutually exclusive with --addon-database/--addon-database-name, and adds a matching interactive prompt in AskForDatabase for apppack modify app. Also replaces the unhelpful "unknown database engine " error (empty engine) with a targeted message that checks for a DATABASE_URL config variable and tells the user how to enable db utils or create a database.
ipmb reviewed #173 and pointed out the user should never have to type the database engine -- it's inferable from the DATABASE_URL scheme. Delete --external-database and both interactive prompts; SetInternalFields now auto-detects the engine from the app's DATABASE_URL config variable via SSM, for both `create app` and `modify app`. A managed AppPack database and pipelines/review apps always force the field back to "", so this is idempotent no matter how many times `modify app` runs. Any SSM/parse failure is silent (the common case, since `create app` runs before the app exists); an unrecognized scheme still gets one warning line, since there's no longer a flag to fall back on. The formations-side CloudFormation parameter and condition are unchanged -- every db-utils resource is still gated on DatabaseEnabled, and there is no task definition to run for an external DB without it.
79c368f to
b31a056
Compare
The engine is now inferred from DATABASE_URL, so the "no database configured" error was pointing users at a flag that no longer exists -- following its advice would fail with "unknown flag". Drop the parenthetical and let `apppack modify app` be the single answer. Turn the test that asserted on the flag name into a negative assertion, so a stale reference can't creep back into user-facing text.
The previous commit was made against an index that already held staged deletions from a concurrent rebase in this worktree, so it removed the go vet/fmt CI gate, the flag-shorthand collision tests, and unrelated CHANGELOG and config entries. Restore all five from main; none of them have anything to do with this branch.
Setting DATABASE_URL is the obvious move when pointing an app at an externally-managed database, but on its own it does nothing for `apppack db shell`/`db dump`/`db load` -- those need the db-utils resources, which only appear when the stack is updated. Nothing told the user that second step existed, so the discoverable path dead-ended at a config variable that looked sufficient. Print a follow-up hint from `config set` and `config import` when DATABASE_URL lands on an app whose db utils aren't enabled yet. Stays quiet when an engine is already set (managed database, or a previous `modify app`), and for pipelines/review apps, where external databases are gated off in CloudFormation anyway. Advisory only: the variable is already stored by the time we're called, so a settings-load failure just skips the hint rather than failing a command that succeeded. Suggested by ipmb in review of #173.
Closes #146.
Adds
--external-database <postgres|mysql>toapppack create app, which sets a newExternalDatabaseEngineCloudFormation parameter sodb shell/db dump/db loadcan target an externally-managed database (Neon, Crunchy, etc.) reachable via the app'sDATABASE_URLconfig variable. Also adds a matching interactive prompt inAskForDatabase(forapppack modify app), client-side validation (mutually exclusive with--addon-database/--addon-database-name, engine must bepostgresormysql), and replaces the unhelpful "unknown database engine " error with a targeted message pointing users at eitherapppack modify app/--external-databaseorapppack create database.Depends on the formations change (apppack-backend) landing and being released first — until formations emits
dbutils.enginefor externally-configured apps, setting this flag has no effect.Caveat carried over from the spec:
apppack db load'sload-from-s3.shscript likely does a DROP/CREATE of the target database, which some managed providers (e.g. Neon) may not permit for the app's role.db shellanddb dumpare the confident wins here;db loadmay not reach full parity even after this lands.Happy path (
DBShellTaskInfo/DBDumpLocation/DBDumpLoadFamily,isPostgresincmd/db.go) is unchanged.Want a Test Plan section added, or is this concise enough as-is?