Skip to content

chore(infra): point Terraform state at the client account bucket - #389

Merged
nourshoreibah merged 7 commits into
mainfrom
infra/point-state-at-client-bucket
Aug 30, 2026
Merged

nourshoreibah merged 7 commits into
mainfrom
infra/point-state-at-client-bucket

Conversation

@nourshoreibah

Copy link
Copy Markdown
Collaborator

Step 3 of the AWS account handoff. The state bucket branch-tf-state now exists in the client's account; this points every Terraform root and every state-related IAM policy at it.

c4c-neu-terraform-state-files lives in C4C's account, so the CI roles that infrastructure/aws creates in the client's account cannot reach it. The backend must move with the account.

What changed

14 references, in 8 files:

  • 5 × backend.tf — aws, github, preview, preview-shared, test. Backend blocks can't interpolate variables, so these are literal edits by necessity.
  • 7 × infrastructure/aws/oidc.tf — four .tflock object ARNs in the plan role's tfstate-lock policy, plus the bucket ARN and two prefixes in the preview role. All inside jsonencode blocks, which is why they don't read as backend config.
  • 2 × AGENTS.md — root and infrastructure/.

No DynamoDB table is involved: since #386 the backends use use_lockfile = true, so the lock is a <key>.tflock object beside the state.

State starts fresh. Nothing is migrated — the old state describes resources in C4C's account that are slated for teardown, and it is kept only so that teardown can run from a pre-merge checkout.

Sequencing — read before merging

Opened as a draft on purpose. The plan role holds ReadOnlyAccess plus a narrow policy naming those exact .tflock objects, so this PR cannot pass its own terraform-plan until the roles exist in the new account. That is expected, not a regression. Required order:

  1. Apply infrastructure/aws locally with the C4CAdmin key, from this branch — that creates the roles already pointing at branch-tf-state.
  2. Publish the Cognito outputs to Infisical, set var.aws_account_id to the new account, and apply infrastructure/github so vars.AWS_ACCOUNT_ID repoints the workflows.
  3. Then mark this ready for review. CI now plans against the new account, where the roles and permissions already exist, and it passes.

Merging out of order means merging a PR whose own plan failed, which terraform-plan-summary correctly blocks.

Verification

  • grep -rn c4c-neu-terraform-state-files . returns nothing.
  • terraform fmt -check -recursive infrastructure/ passes.
  • Not verified locally: terraform init against the new bucket, since these credentials are for a different account.

🤖 Generated with Claude Code

nourshoreibah and others added 7 commits August 30, 2026 13:55
State must live in the client's AWS account: the CI roles created there
cannot reach c4c-neu-terraform-state-files in C4C's account.

Renames the bucket in all 14 references — the five backend.tf files, the
seven .tflock/bucket ARNs inside the oidc.tf jsonencode policies, and
both AGENTS.md files. State starts fresh; nothing is migrated.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The client account is on the AWS free tier plan, which rejects a 7-day
retention outright:

  FreeTierRestrictionError: The specified backup retention period exceeds
  the maximum available to free tier customers.

1 keeps point-in-time recovery as the backstop for CI-applied migrations
rather than disabling it. Raise it back to 7 once the account plan is
upgraded. backup_window stays unset — AWS cross-validates it against the
unmanaged maintenance window, so it is pinned both or neither.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sets var.aws_account_id to the new account, which publishes
vars.AWS_ACCOUNT_ID and repoints all six workflows' OIDC role ARNs in one
apply. README is terraform-docs generated and tracks the default.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The import added in #384 adopts /aws/lambda/branch-* log groups on the
assumption Lambda already created them. That holds in C4C's account, not in
the client's, where the functions have never run:

  Error: Cannot import non-existent remote object

It fails plan as well as apply, so terraform-plan cannot go green while it
is present. Without it Terraform just creates the groups at 30d retention,
which is the same end state.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Terraform Plan 📖 infrastructure/github

Terraform Initialization ⚙️success

Terraform Validation 🤖success

Terraform Plan 📖success

