Point production at its SQLite database and check the API in health checks - #188
Merged
Conversation
Contributor
|
Terraform plan in terraform Plan: 1 to add, 2 to change, 3 to destroy.Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
!~ update in-place
- destroy
-/+ destroy and then create replacement
Terraform will perform the following actions:
# module.home-unite-us.module.db_url_prod.aws_ssm_parameter.this will be destroyed
# (because aws_ssm_parameter.this is not in configuration)
- resource "aws_ssm_parameter" "this" {
- arn = "arn:aws:ssm:us-west-2:035866691871:parameter/home-unite-us/fullstack-prod-database_url" -> null
- data_type = "text" -> null
- has_value_wo = false -> null
- id = "/home-unite-us/fullstack-prod-database_url" -> null
- key_id = "alias/aws/ssm" -> null
- name = "/home-unite-us/fullstack-prod-database_url" -> null
- region = "us-west-2" -> null
- tags = {
- "project" = "home-unite-us"
} -> null
- tags_all = {
- "managed-by" = "terraform-incubator"
- "project" = "home-unite-us"
} -> null
- tier = "Standard" -> null
- type = "SecureString" -> null
- value = (sensitive value) -> null
- value_wo = (write-only attribute) -> null
- version = 1 -> null
# (2 unchanged attributes hidden)
}
# module.home-unite-us.module.db_url_prod.random_password.password will be destroyed
# (because random_password.password is not in configuration)
- resource "random_password" "password" {
- bcrypt_hash = (sensitive value) -> null
- id = "none" -> null
- length = 48 -> null
- lower = true -> null
- min_lower = 0 -> null
- min_numeric = 0 -> null
- min_special = 0 -> null
- min_upper = 0 -> null
- number = true -> null
- numeric = true -> null
- override_special = "!#$-" -> null
- result = (sensitive value) -> null
- special = true -> null
- upper = true -> null
}
# module.home-unite-us.module.prod_service.aws_ecs_service.fargate[0] will be updated in-place
!~ resource "aws_ecs_service" "fargate" {
id = "arn:aws:ecs:us-west-2:035866691871:service/incubator-prod/home-unite-us-fullstack-prod"
name = "home-unite-us-fullstack-prod"
tags = {}
!~ task_definition = "arn:aws:ecs:us-west-2:035866691871:task-definition/home-unite-us-fullstack-prod:1" -> (known after apply)
# (18 unchanged attributes hidden)
# (7 unchanged blocks hidden)
}
# module.home-unite-us.module.prod_service.aws_ecs_task_definition.task must be replaced
-/+ resource "aws_ecs_task_definition" "task" {
!~ arn = "arn:aws:ecs:us-west-2:035866691871:task-definition/home-unite-us-fullstack-prod:1" -> (known after apply)
!~ arn_without_revision = "arn:aws:ecs:us-west-2:035866691871:task-definition/home-unite-us-fullstack-prod" -> (known after apply)
!~ container_definitions = (sensitive value) # forces replacement
!~ enable_fault_injection = false -> (known after apply)
!~ id = "****************************" -> (known after apply)
!~ revision = 1 -> (known after apply)
- tags = {} -> null
# (13 unchanged attributes hidden)
}
# module.home-unite-us.module.prod_service.aws_lb_target_group.this will be updated in-place
!~ resource "aws_lb_target_group" "this" {
id = "arn:aws:elasticloadbalancing:us-west-2:035866691871:targetgroup/home-unite-us-fullstack-prod-tg/f8cec6f42f04281f"
name = "home-unite-us-fullstack-prod-tg"
tags = {}
# (20 unchanged attributes hidden)
!~ health_check {
!~ path = "/" -> "/api/health/"
# (8 unchanged attributes hidden)
}
!~ target_health_state {
+ enable_unhealthy_connection_termination = false
+ unhealthy_draining_interval = 0
}
# (3 unchanged blocks hidden)
}
Plan: 1 to add, 2 to change, 3 to destroy.✅ Plan applied in Terraform apply (OIDC) #70 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Third of four PRs for #166, after #186 (Cognito import) and #187 (production service). It corrects how the new service is configured. It still takes no traffic — the cutover is the next PR.
Production does not use RDS, and never has
#187 set
DATABASE_URLfrom thehomeuniteus-rds-passwordsecret, following the abandoned Terragrunt state, which describes a Postgres database on the shared instance. The service came up and its API died immediately:The credential is not stale — the premise was wrong. The live production container's
.envpointsDATABASE_URLat/opt/huu/homeuniteus.db, a SQLite file on the container's own filesystem. Nothing has connected to that Postgres database since January 2025, which is why the password no longer matches anything.This PR sets
DATABASE_URLto the same SQLite path so the new service matches production, and removes the Postgres wiring: thehomeuniteus-rds-passworddata source, theaws_db_instancelookup, and thedb_url_prodSSM parameter, which was created holding a value that never worked.What that means, recorded here deliberately
The production task definition declares no volume and no mount point. So that SQLite file is created empty when a task starts and is destroyed when the task is replaced — by a deploy, a host drain, or an AZ rebalance. The log group holds 743 task generations. Application data has never survived any of them.
It goes unnoticed because Cognito holds the user accounts and Cognito is durable — 96 of them. The site loads, sign-in works, and only the application's own tables reset. It fails in the one way that looks fine from outside.
The current file was inspected before writing this: 53,248 bytes, containing nothing beyond what the application recreates for itself on startup via
create_alland theafter_createrole seed. So there is nothing to migrate, and nothing was lost in arriving at this PR.This PR reproduces that behaviour rather than fixing it, so that the cutover changes nothing about how the application runs. Making production durable is a real change to a live service and belongs in its own piece of work, not inside a migration. The comment in
environment-prod.tfsays so at the point where the next reader will meet it.Health checks now test the API
The target group checked
/, which nginx serves whether or not the API is alive — the container runs nginx in the foreground and the API as a background process, so the API dying does not even stop the task. When #187's service came up with a dead API, the target group reported healthy the entire time.It now checks
/api/health/, which is served by the API process and returns"UP". Had this been in place, #187 would have failed visibly instead of looking green.LOG_LEVELrestored toDEBUG#187 set
INFO; production runsDEBUG. Reverted to match, keeping this migration behaviour-preserving. WhetherDEBUGis appropriate for production is a separate question and not settled here.What to check in the plan
A new task definition revision and a service update to use it, an in-place update to the target group's health check, and the destruction of the unused
db_url_prodSSM parameter and itsrandom_password. Nothing else should change, and no other resource should be replaced.Verification
terraform validateandterraform fmtpass on 1.16.0.