Repository navigation
Commit 71e6966
feat(aws-startup-advisor): Heroku-to-AWS day-to-day command cheat sheet in the heroku-to-aws migration guide (#615)
* feat(aws-startup-advisor): add a Heroku-to-AWS day-to-day command cheat sheet to the heroku-to-aws migration guide
The guide covered provisioning, data, cutover and rollback and then stopped;
nothing told developers what `heroku logs --tail`, `run bash`, `config:set`,
`ps:scale`, `releases`, `rollback`, `maintenance:on` or `pg:psql` become.
- MIGRATION_GUIDE.md: new "Day-to-day commands: Heroku -> AWS" section (TOC
entry; one table per compute target present, rows filled with the app's
generated names so they paste). Closing paragraph names the two commands
with no one-liner (push-to-deploy -> Phase 3 workflow; pipelines:promote ->
not generated) and suggests bin/ wrappers as a first platform-team task.
- ecs.tf: enable_execute_command = true on each service plus the ssmmessages
actions on the task role, so the `heroku run bash` row (ECS Exec) is true.
- Template Variable Resolution: EB_WEB_ENVIRONMENT and ECS_CLUSTER.
* fix(aws-startup-advisor): render the Heroku command cheat sheet from the design and gate ECS Exec honestly
Review findings on PR #615.
- validate-terraform-policy.py: no_wildcard_iam now exempts a second
statement shape, an Allow whose Action list holds only the four
ssmmessages channel actions (ECS Exec), because AWS defines no
resource-level permissions for them. The exemption is statement-shaped:
any other action in the same list (ssmmessages:*, ssm:*, s3:*) or a
second wildcard statement in the same policy is still rejected. Rule
docs (security-posture-rules.md, SKILL.md) updated; tests cover the
emitted generate-terraform.md statement passing and the mixed cases
failing.
- generate-docs.md: the "Day-to-day commands" section now sits before
the deferred_addons guard so it renders with an empty deferred list.
Rows render per process type from eb_processes[] / fargate_processes[]
(no hardcoded -web service, task family or container); maintenance and
open rows are gated on app_has_eb_web / app_has_fargate_web; app-wide
actions loop over every environment/service. Config rows follow the
actual backing store (plain property, Secrets Manager ARN, SSM
parameter) with explicit identifiers taken from beanstalk.tf/ecs.tf
instead of an invented /<app>/KEY path or <app>/DATABASE_URL secret.
EB log tail uses the full .../eb-current-app/stdouterr.log group;
shells use /bin/sh (Alpine images); pg rows are gated on has_postgres
and branch RDS create-db-snapshot vs Aurora create-db-cluster-snapshot;
open uses https://\<custom domain> when configured, else
http://\<EB CNAME> (the default environment has no HTTPS listener).
- generate-terraform.md: beanstalk.tf enables
aws:elasticbeanstalk:cloudwatch:logs StreamLogs=true with
RetentionInDays so the tailed group exists.
- tests/test_heroku_command_cheatsheet.py pins all of the above.
Verification: `mise run ci` passed (lint:md, lint:artifacts,
lint:vendored-parity, lint:skill-refs, pytest 1483 passed, telemetry 311
passed); skills/tf-best-practices/scripts/test_validate_terraform_policy.py
63 passed; the extracted ecs_task_exec block returns POLICY_OK.
* fix(aws-startup-advisor): make the Heroku command cheat sheet true for the generated stack
Review findings on PR #615.
- beanstalk.tf attaches AmazonSSMManagedInstanceCore to the EB instance
role; the `run bash` / one-off rows use `aws ssm start-session` against
the environment's instance plus `docker exec`, and `eb ssh` is dropped
(no EC2KeyName, no :22 ingress; AWSElasticBeanstalkWebTier has no ssm).
- config:set is split into "existing key" and "new key" on both targets.
A new key is a silent no-op until Terraform binds it: EB injects only
environmentsecrets names and its role reads only parameter/<project>/*
and secret:<project>/*; the Fargate task definition emits no secrets
block and the execution role has no SSM / Secrets Manager read. The
rows name the {{PROJECT_NAME}} prefix and the Terraform change.
- EB rows use {{EB_APPLICATION}} (var.project_name) instead of the
Heroku app name; `ps` stays on describe-environments (basic health).
- ps:scale / restart rows note that the next apply reverts a CLI scale,
point at terraform.tfvars for a persistent change, and forbid scaling
or restarting while writers_quiesced = true.
- pg:psql reads {{DB_CREDENTIALS_SECRET}} ({username,password} JSON) with
jq into PGPASSWORD and connects with sslmode=verify-full; falls back to
db_username / db_password in terraform.tfvars when RDS Proxy is absent.
- Fargate rollback is by image digest via container_image_* in
terraform.tfvars (Phase 3 pushes :latest with --force-new-deployment,
so there is no previous tag); the releases row lists imageDigest.
- compute.tf comment points at aws_iam_role_policy.ecs_task_exec in
security.tf (Step 5) instead of "below".
- The closing paragraph no longer depends on the "Developer workflow"
report section from another PR.
- New good-heroku-fargate-ecs-exec policy fixture (count 31 -> 32); the
cheat-sheet test file pins every row above.
Verification: `mise run ci` passed (lint:md 0 errors, lint:artifacts,
lint:vendored-parity, lint:skill-refs, pytest 1490 passed + 225 subtests,
telemetry 311 passed); test_validate_terraform_policy.py and
test_heroku_command_cheatsheet.py 78 passed together.
* fix(aws-startup-advisor): close the second review round on the Heroku command cheat sheet
Review findings on PR #615.
- validate-terraform-policy.py: the ssmmessages exemption now requires every
Action list member to be a quoted literal from the allowlist; an expression
member (local.x, var.y, function call) keeps the statement under
no_wildcard_iam. Rule docs updated (SKILL.md, security-posture-rules.md).
- generate-docs.md cheat sheet: Fargate rows point at terraform/compute.tf
(never ecs.tf / alb.tf); pg:psql reads the db-credentials secret on the
operator workstation (neither session role can read it) with POSIX-portable
`jq --argjson` instead of a bash here-string, and the no-RDS-Proxy fallback
stays explicit; `open` resolves the rendered app's own hostname through
dns_hostnames[].heroku_app ({{APP_HTTPS_HOSTNAME}}) instead of the global
first custom domain; EB maintenance:on branches on the actual load balancer
(Classic default outside has_route53_dns -> maintenance application version;
ALB -> name -> ARN -> listeners).
- beanstalk.tf RetentionInDays is mapped to the smallest EB-accepted value
>= operational.log_retention_days (documented in the template, Q13 and the
assemble checklist so reused preferences are validated the same way).
Tests: test_ssmmessages_exception_requires_every_member_to_be_a_literal;
test_terraform_file_references_match_the_emitted_inventory;
test_pg_psql_credential_path_is_the_operator_not_the_session_role (dash -n);
test_eb_maintenance_row_branches_on_the_actual_load_balancer_type;
test_open_hostname_is_the_rendered_apps_own_dns_hostname;
test_eb_retention_is_mapped_to_the_accepted_domain.
Verified: `mise run ci` passed (lint:md 0 errors, lint:artifacts,
lint:vendored-parity, lint:skill-refs, pytest 1495 passed + 225 subtests,
telemetry 311 passed).
* fix(aws-startup-advisor): Review findings on PR #615
Replace AmazonSSMManagedInstanceCore with a Session Manager inline policy so parameter reads stay under the project prefix; switch every forwarding EB ALB listener for maintenance mode; fetch the RDS CA bundle on the psql host in both pg:psql rows.
Verified: mise run ci passed (1497 tests).
---------
Co-authored-by: Logan Kleier <lkleier@amazon.com>1 parent ac89c65 commit 71e6966
10 files changed
Lines changed: 980 additions & 13 deletions
File tree
- plugins/aws-startup-advisor
- skills
- heroku-to-aws/references/phases
- clarify
- generate
- tf-best-practices
- fixtures/terraform-policy/good-heroku-fargate-ecs-exec
- references
- scripts
- tests
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
137 | 137 | | |
138 | 138 | | |
139 | 139 | | |
| 140 | + | |
140 | 141 | | |
141 | 142 | | |
142 | 143 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
801 | 801 | | |
802 | 802 | | |
803 | 803 | | |
| 804 | + | |
| 805 | + | |
| 806 | + | |
| 807 | + | |
| 808 | + | |
| 809 | + | |
804 | 810 | | |
805 | 811 | | |
806 | 812 | | |
| |||
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1056 | 1056 | | |
1057 | 1057 | | |
1058 | 1058 | | |
| 1059 | + | |
| 1060 | + | |
| 1061 | + | |
| 1062 | + | |
| 1063 | + | |
| 1064 | + | |
| 1065 | + | |
| 1066 | + | |
| 1067 | + | |
| 1068 | + | |
| 1069 | + | |
| 1070 | + | |
| 1071 | + | |
| 1072 | + | |
| 1073 | + | |
| 1074 | + | |
| 1075 | + | |
| 1076 | + | |
| 1077 | + | |
1059 | 1078 | | |
1060 | 1079 | | |
1061 | 1080 | | |
| |||
1157 | 1176 | | |
1158 | 1177 | | |
1159 | 1178 | | |
| 1179 | + | |
| 1180 | + | |
| 1181 | + | |
| 1182 | + | |
1160 | 1183 | | |
1161 | 1184 | | |
1162 | 1185 | | |
| |||
1422 | 1445 | | |
1423 | 1446 | | |
1424 | 1447 | | |
| 1448 | + | |
| 1449 | + | |
| 1450 | + | |
| 1451 | + | |
| 1452 | + | |
| 1453 | + | |
| 1454 | + | |
| 1455 | + | |
| 1456 | + | |
| 1457 | + | |
| 1458 | + | |
| 1459 | + | |
| 1460 | + | |
| 1461 | + | |
| 1462 | + | |
| 1463 | + | |
| 1464 | + | |
| 1465 | + | |
| 1466 | + | |
| 1467 | + | |
| 1468 | + | |
1425 | 1469 | | |
1426 | 1470 | | |
1427 | 1471 | | |
| |||
1467 | 1511 | | |
1468 | 1512 | | |
1469 | 1513 | | |
| 1514 | + | |
| 1515 | + | |
| 1516 | + | |
| 1517 | + | |
| 1518 | + | |
| 1519 | + | |
| 1520 | + | |
| 1521 | + | |
| 1522 | + | |
| 1523 | + | |
| 1524 | + | |
| 1525 | + | |
| 1526 | + | |
| 1527 | + | |
| 1528 | + | |
| 1529 | + | |
| 1530 | + | |
| 1531 | + | |
| 1532 | + | |
| 1533 | + | |
| 1534 | + | |
| 1535 | + | |
| 1536 | + | |
| 1537 | + | |
| 1538 | + | |
| 1539 | + | |
| 1540 | + | |
| 1541 | + | |
1470 | 1542 | | |
1471 | 1543 | | |
1472 | 1544 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
223 | 223 | | |
224 | 224 | | |
225 | 225 | | |
226 | | - | |
227 | | - | |
228 | | - | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
229 | 232 | | |
230 | 233 | | |
231 | 234 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
188 | 188 | | |
189 | 189 | | |
190 | 190 | | |
191 | | - | |
192 | | - | |
193 | | - | |
194 | | - | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
195 | 203 | | |
196 | 204 | | |
197 | 205 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
138 | 138 | | |
139 | 139 | | |
140 | 140 | | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
141 | 264 | | |
142 | 265 | | |
143 | 266 | | |
| |||
833 | 956 | | |
834 | 957 | | |
835 | 958 | | |
836 | | - | |
| 959 | + | |
837 | 960 | | |
838 | 961 | | |
839 | 962 | | |
| |||
0 commit comments