Show Plan
data.infisical_secrets.infisical_folder: Reading...
data.infisical_secrets.slack_folder: Reading...
data.infisical_secrets.cognito_folder: Reading...
data.infisical_secrets.github_folder: Reading...
data.infisical_secrets.infisical_folder: Read complete after 0s
data.infisical_secrets.cognito_folder: Read complete after 0s
data.infisical_secrets.slack_folder: Read complete after 0s
data.infisical_secrets.github_folder: Read complete after 0s
github_repository.branch: Refreshing state... [id=branch]
github_actions_secret.infisical_client_id: Refreshing state... [id=branch:INFISICAL_CLIENT_ID]
github_branch_protection.main: Refreshing state... [id=BPR_kwDOPjZxzc4D-9hQ]
github_actions_secret.slack_bot_token: Refreshing state... [id=branch:SLACK_BOT_TOKEN]
github_branch_protection.bot_state: Refreshing state... [id=BPR_kwDOPjZxzc4EU_R9]
github_repository_environment.preview: Refreshing state... [id=branch:preview]
github_actions_secret.infisical_client_secret: Refreshing state... [id=branch:INFISICAL_CLIENT_SECRET]
github_branch_default.main: Refreshing state... [id=branch]
github_repository_environment.production_db: Refreshing state... [id=branch:production-db]
github_actions_secret.gh_pat: Refreshing state... [id=branch:GH_PAT]
github_actions_secret.cognito_user_pool_id: Refreshing state... [id=branch:COGNITO_USER_POOL_ID]
github_actions_variable.aws_account_id: Refreshing state... [id=branch:AWS_ACCOUNT_ID]
github_actions_secret.cognito_client_id: Refreshing state... [id=branch:COGNITO_CLIENT_ID]
github_branch.bot_state: Refreshing state... [id=branch:bot-state]
github_repository_file.bot_state_json: Refreshing state... [id=branch:state.json:bot-state]
github_repository_file.bot_config_json: Refreshing state... [id=branch:config.json:bot-state]

Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # github_repository.branch will be updated in-place
  ~ resource "github_repository" "branch" {
      ~ has_downloads                           = false -> true
        id                                      = "branch"
        name                                    = "branch"
        # (40 unchanged attributes hidden)

        # (1 unchanged block hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

Warning: Argument is deprecated

  with github_repository.branch,
  on main.tf line 6, in resource "github_repository" "branch":
   6:   has_downloads   = true

This attribute is no longer in use, but it hasn't been removed yet. It will
be removed in a future version. See
https://github.com/orgs/community/discussions/102145#discussioncomment-8351756

(and 7 more similar warnings elsewhere)

─────────────────────────────────────────────────────────────────────────────

Saved the plan to: tfplan

To perform exactly these actions, run the following command to apply:
    terraform apply "tfplan"

Pushed by: @nourshoreibah, Action: pull_request

@github-actions

Copy link
Copy Markdown
Contributor

Terraform Plan 📖 infrastructure/test

Terraform Initialization ⚙️success

Terraform Validation 🤖success

Terraform Plan 📖success

Show Plan
No changes. Your infrastructure matches the configuration.

Terraform has compared your real infrastructure against your configuration
and found no differences, so no changes are needed.

Pushed by: @nourshoreibah, Action: pull_request

@github-actions

Copy link
Copy Markdown
Contributor

Terraform Plan 📖 infrastructure/preview-shared

Terraform Initialization ⚙️success

Terraform Validation 🤖success

Terraform Plan 📖success

Show Plan
aws_cloudfront_origin_access_control.previews: Refreshing state... [id=E1HVOXE6PI15TT]
aws_cloudfront_function.preview_rewrite: Refreshing state... [id=branch-previews-rewrite]
data.aws_caller_identity.current: Reading...
data.aws_caller_identity.current: Read complete after 0s [id=404813129370]
aws_s3_bucket.previews: Refreshing state... [id=branch-previews-404813129370]
aws_s3_bucket_public_access_block.previews: Refreshing state... [id=branch-previews-404813129370]
aws_cloudfront_distribution.previews: Refreshing state... [id=E3HV0Z6BS1G5RZ]
data.aws_iam_policy_document.previews_bucket: Reading...
data.aws_iam_policy_document.previews_bucket: Read complete after 0s [id=4163081279]
aws_s3_bucket_policy.previews: Refreshing state... [id=branch-previews-404813129370]

No changes. Your infrastructure matches the configuration.

Terraform has compared your real infrastructure against your configuration
and found no differences, so no changes are needed.

Pushed by: @nourshoreibah, Action: pull_request

@github-actions

Copy link
Copy Markdown
Contributor

Terraform Plan 📖 infrastructure/aws

Terraform Initialization ⚙️success

Terraform Validation 🤖success

Terraform Plan 📖success

Show Plan
data.archive_file.lambda_placeholder: Reading...
data.archive_file.lambda_placeholder: Read complete after 0s [id=96878a51e358033297a32b882fd5223cc95fb8a7]
data.aws_region.current: Reading...
aws_cloudfront_origin_access_control.frontend: Refreshing state... [id=E1ZI46GY0YEFAD]
aws_cloudfront_function.rewrite_index: Refreshing state... [id=branch-frontend-rewrite-index]
aws_iam_role.lambda_role: Refreshing state... [id=branch-lambda-role]
data.aws_region.current: Read complete after 0s [id=us-east-2]
data.aws_caller_identity.current: Reading...
data.aws_vpc.default: Reading...
aws_api_gateway_rest_api.branch_api: Refreshing state... [id=btt3bl5139]
aws_iam_openid_connect_provider.github: Refreshing state... [id=arn:aws:iam::404813129370:oidc-provider/token.actions.githubusercontent.com]
data.infisical_secrets.grafana_folder: Reading...
aws_s3_bucket.reports_bucket: Refreshing state... [id=c4c-branch-generated-reports20260830181426405600000001]
data.infisical_secrets.rds_folder: Reading...
data.aws_caller_identity.current: Read complete after 0s [id=404813129370]
data.infisical_secrets.sentry_folder: Reading...
data.infisical_secrets.sentry_folder: Read complete after 0s
data.infisical_secrets.grafana_folder: Read complete after 0s
aws_s3_bucket.lambda_deployments: Refreshing state... [id=branch-lambda-deployments-404813129370]
aws_s3_bucket.frontend: Refreshing state... [id=branch-frontend-404813129370]
data.infisical_secrets.rds_folder: Read complete after 0s
data.aws_iam_policy_document.ci_apply_assume: Reading...
data.aws_iam_policy_document.ci_plan_assume: Reading...
data.aws_iam_policy_document.ci_apply_assume: Read complete after 0s [id=3235391464]
data.aws_iam_policy_document.ci_plan_assume: Read complete after 0s [id=1050147292]
data.aws_iam_policy_document.ci_migrate_assume: Reading...
data.aws_iam_policy_document.ci_preview_assume: Reading...
data.aws_iam_policy_document.ci_preview_assume: Read complete after 0s [id=245163413]
aws_iam_role.ci_apply: Refreshing state... [id=branch-ci-apply]
data.aws_iam_policy_document.ci_migrate_assume: Read complete after 0s [id=3606114350]
aws_iam_role.ci_plan: Refreshing state... [id=branch-ci-plan]
aws_iam_role.ci_preview: Refreshing state... [id=branch-ci-preview]
aws_iam_role.ci_migrate: Refreshing state... [id=branch-ci-migrate]
aws_api_gateway_gateway_response.cors["DEFAULT_5XX"]: Refreshing state... [id=aggr-btt3bl5139-DEFAULT_5XX]
aws_api_gateway_gateway_response.cors["DEFAULT_4XX"]: Refreshing state... [id=aggr-btt3bl5139-DEFAULT_4XX]
aws_api_gateway_resource.lambda_resources["auth"]: Refreshing state... [id=j2bjjp]
aws_api_gateway_resource.lambda_resources["reports"]: Refreshing state... [id=fbius2]
aws_api_gateway_resource.lambda_resources["users"]: Refreshing state... [id=r6frgh]
aws_api_gateway_resource.lambda_resources["expenditures"]: Refreshing state... [id=x3f6cx]
aws_api_gateway_resource.lambda_resources["donors"]: Refreshing state... [id=ooaugc]
aws_api_gateway_resource.lambda_resources["projects"]: Refreshing state... [id=5rlpdk]
aws_iam_role_policy_attachment.ci_apply_admin: Refreshing state... [id=branch-ci-apply/arn:aws:iam::aws:policy/AdministratorAccess]
aws_iam_role_policy.lambda_ses_send: Refreshing state... [id=branch-lambda-role:branch-lambda-ses-send]
aws_iam_role_policy_attachment.lambda_basic: Refreshing state... [id=branch-lambda-role/arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole]
aws_iam_role_policy.ci_preview: Refreshing state... [id=branch-ci-preview:preview-env]
aws_iam_role_policy.ci_plan_state_lock: Refreshing state... [id=branch-ci-plan:tfstate-lock]
aws_iam_role_policy_attachment.ci_plan_readonly: Refreshing state... [id=branch-ci-plan/arn:aws:iam::aws:policy/ReadOnlyAccess]
aws_api_gateway_method.lambda_methods["reports-OPTIONS"]: Refreshing state... [id=agm-btt3bl5139-fbius2-OPTIONS]
aws_api_gateway_method.lambda_methods["projects-GET"]: Refreshing state... [id=agm-btt3bl5139-5rlpdk-GET]
aws_api_gateway_method.lambda_methods["users-GET"]: Refreshing state... [id=agm-btt3bl5139-r6frgh-GET]
aws_api_gateway_method.lambda_methods["users-PATCH"]: Refreshing state... [id=agm-btt3bl5139-r6frgh-PATCH]
aws_api_gateway_method.lambda_methods["reports-GET"]: Refreshing state... [id=agm-btt3bl5139-fbius2-GET]
aws_api_gateway_method.lambda_methods["users-DELETE"]: Refreshing state... [id=agm-btt3bl5139-r6frgh-DELETE]
aws_api_gateway_method.lambda_methods["auth-POST"]: Refreshing state... [id=agm-btt3bl5139-j2bjjp-POST]
aws_api_gateway_method.lambda_methods["donors-OPTIONS"]: Refreshing state... [id=agm-btt3bl5139-ooaugc-OPTIONS]
aws_api_gateway_method.lambda_methods["users-OPTIONS"]: Refreshing state... [id=agm-btt3bl5139-r6frgh-OPTIONS]
aws_api_gateway_method.lambda_methods["donors-GET"]: Refreshing state... [id=agm-btt3bl5139-ooaugc-GET]
aws_api_gateway_method.lambda_methods["expenditures-POST"]: Refreshing state... [id=agm-btt3bl5139-x3f6cx-POST]
data.aws_vpc.default: Read complete after 1s [id=vpc-0d3819d8bbb63db8c]
aws_api_gateway_method.lambda_methods["auth-OPTIONS"]: Refreshing state... [id=agm-btt3bl5139-j2bjjp-OPTIONS]
aws_api_gateway_method.lambda_methods["expenditures-GET"]: Refreshing state... [id=agm-btt3bl5139-x3f6cx-GET]
aws_api_gateway_method.lambda_methods["projects-OPTIONS"]: Refreshing state... [id=agm-btt3bl5139-5rlpdk-OPTIONS]
aws_api_gateway_resource.lambda_proxy["users"]: Refreshing state... [id=0s4etn]
aws_api_gateway_method.lambda_methods["auth-GET"]: Refreshing state... [id=agm-btt3bl5139-j2bjjp-GET]
aws_api_gateway_method.lambda_methods["users-POST"]: Refreshing state... [id=agm-btt3bl5139-r6frgh-POST]
aws_api_gateway_method.lambda_methods["donors-POST"]: Refreshing state... [id=agm-btt3bl5139-ooaugc-POST]
aws_api_gateway_method.lambda_methods["projects-POST"]: Refreshing state... [id=agm-btt3bl5139-5rlpdk-POST]
aws_api_gateway_method.lambda_methods["expenditures-OPTIONS"]: Refreshing state... [id=agm-btt3bl5139-x3f6cx-OPTIONS]
aws_api_gateway_resource.lambda_proxy["auth"]: Refreshing state... [id=7tjm3k]
aws_api_gateway_method.lambda_methods["expenditures-PATCH"]: Refreshing state... [id=agm-btt3bl5139-x3f6cx-PATCH]
aws_api_gateway_resource.lambda_proxy["donors"]: Refreshing state... [id=37l1nw]
aws_api_gateway_resource.lambda_proxy["expenditures"]: Refreshing state... [id=2haqg7]
aws_api_gateway_resource.lambda_proxy["projects"]: Refreshing state... [id=zofyad]
aws_api_gateway_resource.lambda_proxy["reports"]: Refreshing state... [id=qpfkcg]
aws_s3_bucket_server_side_encryption_configuration.lambda_deployments: Refreshing state... [id=branch-lambda-deployments-404813129370]
aws_s3_object.lambda_placeholder["reports"]: Refreshing state... [id=branch-lambda-deployments-404813129370/reports/initial.zip]
aws_s3_object.lambda_placeholder["donors"]: Refreshing state... [id=branch-lambda-deployments-404813129370/donors/initial.zip]
aws_s3_object.lambda_placeholder["auth"]: Refreshing state... [id=branch-lambda-deployments-404813129370/auth/initial.zip]
aws_s3_object.lambda_placeholder["expenditures"]: Refreshing state... [id=branch-lambda-deployments-404813129370/expenditures/initial.zip]
aws_s3_object.lambda_placeholder["projects"]: Refreshing state... [id=branch-lambda-deployments-404813129370/projects/initial.zip]
aws_s3_bucket_versioning.lambda_deployments: Refreshing state... [id=branch-lambda-deployments-404813129370]
aws_s3_object.lambda_placeholder["users"]: Refreshing state... [id=branch-lambda-deployments-404813129370/users/initial.zip]
aws_iam_role_policy.lambda_s3_objects: Refreshing state... [id=branch-lambda-role:branch-lambda-s3-objects]
aws_s3_bucket_public_access_block.reports_bucket_public_access: Refreshing state... [id=c4c-branch-generated-reports20260830181426405600000001]
aws_security_group.rds: Refreshing state... [id=sg-0fcbb6d585a94c4b9]
aws_api_gateway_method.cors_proxy_options["donors"]: Refreshing state... [id=agm-btt3bl5139-37l1nw-OPTIONS]
aws_api_gateway_method.cors_proxy_options["expenditures"]: Refreshing state... [id=agm-btt3bl5139-2haqg7-OPTIONS]
aws_api_gateway_method.cors_proxy_options["projects"]: Refreshing state... [id=agm-btt3bl5139-zofyad-OPTIONS]
aws_api_gateway_method.cors_proxy_options["auth"]: Refreshing state... [id=agm-btt3bl5139-7tjm3k-OPTIONS]
aws_api_gateway_method.cors_proxy_options["reports"]: Refreshing state... [id=agm-btt3bl5139-qpfkcg-OPTIONS]
aws_api_gateway_method.cors_proxy_options["users"]: Refreshing state... [id=agm-btt3bl5139-0s4etn-OPTIONS]
aws_api_gateway_method.lambda_proxy_any["auth"]: Refreshing state... [id=agm-btt3bl5139-7tjm3k-ANY]
aws_api_gateway_method.lambda_proxy_any["donors"]: Refreshing state... [id=agm-btt3bl5139-37l1nw-ANY]
aws_api_gateway_method.lambda_proxy_any["reports"]: Refreshing state... [id=agm-btt3bl5139-qpfkcg-ANY]
aws_api_gateway_method.lambda_proxy_any["expenditures"]: Refreshing state... [id=agm-btt3bl5139-2haqg7-ANY]
aws_api_gateway_method.lambda_proxy_any["projects"]: Refreshing state... [id=agm-btt3bl5139-zofyad-ANY]
aws_api_gateway_method.lambda_proxy_any["users"]: Refreshing state... [id=agm-btt3bl5139-0s4etn-ANY]
aws_s3_bucket_public_access_block.frontend: Refreshing state... [id=branch-frontend-404813129370]
aws_vpc_security_group_ingress_rule.rds_postgres: Refreshing state... [id=sgr-04300761c6a4d1014]
aws_vpc_security_group_egress_rule.rds_all: Refreshing state... [id=sgr-0937cfcf0113fcbe8]
aws_api_gateway_integration.cors["projects"]: Refreshing state... [id=agi-btt3bl5139-5rlpdk-OPTIONS]
aws_db_instance.branch_rds: Refreshing state... [id=db-RQUC7A6QEZXSCYCKNMBKSKTS3Y]
aws_api_gateway_integration.cors["reports"]: Refreshing state... [id=agi-btt3bl5139-fbius2-OPTIONS]
aws_api_gateway_integration.cors["auth-proxy"]: Refreshing state... [id=agi-btt3bl5139-7tjm3k-OPTIONS]
aws_api_gateway_integration.cors["users-proxy"]: Refreshing state... [id=agi-btt3bl5139-0s4etn-OPTIONS]
aws_api_gateway_integration.cors["projects-proxy"]: Refreshing state... [id=agi-btt3bl5139-zofyad-OPTIONS]
aws_api_gateway_integration.cors["expenditures"]: Refreshing state... [id=agi-btt3bl5139-x3f6cx-OPTIONS]
aws_api_gateway_integration.cors["reports-proxy"]: Refreshing state... [id=agi-btt3bl5139-qpfkcg-OPTIONS]
aws_api_gateway_integration.cors["donors"]: Refreshing state... [id=agi-btt3bl5139-ooaugc-OPTIONS]
aws_api_gateway_integration.cors["users"]: Refreshing state... [id=agi-btt3bl5139-r6frgh-OPTIONS]
aws_api_gateway_integration.cors["auth"]: Refreshing state... [id=agi-btt3bl5139-j2bjjp-OPTIONS]
aws_api_gateway_integration.cors["expenditures-proxy"]: Refreshing state... [id=agi-btt3bl5139-2haqg7-OPTIONS]
aws_api_gateway_integration.cors["donors-proxy"]: Refreshing state... [id=agi-btt3bl5139-37l1nw-OPTIONS]
aws_api_gateway_method_response.cors["donors"]: Refreshing state... [id=agmr-btt3bl5139-ooaugc-OPTIONS-200]
aws_api_gateway_method_response.cors["auth-proxy"]: Refreshing state... [id=agmr-btt3bl5139-7tjm3k-OPTIONS-200]
aws_api_gateway_method_response.cors["users"]: Refreshing state... [id=agmr-btt3bl5139-r6frgh-OPTIONS-200]
aws_api_gateway_method_response.cors["reports"]: Refreshing state... [id=agmr-btt3bl5139-fbius2-OPTIONS-200]
aws_api_gateway_method_response.cors["projects"]: Refreshing state... [id=agmr-btt3bl5139-5rlpdk-OPTIONS-200]
aws_api_gateway_method_response.cors["expenditures"]: Refreshing state... [id=agmr-btt3bl5139-x3f6cx-OPTIONS-200]
aws_api_gateway_method_response.cors["expenditures-proxy"]: Refreshing state... [id=agmr-btt3bl5139-2haqg7-OPTIONS-200]
aws_api_gateway_method_response.cors["users-proxy"]: Refreshing state... [id=agmr-btt3bl5139-0s4etn-OPTIONS-200]
aws_api_gateway_method_response.cors["donors-proxy"]: Refreshing state... [id=agmr-btt3bl5139-37l1nw-OPTIONS-200]
aws_api_gateway_method_response.cors["projects-proxy"]: Refreshing state... [id=agmr-btt3bl5139-zofyad-OPTIONS-200]
aws_api_gateway_method_response.cors["reports-proxy"]: Refreshing state... [id=agmr-btt3bl5139-qpfkcg-OPTIONS-200]
aws_api_gateway_method_response.cors["auth"]: Refreshing state... [id=agmr-btt3bl5139-j2bjjp-OPTIONS-200]
aws_cloudfront_distribution.frontend: Refreshing state... [id=EOTKQTE3WUELO]
data.aws_iam_policy_document.frontend_bucket: Reading...
data.aws_iam_policy_document.frontend_bucket: Read complete after 0s [id=1913669945]
aws_s3_bucket_policy.frontend: Refreshing state... [id=branch-frontend-404813129370]
aws_cognito_user_pool.branch_user_pool: Refreshing state... [id=us-east-2_ES8vlp7b4]
aws_iam_role_policy.lambda_cognito_admin: Refreshing state... [id=branch-lambda-role:branch-lambda-cognito-admin]
aws_cognito_user_pool_client.branch_client: Refreshing state... [id=26r3n4d9ttjp6fvhdg1erd2eli]
aws_lambda_function.functions["users"]: Refreshing state... [id=branch-users]
aws_lambda_function.functions["projects"]: Refreshing state... [id=branch-projects]
aws_lambda_function.functions["auth"]: Refreshing state... [id=branch-auth]
aws_lambda_function.functions["donors"]: Refreshing state... [id=branch-donors]
aws_lambda_function.functions["reports"]: Refreshing state... [id=branch-reports]
aws_lambda_function.functions["expenditures"]: Refreshing state... [id=branch-expenditures]
aws_iam_role_policy.ci_migrate: Refreshing state... [id=branch-ci-migrate:db-migrate]
aws_lambda_permission.api_gateway_permissions["expenditures"]: Refreshing state... [id=AllowAPIGatewayInvoke]
aws_lambda_permission.api_gateway_permissions["auth"]: Refreshing state... [id=AllowAPIGatewayInvoke]
aws_lambda_permission.api_gateway_permissions["users"]: Refreshing state... [id=AllowAPIGatewayInvoke]
aws_lambda_permission.api_gateway_permissions["reports"]: Refreshing state... [id=AllowAPIGatewayInvoke]
aws_api_gateway_integration.lambda_proxy_integrations["users"]: Refreshing state... [id=agi-btt3bl5139-0s4etn-ANY]
aws_lambda_permission.api_gateway_permissions["projects"]: Refreshing state... [id=AllowAPIGatewayInvoke]
aws_lambda_permission.api_gateway_permissions["donors"]: Refreshing state... [id=AllowAPIGatewayInvoke]
aws_api_gateway_integration.lambda_proxy_integrations["auth"]: Refreshing state... [id=agi-btt3bl5139-7tjm3k-ANY]
aws_api_gateway_integration.lambda_proxy_integrations["donors"]: Refreshing state... [id=agi-btt3bl5139-37l1nw-ANY]
aws_api_gateway_integration.lambda_proxy_integrations["expenditures"]: Refreshing state... [id=agi-btt3bl5139-2haqg7-ANY]
aws_api_gateway_integration.lambda_proxy_integrations["projects"]: Refreshing state... [id=agi-btt3bl5139-zofyad-ANY]
aws_api_gateway_integration.lambda_integrations["reports-GET"]: Refreshing state... [id=agi-btt3bl5139-fbius2-GET]
aws_api_gateway_integration.lambda_proxy_integrations["reports"]: Refreshing state... [id=agi-btt3bl5139-qpfkcg-ANY]
aws_api_gateway_integration.lambda_integrations["expenditures-POST"]: Refreshing state... [id=agi-btt3bl5139-x3f6cx-POST]
aws_api_gateway_integration.lambda_integrations["users-PATCH"]: Refreshing state... [id=agi-btt3bl5139-r6frgh-PATCH]
aws_api_gateway_integration.lambda_integrations["auth-GET"]: Refreshing state... [id=agi-btt3bl5139-j2bjjp-GET]
aws_api_gateway_integration.lambda_integrations["auth-POST"]: Refreshing state... [id=agi-btt3bl5139-j2bjjp-POST]
aws_api_gateway_integration.lambda_integrations["expenditures-GET"]: Refreshing state... [id=agi-btt3bl5139-x3f6cx-GET]
aws_api_gateway_integration.lambda_integrations["expenditures-PATCH"]: Refreshing state... [id=agi-btt3bl5139-x3f6cx-PATCH]
aws_api_gateway_integration.lambda_integrations["donors-POST"]: Refreshing state... [id=agi-btt3bl5139-ooaugc-POST]
aws_api_gateway_integration.lambda_integrations["projects-GET"]: Refreshing state... [id=agi-btt3bl5139-5rlpdk-GET]
aws_api_gateway_integration.lambda_integrations["users-GET"]: Refreshing state... [id=agi-btt3bl5139-r6frgh-GET]
aws_api_gateway_integration.lambda_integrations["projects-POST"]: Refreshing state... [id=agi-btt3bl5139-5rlpdk-POST]
aws_api_gateway_integration.lambda_integrations["users-POST"]: Refreshing state... [id=agi-btt3bl5139-r6frgh-POST]
aws_api_gateway_integration.lambda_integrations["donors-GET"]: Refreshing state... [id=agi-btt3bl5139-ooaugc-GET]
aws_api_gateway_integration.lambda_integrations["users-DELETE"]: Refreshing state... [id=agi-btt3bl5139-r6frgh-DELETE]
aws_api_gateway_integration_response.cors["expenditures-proxy"]: Refreshing state... [id=agir-btt3bl5139-2haqg7-OPTIONS-200]
aws_api_gateway_integration_response.cors["auth"]: Refreshing state... [id=agir-btt3bl5139-j2bjjp-OPTIONS-200]
aws_api_gateway_integration_response.cors["donors"]: Refreshing state... [id=agir-btt3bl5139-ooaugc-OPTIONS-200]
aws_api_gateway_integration_response.cors["users-proxy"]: Refreshing state... [id=agir-btt3bl5139-0s4etn-OPTIONS-200]
aws_api_gateway_integration_response.cors["users"]: Refreshing state... [id=agir-btt3bl5139-r6frgh-OPTIONS-200]
aws_api_gateway_integration_response.cors["auth-proxy"]: Refreshing state... [id=agir-btt3bl5139-7tjm3k-OPTIONS-200]
aws_api_gateway_integration_response.cors["expenditures"]: Refreshing state... [id=agir-btt3bl5139-x3f6cx-OPTIONS-200]
aws_api_gateway_integration_response.cors["projects-proxy"]: Refreshing state... [id=agir-btt3bl5139-zofyad-OPTIONS-200]
aws_api_gateway_integration_response.cors["reports-proxy"]: Refreshing state... [id=agir-btt3bl5139-qpfkcg-OPTIONS-200]
aws_api_gateway_integration_response.cors["donors-proxy"]: Refreshing state... [id=agir-btt3bl5139-37l1nw-OPTIONS-200]
aws_api_gateway_integration_response.cors["projects"]: Refreshing state... [id=agir-btt3bl5139-5rlpdk-OPTIONS-200]
aws_api_gateway_integration_response.cors["reports"]: Refreshing state... [id=agir-btt3bl5139-fbius2-OPTIONS-200]
aws_api_gateway_deployment.branch_deployment: Refreshing state... [id=f4ddhq]
aws_api_gateway_stage.branch_stage: Refreshing state... [id=ags-btt3bl5139-prod]

Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_cloudwatch_log_group.lambda["auth"] will be created
  + resource "aws_cloudwatch_log_group" "lambda" {
      + arn               = (known after apply)
      + id                = (known after apply)
      + log_group_class   = (known after apply)
      + name              = "/aws/lambda/branch-auth"
      + name_prefix       = (known after apply)
      + region            = "us-east-2"
      + retention_in_days = 30
      + skip_destroy      = false
      + tags_all          = {
          + "Project" = "branch"
        }
    }

  # aws_cloudwatch_log_group.lambda["donors"] will be created
  + resource "aws_cloudwatch_log_group" "lambda" {
      + arn               = (known after apply)
      + id                = (known after apply)
      + log_group_class   = (known after apply)
      + name              = "/aws/lambda/branch-donors"
      + name_prefix       = (known after apply)
      + region            = "us-east-2"
      + retention_in_days = 30
      + skip_destroy      = false
      + tags_all          = {
          + "Project" = "branch"
        }
    }

  # aws_cloudwatch_log_group.lambda["expenditures"] will be created
  + resource "aws_cloudwatch_log_group" "lambda" {
      + arn               = (known after apply)
      + id                = (known after apply)
      + log_group_class   = (known after apply)
      + name              = "/aws/lambda/branch-expenditures"
      + name_prefix       = (known after apply)
      + region            = "us-east-2"
      + retention_in_days = 30
      + skip_destroy      = false
      + tags_all          = {
          + "Project" = "branch"
        }
    }

  # aws_cloudwatch_log_group.lambda["projects"] will be created
  + resource "aws_cloudwatch_log_group" "lambda" {
      + arn               = (known after apply)
      + id                = (known after apply)
      + log_group_class   = (known after apply)
      + name              = "/aws/lambda/branch-projects"
      + name_prefix       = (known after apply)
      + region            = "us-east-2"
      + retention_in_days = 30
      + skip_destroy      = false
      + tags_all          = {
          + "Project" = "branch"
        }
    }

  # aws_cloudwatch_log_group.lambda["reports"] will be created
  + resource "aws_cloudwatch_log_group" "lambda" {
      + arn               = (known after apply)
      + id                = (known after apply)
      + log_group_class   = (known after apply)
      + name              = "/aws/lambda/branch-reports"
      + name_prefix       = (known after apply)
      + region            = "us-east-2"
      + retention_in_days = 30
      + skip_destroy      = false
      + tags_all          = {
          + "Project" = "branch"
        }
    }

  # aws_cloudwatch_log_group.lambda["users"] will be created
  + resource "aws_cloudwatch_log_group" "lambda" {
      + arn               = (known after apply)
      + id                = (known after apply)
      + log_group_class   = (known after apply)
      + name              = "/aws/lambda/branch-users"
      + name_prefix       = (known after apply)
      + region            = "us-east-2"
      + retention_in_days = 30
      + skip_destroy      = false
      + tags_all          = {
          + "Project" = "branch"
        }
    }

Plan: 6 to add, 0 to change, 0 to destroy.

─────────────────────────────────────────────────────────────────────────────

Saved the plan to: tfplan

To perform exactly these actions, run the following command to apply:
    terraform apply "tfplan"

Pushed by: @nourshoreibah, Action: pull_request

@nourshoreibah nourshoreibah added the no-review The PR review bot won't run label Aug 30, 2026
@nourshoreibah
nourshoreibah marked this pull request as ready for review August 30, 2026 18:59
@nourshoreibah
nourshoreibah merged commit baef074 into main Aug 30, 2026
20 checks passed
@nourshoreibah
nourshoreibah deleted the infra/point-state-at-client-bucket branch August 30, 2026 18:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-review The PR review bot won't run

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant