Skip to content

Conversation

@tataihono
Copy link
Contributor

@tataihono tataihono commented Jan 14, 2026

Summary

This PR adds a new Strapi CMS service to the Core monorepo with complete infrastructure setup for staging and production environments. The CMS is configured as an app (following the apps/arclight pattern) and includes all necessary configuration for deployment on AWS ECS.

Changes

🆕 New Strapi CMS Application

  • Complete Strapi CMS setup with:

    • Admin panel configuration (config/admin.ts)
    • API configuration (config/api.ts)
    • Database configuration using PostgreSQL (config/database.ts)
    • Server configuration (config/server.ts)
    • Middleware setup (config/middlewares.ts)
    • Plugin configuration including Mux video uploader (config/plugins.ts)
  • Content types pre-configured:

    • Article, Author, Category, About, Global content types
    • Shared components (Media, Quote, Rich Text, SEO, Slider)
  • Docker configuration for containerized deployment

  • Nx project configuration with build, serve, and upgrade targets

  • TypeScript configuration with generated types

🏗️ Infrastructure Setup

Environment Configuration

  • Production environment (infrastructure/environments/prod/):

    • ECS service configuration with auto-scaling (1-4 instances)
    • ALB listener configuration
    • Host name: cms.jesusfilm.org
    • Health check endpoint: /_health on port 1337
    • Doppler secrets integration for environment variables
  • Stage environment (infrastructure/environments/stage/):

    • Same configuration as production
    • Host name: cms-stage.jesusfilm.org
    • Separate Doppler token for stage secrets

Infrastructure Pattern

  • Follows the apps/arclight infrastructure pattern:
    • ALB listener managed at environment level (not within module)
    • Uses alb_listener_arn and alb_dns_name variables
    • Supports host_name and host_names for routing
    • Service config includes alb from ecs_config

ECS Configuration

  • Container: Port 1337 (Strapi default)
  • Resources: 1024 CPU, 2048 MB memory
  • Scaling:
    • Desired count: 1
    • Min capacity: 1
    • Max capacity: 4
    • Auto-scaling based on CPU (75%) and memory (75%)
  • Health checks: /_health endpoint, 30s interval

🔧 Development Environment

  • DevContainer setup: Added CMS database creation in post-create script
  • Workspace configuration: Added CMS to pnpm-workspace.yaml
  • Git ignore: Added CMS-specific ignore patterns

📦 Dependencies

  • Strapi v5.33.3
  • Mux video uploader plugin
  • Blurhash plugin for image optimization
  • PostgreSQL database connection

Environment Variables

The CMS requires the following environment variables (managed via Doppler):

  • ADMIN_JWT_SECRET - Admin panel JWT secret
  • API_TOKEN_SALT - API token salt
  • APP_KEYS - Application keys array
  • ENCRYPTION_KEY - Encryption key
  • PG_DATABASE_URL_CMS - PostgreSQL connection string
  • TRANSFER_TOKEN_SALT - Transfer token salt
  • MUX_* - Mux video service credentials

Testing

  • Infrastructure validated with Terraform plan
  • CMS builds successfully (pnpm --filter cms exec strapi build)
  • CMS runs locally (pnpm --filter cms exec strapi develop)
  • Database connection works correctly
  • Health check endpoint responds correctly
  • ALB routing works with host names

Related

Related to AI-3 - Setting up Strapi CMS infrastructure

Migration Notes

This is a new service addition. No migration required for existing services.

Summary by CodeRabbit

  • New Features

    • Added a CMS app with admin UI, APIs, content types (articles, authors, categories, global), reusable components, Docker image, and deploy targets.
  • Documentation

    • Added comprehensive CMS README and admin examples.
  • Chores

    • Provisioned CMS infra for stage/prod and workspace/project config; added package override.
    • Made CI installs verbose and propagated a new CMS secret to workflows.
    • Added idempotent CMS DB setup and expanded .gitignore rules.

✏️ Tip: You can customize this high-level summary in your review settings.

- Add Strapi CMS API setup with Docker configuration
- Configure database, admin panel, and server settings
- Update infrastructure for staging and production environments
- Update devcontainer post-create command
- Add CMS API to workspace configuration

Related to AI-3
- Move Strapi CMS project directory from apis/cms to apps/cms
- Update infrastructure module references in prod and stage environments
- Update project.json sourceRoot and cwd paths
- Update fetch-secrets command path in project.json
- Adjust desired count for ECS service from 2 to 1
- Enhance ALB configuration with new listener settings
- Refactor variable definitions for ALB listener and host names
- Update production and staging environment configurations to use new ALB settings
- Remove deprecated ALB module references in main.tf
@linear
Copy link

linear bot commented Jan 14, 2026

AI-3 Set up Strapi CMS

@jesus-film-bot
Copy link

Ran Plan for dir: infrastructure workspace: default

Plan Failed: This project is currently locked by an unapplied plan from pull #6780. To continue, delete the lock from #6780 or apply that plan and merge the pull request.

Once the lock is released, comment atlantis plan here to re-plan.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 14, 2026

Walkthrough

Adds a new Strapi CMS application (code, configs, Dockerfile, infra, CI updates), wires stage/prod Terraform modules with Doppler secrets and health checks, marks many Doppler vars sensitive, updates CI to remove pnpm --silent, and adds an idempotent devcontainer DB creation step for the cms database.

Changes

Cohort / File(s) Summary
Devcontainer DB bootstrap
\.devcontainer/post-create-command.sh
Added idempotent check to create Postgres database cms if missing during devcontainer setup.
CI workflows
\.github/workflows/...
Removed --silent from pnpm install --frozen-lockfile across workflows; added/propagated DOPPLER_CMS_TOKEN secret to several jobs.
New CMS app scaffold
apps/cms/*package.json, project.json, tsconfig.json, index.ts, src/index.ts, README.md, Dockerfile, eslint.config.mjs, .gitignore, public/robots.txt
New Strapi app skeleton, build/serve targets, Dockerfile, README, ESLint/TS configs, workspace integration, and ignore rules.
CMS config modules
apps/cms/config/*
Added Strapi config files: admin.ts, api.ts, database.ts, middlewares.ts, plugins.ts, server.ts.
CMS content types & APIs
apps/cms/src/api/...
New content types and standard controllers/routes/services for about, article, author, category, global.
CMS shared components
apps/cms/src/components/shared/*
Added component schemas: media.json, quote.json, rich-text.json, seo.json, slider.json.
CMS admin tooling
apps/cms/src/admin/*
Admin example, admin tsconfig, and Vite example config added.
CMS infra module
apps/cms/infrastructure/{locals.tf,main.tf,variables.tf}
New Terraform module for ECS task/service, ALB target group, autoscaling, resource sizing, and required variables (including doppler_token).
Environment wiring
infrastructure/environments/{stage,prod}/{data.tf,main.tf}
Added cms module invocations for stage/prod, SSM data sources for Doppler tokens, hostnames, and health-check overrides (/_health, port 1337).
Workspace & package config
pnpm-workspace.yaml, package.json
Added workspace package globs and pnpm.overrides pinning canvas for strapi-blurhash.
Terraform doppler_token metadata
**/infrastructure/variables.tf
Marked many doppler_token variables as sensitive and added descriptions across modules and apps.
Misc infra tweaks
infrastructure/modules/aws/*, apps/arclight/infrastructure/locals.tf
RDS engine version bump, EKS node group scaling adjustments, arclight desired_count change.
App-level .gitignore
apps/cms/.gitignore
Added comprehensive ignores for CMS artifacts and Strapi outputs.
Small code edits
apps/journeys-admin/src/libs/firebaseClient/initAuth.ts
Added non-null assertions to cookie secret env vars.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant ALB
  participant ECS as "ECS Task (CMS)"
  participant DB as "Postgres DB"
  participant Doppler

  Client->>ALB: HTTP request to cms domain
  ALB->>ECS: Forward to container port 1337
  ECS->>Doppler: Fetch secrets (startup) using Doppler token
  ECS->>DB: Connect / query (PG via PG_DATABASE_URL_CMS)
  DB-->>ECS: DB response
  ECS-->>ALB: HTTP response
  ALB-->>Client: Return response
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • kiran-redhat
  • mikeallisonJS
🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: add Strapi CMS service and infrastructure' directly and accurately describes the primary change: adding a new Strapi CMS service and its infrastructure configuration to the monorepo.
Linked Issues check ✅ Passed All code requirements from AI-3 are met: Strapi CMS app with API, admin panel, Docker config, Nx targets, database config, plugins (Mux, Blurhash), content types, shared components, and infrastructure for staging/production with ECS, ALB, secrets, and autoscaling.
Out of Scope Changes check ✅ Passed Minor supporting changes (GitHub workflows --silent flag removals, RDS/EKS version bumps, ESLint config, cookie secret assertions) are reasonable adjacent improvements related to CMS deployment and development environment setup.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch cursor/ai-3-set-up-strapi-cms


📜 Recent review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between f3b6fd0 and 0abff07.

⛔ Files ignored due to path filters (2)
  • apps/cms/types/generated/components.d.ts is excluded by !**/generated/**
  • apps/cms/types/generated/contentTypes.d.ts is excluded by !**/generated/**
📒 Files selected for processing (2)
  • apps/cms/eslint.config.mjs
  • apps/journeys-admin/src/libs/firebaseClient/initAuth.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/journeys-admin/src/libs/firebaseClient/initAuth.ts
🧰 Additional context used
🧠 Learnings (12)
📓 Common learnings
Learnt from: mikeallisonJS
Repo: JesusFilm/core PR: 7549
File: apps/arclight/Dockerfile:20-20
Timestamp: 2025-09-04T04:01:06.341Z
Learning: In the JesusFilm/core repository, the build process for apps includes package.json with the necessary scripts, so Docker containers can safely use `pnpm start` after copying the dist directory.
📚 Learning: 2025-08-29T01:43:13.476Z
Learnt from: mikeallisonJS
Repo: JesusFilm/core PR: 7560
File: apps/watch-e2e/eslint.config.mjs:1-3
Timestamp: 2025-08-29T01:43:13.476Z
Learning: The shared e2e ESLint config in libs/shared/eslint/e2e.mjs inherits TypeScript parserOptions and project settings from the common config (libs/shared/eslint/common.mjs) by spreading commonConfig in its exported array. The common config provides comprehensive TS settings including files patterns, parser, parserOptions with project references, and tsconfigRootDir configuration.

Applied to files:

  • apps/cms/eslint.config.mjs
📚 Learning: 2025-08-29T01:43:13.476Z
Learnt from: mikeallisonJS
Repo: JesusFilm/core PR: 7560
File: apps/watch-e2e/eslint.config.mjs:1-3
Timestamp: 2025-08-29T01:43:13.476Z
Learning: The shared e2e ESLint config in libs/shared/eslint/e2e.mjs inherits TypeScript parserOptions and project settings from the common config (libs/shared/eslint/common.mjs) by spreading commonConfig in its exported array, eliminating the need for duplicate TypeScript configuration in the e2e-specific config.

Applied to files:

  • apps/cms/eslint.config.mjs
📚 Learning: 2025-08-29T01:43:28.249Z
Learnt from: mikeallisonJS
Repo: JesusFilm/core PR: 7560
File: libs/nest/common/eslint.config.mjs:1-3
Timestamp: 2025-08-29T01:43:28.249Z
Learning: In the shared ESLint config (libs/shared/eslint/common.mjs), the parserOptions with explicit project and tsconfigRootDir settings work correctly through inheritance mechanisms when consumed by other packages, so no simplification to projectService-only is needed.

Applied to files:

  • apps/cms/eslint.config.mjs
📚 Learning: 2025-08-29T01:44:57.096Z
Learnt from: mikeallisonJS
Repo: JesusFilm/core PR: 7560
File: libs/prisma/users/eslint.config.mjs:1-3
Timestamp: 2025-08-29T01:44:57.096Z
Learning: In libs/prisma/users/eslint.config.mjs, the centralized ESLint config doesn't cause import/no-useless-path-segments rule violations for the Prisma import patterns used in this file, so no local rule override is needed when switching to the shared config.

Applied to files:

  • apps/cms/eslint.config.mjs
📚 Learning: 2025-08-29T01:44:56.258Z
Learnt from: mikeallisonJS
Repo: JesusFilm/core PR: 7560
File: libs/prisma/languages/eslint.config.mjs:1-3
Timestamp: 2025-08-29T01:44:56.258Z
Learning: In libs/prisma/languages/eslint.config.mjs, the shared ESLint config's import/no-useless-path-segments rule does not actually trigger false positives for .prisma client imports despite the rule being enabled, so no local override is needed when switching to the shared commonConfig.

Applied to files:

  • apps/cms/eslint.config.mjs
📚 Learning: 2025-08-29T01:42:29.242Z
Learnt from: mikeallisonJS
Repo: JesusFilm/core PR: 7560
File: apps/docs/eslint.config.mjs:5-5
Timestamp: 2025-08-29T01:42:29.242Z
Learning: In apps/docs/eslint.config.mjs, the ignore pattern 'apps/docs/.docusaurus/*' should ideally be 'apps/docs/.docusaurus/**' to cover nested directories, but the user mikeallisonJS prefers not to address this pre-existing issue during ESLint config standardization work.

Applied to files:

  • apps/cms/eslint.config.mjs
📚 Learning: 2025-07-22T18:37:24.555Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: .cursor/rules/base.mdc:0-0
Timestamp: 2025-07-22T18:37:24.555Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Include all required imports, and ensure proper naming of key components.

Applied to files:

  • apps/cms/eslint.config.mjs
📚 Learning: 2025-12-19T04:58:24.460Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-12-19T04:58:24.460Z
Learning: Applies to apps/watch/src/**/*.{ts,tsx} : Use alphabetical order for imports and exports.

Applied to files:

  • apps/cms/eslint.config.mjs
📚 Learning: 2025-03-02T23:04:53.192Z
Learnt from: tataihono
Repo: JesusFilm/core PR: 5390
File: apis/api-media/src/workers/bigQuery/importers/shortLinks/shortLinks.ts:4-4
Timestamp: 2025-03-02T23:04:53.192Z
Learning: Always ignore ESLint warnings about Prisma client import paths. The import path `.prisma/api-media-client` should not be changed to `./.prisma/api-media-client` despite ESLint flagging it as an error with the rule "import/no-useless-path-segments".

Applied to files:

  • apps/cms/eslint.config.mjs
📚 Learning: 2025-03-02T23:04:09.558Z
Learnt from: tataihono
Repo: JesusFilm/core PR: 5390
File: apis/api-media/src/workers/bigQuery/importers/shortLinks/shortLinks.spec.ts:1-1
Timestamp: 2025-03-02T23:04:09.558Z
Learning: Always ignore ESLint warnings (import/no-useless-path-segments) for Prisma client imports using the format `.prisma/api-media-client` instead of `./.prisma/api-media-client`. This is an intentional pattern in the codebase.

Applied to files:

  • apps/cms/eslint.config.mjs
📚 Learning: 2025-12-19T19:18:43.790Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-19T19:18:43.790Z
Learning: Applies to apps/resources/**/*.spec.ts?(x) : Co-locate React Testing Library specs under `*.spec.ts(x)` and mock network traffic with MSW handlers in `apps/resources/test`

Applied to files:

  • apps/cms/eslint.config.mjs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (15)
  • GitHub Check: Deploy Preview (watch-modern, 8594/merge, pull_request, 22)
  • GitHub Check: Deploy Preview (journeys, 8594/merge, pull_request, 22)
  • GitHub Check: Deploy Preview (watch, 8594/merge, pull_request, 22)
  • GitHub Check: Deploy Preview (videos-admin, 8594/merge, pull_request, 22)
  • GitHub Check: Deploy Preview (resources, 8594/merge, pull_request, 22)
  • GitHub Check: Deploy Preview (journeys-admin, 8594/merge, pull_request, 22)
  • GitHub Check: Deploy Preview (player, 8594/merge, pull_request, 22)
  • GitHub Check: Deploy Preview (docs, 8594/merge, pull_request, 22)
  • GitHub Check: Deploy Preview (short-links, 8594/merge, pull_request, 22)
  • GitHub Check: test (22, 2/3)
  • GitHub Check: build (22)
  • GitHub Check: test (22, 3/3)
  • GitHub Check: test (22, 1/3)
  • GitHub Check: lint (22)
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (1)
apps/cms/eslint.config.mjs (1)

1-22: LGTM!

The ESLint configuration follows the established monorepo pattern correctly:

  • Properly extends the shared commonConfig
  • Appropriate ignore patterns for Strapi-specific directories (.strapi, types/generated)
  • Standard ESM technique for computing tsconfigRootDir

Based on learnings, the explicit project + projectService combination is intentional in this codebase and works correctly through inheritance.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@infracost
Copy link

infracost bot commented Jan 14, 2026

💰 Infracost report

Monthly estimate increased by $414 📈

Changed project Baseline cost Usage cost* Total change New monthly cost
infrastructure +$414 - +$414 (+28%) $1,904

*Usage costs can be estimated by updating Infracost Cloud settings, see docs for other options.

Estimate details (includes details of unsupported resources)
Key: * usage cost, ~ changed, + added, - removed

──────────────────────────────────
Project: infrastructure
Module path: infrastructure

~ module.prod.module.arclight.module.ecs-task.aws_ecs_service.ecs_service
  +$108 ($36 → $144)

    ~ Per GB per hour
      +$19 ($6 → $26)

    ~ Per vCPU per hour
      +$89 ($30 → $118)

~ module.stage.module.arclight.module.ecs-task.aws_ecs_service.ecs_service
  +$108 ($36 → $144)

    ~ Per GB per hour
      +$19 ($6 → $26)

    ~ Per vCPU per hour
      +$89 ($30 → $118)

~ module.prod.module.eks.aws_eks_node_group.az_2a_ondemand
  +$63 ($125 → $188)

    ~ Instance usage (Linux/UNIX, on-demand, t3.large)
      +$61 ($121 → $182)

    ~ Storage (general purpose SSD, gp2)
      +$2 ($4 → $6)

~ module.stage.module.eks.aws_eks_node_group.az_2a_ondemand
  +$63 ($125 → $188)

    ~ Instance usage (Linux/UNIX, on-demand, t3.large)
      +$61 ($121 → $182)

    ~ Storage (general purpose SSD, gp2)
      +$2 ($4 → $6)

+ module.prod.module.cms.module.ecs-task.aws_ecs_service.ecs_service
  +$36

    + Per GB per hour
      +$6

    + Per vCPU per hour
      +$30

+ module.stage.module.cms.module.ecs-task.aws_ecs_service.ecs_service
  +$36

    + Per GB per hour
      +$6

    + Per vCPU per hour
      +$30

+ module.prod.module.cms.module.ecs-task.aws_cloudwatch_log_group.ecs_cw_log_group
  Monthly cost depends on usage

    + Data ingested
      Monthly cost depends on usage
        +$0.50 per GB

    + Archival Storage
      Monthly cost depends on usage
        +$0.03 per GB

    + Insights queries data scanned
      Monthly cost depends on usage
        +$0.005 per GB

+ module.prod.module.cms.module.ecs-task.aws_route53_record.record
  Monthly cost depends on usage

    + Standard queries (first 1B)
      Monthly cost depends on usage
        +$0.40 per 1M queries

    + Latency based routing queries (first 1B)
      Monthly cost depends on usage
        +$0.60 per 1M queries

    + Geo DNS queries (first 1B)
      Monthly cost depends on usage
        +$0.70 per 1M queries

+ module.stage.module.cms.module.ecs-task.aws_cloudwatch_log_group.ecs_cw_log_group
  Monthly cost depends on usage

    + Data ingested
      Monthly cost depends on usage
        +$0.50 per GB

    + Archival Storage
      Monthly cost depends on usage
        +$0.03 per GB

    + Insights queries data scanned
      Monthly cost depends on usage
        +$0.005 per GB

+ module.stage.module.cms.module.ecs-task.aws_route53_record.record
  Monthly cost depends on usage

    + Standard queries (first 1B)
      Monthly cost depends on usage
        +$0.40 per 1M queries

    + Latency based routing queries (first 1B)
      Monthly cost depends on usage
        +$0.60 per 1M queries

    + Geo DNS queries (first 1B)
      Monthly cost depends on usage
        +$0.70 per 1M queries

Monthly cost change for infrastructure (Module path: infrastructure)
Amount:  +$414 ($1,490 → $1,904)
Percent: +28%

──────────────────────────────────
Key: * usage cost, ~ changed, + added, - removed

*Usage costs can be estimated by updating Infracost Cloud settings, see docs for other options.

910 cloud resources were detected:
∙ 126 were estimated
∙ 782 were free
∙ 2 are not supported yet, see https://infracost.io/requested-resources:
  ∙ 1 x aws_s3_bucket_accelerate_configuration
  ∙ 1 x aws_s3_bucket_request_payment_configuration

Infracost estimate: Monthly estimate increased by $414 ↑
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┓
┃ Changed project                                    ┃ Baseline cost ┃ Usage cost* ┃ Total change ┃
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━╋━━━━━━━━━━━━━━┫
┃ infrastructure                                     ┃         +$414 ┃           - ┃ +$414 (+28%) ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━┻━━━━━━━━━━━━━━┛
This comment will be updated when code changes.

@tataihono tataihono changed the title refactor: move CMS to apps and update infrastructure to match apps pattern feat: add Strapi CMS service and infrastructure Jan 14, 2026
- Updated all workflow files to remove the --silent flag from the pnpm install command for better visibility during dependency installation.
@jesus-film-bot
Copy link

Ran Plan for dir: infrastructure workspace: default

Plan Failed: This project is currently locked by an unapplied plan from pull #6780. To continue, delete the lock from #6780 or apply that plan and merge the pull request.

Once the lock is released, comment atlantis plan here to re-plan.

@tataihono tataihono self-assigned this Jan 14, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Fix all issues with AI agents
In @.gitignore:
- Line 10: Update the incorrect .gitignore entries that reference the old
"apis/cms" path to the new "apps/cms" path; replace occurrences like
"/apis/cms/node_modules" (and the other entries in the same block around lines
97-100) with their corresponding "/apps/cms/..." counterparts so the ignored
paths match the repository's current structure.

In `@apps/cms/infrastructure/variables.tf`:
- Around line 34-37: The variable "doppler_token" is a secret and must be marked
sensitive to avoid exposure in plan/output; update the variable declaration for
doppler_token (variable "doppler_token") to include sensitive = true so
Terraform treats its value as sensitive and omits it from logs and plan output.

In `@apps/cms/package.json`:
- Around line 1-39: package.json pins a non-existent `@strapi/strapi`@5.33.3 which
will break installs; update the "@strapi/strapi" version to a published release
(e.g., "5.33.2" or "5.33.1") and ensure the companion packages
"@strapi/plugin-cloud", "@strapi/plugin-users-permissions", and "@strapi/types"
are set to matching published versions (adjust their versions if 5.33.3 is
unavailable); optionally change "pg": "8.8.0" to a caret range "^8.8.0" for
consistency with other deps if you don't require the exact patch, and leave the
"engines" node constraint as-is unless you want to explicitly expand/remove the
upper bound.

In `@apps/cms/public/robots.txt`:
- Around line 1-3: Uncomment and replace the current commented directives in
robots.txt so search engines are blocked from indexing the admin panel and API
endpoints: add a User-agent: * line and Disallow entries for /admin and /api
(i.e., "User-agent: *", "Disallow: /admin", "Disallow: /api"), ensuring the
commented lines "# User-Agent: *" and "# Disallow: /" are removed or replaced so
/admin and /api are explicitly disallowed.
🧹 Nitpick comments (14)
apps/cms/src/components/shared/seo.json (1)

5-7: Consider using a more semantically appropriate icon.

The "allergies" icon doesn't convey SEO functionality. Consider using an icon like "search", "globe", or "file-search" for better admin panel UX.

apps/cms/README.md (1)

5-13: Consider using pnpm commands for consistency with the monorepo.

The project uses pnpm as its package manager. Update the examples to use pnpm instead of npm/yarn for developer consistency.

Also, add language specifiers to code blocks (e.g., ```bash) and fix the heading level jump from h1 to h3 (should be h2) as flagged by static analysis.

📝 Suggested fix
-### `develop`
+## `develop`

 Start your Strapi application with autoReload enabled. [Learn more](https://docs.strapi.io/dev-docs/cli#strapi-develop)

-```
-npm run develop
-# or
-yarn develop
+```bash
+pnpm develop
</details>

</blockquote></details>
<details>
<summary>.devcontainer/post-create-command.sh (1)</summary><blockquote>

`45-50`: **Move success message after CMS database setup for accuracy.**

The "Post-create setup completed!" message at line 45 is logged before the CMS database setup, which is misleading. Consider reordering or adding consistent error handling like the Plausible section.

<details>
<summary>📝 Suggested fix</summary>

```diff
 if ! psql -h db -U postgres -d plausible_db < .devcontainer/plausible.sql; then
   echo "❌ Plausible DB bootstrap failed" >&2
   exit 1
 fi
-echo "Post-create setup completed!"

 echo "Setting up CMS database..."
-psql -U postgres -h db -tc "SELECT 1 FROM pg_database WHERE datname = 'cms'" | grep -q 1 \
-  || psql -U postgres -h db -c "CREATE DATABASE cms;"
+if ! psql -U postgres -h db -tc "SELECT 1 FROM pg_database WHERE datname = 'cms'" | grep -q 1; then
+  if ! psql -U postgres -h db -c "CREATE DATABASE cms;"; then
+    echo "❌ CMS DB creation failed" >&2
+    exit 1
+  fi
+fi
+echo "CMS database ready!"

 echo "Installing Argo CD..."
apps/cms/config/api.ts (1)

1-7: Consider adding a type annotation for the configuration object.

Per coding guidelines, types should be defined when possible. Strapi v5 exports configuration types that can be used here.

📝 Suggested improvement
+interface ApiConfig {
+  rest: {
+    defaultLimit: number;
+    maxLimit: number;
+    withCount: boolean;
+  };
+}
+
-export default {
+export default {
   rest: {
     defaultLimit: 25,
     maxLimit: 100,
     withCount: true,
   },
-};
+} satisfies ApiConfig;

As per coding guidelines, defining types is recommended for TypeScript files.

apps/cms/src/admin/app.example.tsx (1)

34-36: Consider removing console.log from the example template.

While this is an example file (.example.tsx), the console.log(app) in the bootstrap function could inadvertently make it to production if copied without modification. Consider removing it or replacing with a comment explaining where custom bootstrap logic should go.

♻️ Suggested change
   bootstrap(app: StrapiApp) {
-    console.log(app);
+    // Add custom bootstrap logic here
+    // Example: app.registerPlugin({ ... });
   },
apps/cms/config/database.ts (1)

1-15: Consider adding TypeScript type annotation and SSL configuration.

The database configuration is functional, but could benefit from:

  1. Type annotation per coding guidelines for .ts files
  2. Explicit SSL configuration for production PostgreSQL connections (unless handled via PG_DATABASE_URL_CMS query parameters)
♻️ Suggested improvement with type annotation and SSL
+import type { Strapi } from '@strapi/strapi'
+
+interface DatabaseConfig {
+  connection: {
+    client: string
+    connection: {
+      connectionString: string
+      ssl?: { rejectUnauthorized: boolean }
+    }
+    pool: { min: number; max: number }
+    acquireConnectionTimeout: number
+  }
+}
+
-export default ({ env }) => {
-  return {
+export default ({ env }: { env: Strapi['config']['env'] }): DatabaseConfig => ({
     connection: {
       client: 'postgres',
       connection: {
-        connectionString: env('PG_DATABASE_URL_CMS')
+        connectionString: env('PG_DATABASE_URL_CMS'),
+        ssl: env.bool('DATABASE_SSL', true) ? { rejectUnauthorized: false } : undefined
       },
       pool: {
         min: env.int('DATABASE_POOL_MIN', 2),
         max: env.int('DATABASE_POOL_MAX', 10)
       },
       acquireConnectionTimeout: env.int('DATABASE_CONNECTION_TIMEOUT', 60000)
     }
-  }
-}
+})

If SSL is already configured via the PG_DATABASE_URL_CMS connection string (e.g., ?sslmode=require), the explicit SSL option can be omitted.

apps/cms/Dockerfile (1)

1-28: Dockerfile structure is solid with good layer caching optimization.

The Dockerfile is well-structured with proper layer ordering (dependencies before code) for cache efficiency. The native build dependencies (g++, make, python3) are necessary for PostgreSQL and image processing packages. The pnpm run start command is safe given the package.json scripts.

Add .dockerignore to prevent unnecessary files from being copied into the image:

The COPY . . at line 23 will include all files from the directory. Create apps/cms/.dockerignore with:

node_modules
.git
.gitignore
dist
.env*
.env

Consider adding a non-root user for improved container security (optional):

🔒 Suggested security improvement
 RUN apk upgrade --update-cache --available && \
     apk add g++ make python3 py3-pip curl-dev && \
     rm -rf /var/cache/apk/*

+RUN addgroup --system --gid 1001 nodejs && \
+    adduser --system --uid 1001 strapi
+
 WORKDIR /app

 COPY ./package.json ./package.json
 COPY ./pnpm-lock.yaml* ./

 RUN corepack enable && corepack prepare pnpm --activate
 RUN pnpm install --frozen-lockfile

 COPY . .

 RUN pnpm run build

+RUN chown -R strapi:nodejs /app
+USER strapi
+
 CMD ["pnpm", "run", "start"]
apps/cms/config/plugins.ts (1)

1-19: Good security practice — secrets loaded from environment variables.

The plugin configuration correctly uses env() to load sensitive credentials rather than hardcoding them. This aligns with the infrastructure setup that provisions these via Doppler.

Per coding guidelines, consider adding a type annotation for the env parameter. Strapi provides types via @strapi/strapi:

💡 Optional: Add type annotation
+import type { Core } from '@strapi/strapi';
+
-export default ({ env }) => ({
+export default ({ env }: { env: Core.Env }) => ({
   'mux-video-uploader': {
apps/cms/project.json (1)

50-59: Consider adding error handling for missing Doppler token.

The fetch-secrets command may fail silently or create an empty .env file if DOPPLER_CMS_TOKEN is not set, since shell variable expansion won't error and the redirect will still execute.

💡 Suggested improvement with token validation
     "fetch-secrets": {
       "executor": "nx:run-commands",
       "options": {
         "commands": [
           {
-            "command": "DOPPLER_TOKEN=$DOPPLER_CMS_TOKEN doppler secrets download --no-file --format=env-no-quotes --project cms > apps/cms/.env"
+            "command": "test -n \"$DOPPLER_CMS_TOKEN\" || { echo 'Error: DOPPLER_CMS_TOKEN is not set'; exit 1; } && DOPPLER_TOKEN=$DOPPLER_CMS_TOKEN doppler secrets download --no-file --format=env-no-quotes --project cms > apps/cms/.env"
           }
         ]
       }
     }
apps/cms/src/api/category/content-types/category/schema.json (1)

14-19: Consider adding targetField for auto-slug generation and required constraint on name.

The slug field uses uid type but lacks a targetField, so it won't auto-populate from another attribute (e.g., name). Additionally, name has no required: true, allowing empty category names.

♻️ Suggested enhancement
 "attributes": {
   "name": {
-    "type": "string"
+    "type": "string",
+    "required": true
   },
   "slug": {
-    "type": "uid"
+    "type": "uid",
+    "targetField": "name"
   },
apps/cms/src/api/author/content-types/author/schema.json (1)

14-26: Consider adding validation constraints for author attributes.

A few observations on the schema:

  1. name is not marked as required — authors without names may cause display issues.
  2. email lacks email format validation. Strapi supports "type": "email" which provides built-in validation.
  3. avatar allows "videos" — unusual for an avatar field; consider restricting to ["images"] only.
💡 Suggested schema improvements
     "name": {
-      "type": "string"
+      "type": "string",
+      "required": true
     },
     "avatar": {
       "type": "media",
       "multiple": false,
       "required": false,
-      "allowedTypes": ["images", "files", "videos"]
+      "allowedTypes": ["images"]
     },
     "email": {
-      "type": "string"
+      "type": "email"
     },
apps/cms/src/api/global/content-types/global/schema.json (1)

19-24: Consider restricting allowedTypes for favicon to images only.

A favicon is typically an image file (ICO, PNG, SVG). Allowing "files" and "videos" seems unintentional and could lead to invalid favicon configurations.

Suggested fix
     "favicon": {
       "type": "media",
       "multiple": false,
       "required": false,
-      "allowedTypes": ["images", "files", "videos"]
+      "allowedTypes": ["images"]
     },
apps/cms/src/api/article/content-types/article/schema.json (1)

15-17: Consider marking title as required.

The slug field (line 22-25) uses targetField: "title" to auto-generate slugs. If title is empty, slug generation may produce unexpected results or empty slugs, potentially causing routing issues.

Suggested fix
     "title": {
-      "type": "string"
+      "type": "string",
+      "required": true
     },
apps/cms/infrastructure/variables.tf (1)

28-32: Consider adding validation for the env variable.

A validation rule would prevent typos and ensure only valid environments are used. Based on learnings, validation rules help catch incorrect input values early.

Suggested fix
 variable "env" {
   type        = string
   default     = "prod"
   description = "Environment for CMS"
+
+  validation {
+    condition     = contains(["prod", "stage"], var.env)
+    error_message = "Environment must be either 'prod' or 'stage'."
+  }
 }
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between f1d0722 and aa385fa.

⛔ Files ignored due to path filters (4)
  • apps/cms/favicon.png is excluded by !**/*.png
  • apps/cms/types/generated/components.d.ts is excluded by !**/generated/**
  • apps/cms/types/generated/contentTypes.d.ts is excluded by !**/generated/**
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (69)
  • .devcontainer/post-create-command.sh
  • .github/workflows/api-deploy-prod.yml
  • .github/workflows/api-deploy-stage.yml
  • .github/workflows/api-deploy-worker.yml
  • .github/workflows/app-deploy.yml
  • .github/workflows/danger.yml
  • .github/workflows/e2e-tests.yml
  • .github/workflows/ecs-frontend-deploy-prod-worker.yml
  • .github/workflows/ecs-frontend-deploy-stage-worker.yml
  • .github/workflows/ecs-frontend-deploy-stage.yml
  • .github/workflows/main.yml
  • .github/workflows/visual-test.yml
  • .github/workflows/worker-deploy.yml
  • .gitignore
  • apps/cms/.gitignore
  • apps/cms/Dockerfile
  • apps/cms/README.md
  • apps/cms/config/admin.ts
  • apps/cms/config/api.ts
  • apps/cms/config/database.ts
  • apps/cms/config/middlewares.ts
  • apps/cms/config/plugins.ts
  • apps/cms/config/server.ts
  • apps/cms/database/migrations/.gitkeep
  • apps/cms/index.ts
  • apps/cms/infrastructure/locals.tf
  • apps/cms/infrastructure/main.tf
  • apps/cms/infrastructure/variables.tf
  • apps/cms/package.json
  • apps/cms/project.json
  • apps/cms/public/robots.txt
  • apps/cms/public/uploads/.gitkeep
  • apps/cms/src/admin/app.example.tsx
  • apps/cms/src/admin/tsconfig.json
  • apps/cms/src/admin/vite.config.example.ts
  • apps/cms/src/api/.gitkeep
  • apps/cms/src/api/about/content-types/about/schema.json
  • apps/cms/src/api/about/controllers/about.ts
  • apps/cms/src/api/about/routes/about.ts
  • apps/cms/src/api/about/services/about.ts
  • apps/cms/src/api/article/content-types/article/schema.json
  • apps/cms/src/api/article/controllers/article.ts
  • apps/cms/src/api/article/routes/article.ts
  • apps/cms/src/api/article/services/article.ts
  • apps/cms/src/api/author/content-types/author/schema.json
  • apps/cms/src/api/author/controllers/author.ts
  • apps/cms/src/api/author/routes/author.ts
  • apps/cms/src/api/author/services/author.ts
  • apps/cms/src/api/category/content-types/category/schema.json
  • apps/cms/src/api/category/controllers/category.ts
  • apps/cms/src/api/category/routes/category.ts
  • apps/cms/src/api/category/services/category.ts
  • apps/cms/src/api/global/content-types/global/schema.json
  • apps/cms/src/api/global/controllers/global.ts
  • apps/cms/src/api/global/routes/global.ts
  • apps/cms/src/api/global/services/global.ts
  • apps/cms/src/components/shared/media.json
  • apps/cms/src/components/shared/quote.json
  • apps/cms/src/components/shared/rich-text.json
  • apps/cms/src/components/shared/seo.json
  • apps/cms/src/components/shared/slider.json
  • apps/cms/src/extensions/.gitkeep
  • apps/cms/src/index.ts
  • apps/cms/tsconfig.json
  • infrastructure/environments/prod/data.tf
  • infrastructure/environments/prod/main.tf
  • infrastructure/environments/stage/data.tf
  • infrastructure/environments/stage/main.tf
  • pnpm-workspace.yaml
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/base.mdc)

**/*.{ts,tsx,js,jsx}: Use early returns whenever possible to make the code more readable.
Use descriptive variable and function/const names.
Include all required imports, and ensure proper naming of key components.

Files:

  • apps/cms/src/api/about/controllers/about.ts
  • apps/cms/src/api/global/services/global.ts
  • apps/cms/src/api/global/controllers/global.ts
  • apps/cms/src/api/author/controllers/author.ts
  • apps/cms/src/api/global/routes/global.ts
  • apps/cms/src/api/category/services/category.ts
  • apps/cms/src/api/article/routes/article.ts
  • apps/cms/src/api/about/services/about.ts
  • apps/cms/index.ts
  • apps/cms/src/api/article/services/article.ts
  • apps/cms/src/api/category/controllers/category.ts
  • apps/cms/src/admin/vite.config.example.ts
  • apps/cms/src/admin/app.example.tsx
  • apps/cms/src/api/author/services/author.ts
  • apps/cms/src/index.ts
  • apps/cms/config/server.ts
  • apps/cms/config/admin.ts
  • apps/cms/src/api/about/routes/about.ts
  • apps/cms/src/api/category/routes/category.ts
  • apps/cms/config/api.ts
  • apps/cms/config/database.ts
  • apps/cms/config/plugins.ts
  • apps/cms/src/api/author/routes/author.ts
  • apps/cms/src/api/article/controllers/article.ts
  • apps/cms/config/middlewares.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/base.mdc)

Define a type if possible.

Files:

  • apps/cms/src/api/about/controllers/about.ts
  • apps/cms/src/api/global/services/global.ts
  • apps/cms/src/api/global/controllers/global.ts
  • apps/cms/src/api/author/controllers/author.ts
  • apps/cms/src/api/global/routes/global.ts
  • apps/cms/src/api/category/services/category.ts
  • apps/cms/src/api/article/routes/article.ts
  • apps/cms/src/api/about/services/about.ts
  • apps/cms/index.ts
  • apps/cms/src/api/article/services/article.ts
  • apps/cms/src/api/category/controllers/category.ts
  • apps/cms/src/admin/vite.config.example.ts
  • apps/cms/src/admin/app.example.tsx
  • apps/cms/src/api/author/services/author.ts
  • apps/cms/src/index.ts
  • apps/cms/config/server.ts
  • apps/cms/config/admin.ts
  • apps/cms/src/api/about/routes/about.ts
  • apps/cms/src/api/category/routes/category.ts
  • apps/cms/config/api.ts
  • apps/cms/config/database.ts
  • apps/cms/config/plugins.ts
  • apps/cms/src/api/author/routes/author.ts
  • apps/cms/src/api/article/controllers/article.ts
  • apps/cms/config/middlewares.ts
apps/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/apps.mdc)

apps/**/*.{js,jsx,ts,tsx}: Always use MUI over HTML elements; avoid using CSS or tags.
Use descriptive variable and function/const names. Also, event functions should be named with a “handle” prefix, like “handleClick” for onClick and “handleKeyDown” for onKeyDown.
Implement accessibility features on elements. For example, a tag should have a tabindex=“0”, aria-label, on:click, and on:keydown, and similar attributes.

Files:

  • apps/cms/src/api/about/controllers/about.ts
  • apps/cms/src/api/global/services/global.ts
  • apps/cms/src/api/global/controllers/global.ts
  • apps/cms/src/api/author/controllers/author.ts
  • apps/cms/src/api/global/routes/global.ts
  • apps/cms/src/api/category/services/category.ts
  • apps/cms/src/api/article/routes/article.ts
  • apps/cms/src/api/about/services/about.ts
  • apps/cms/index.ts
  • apps/cms/src/api/article/services/article.ts
  • apps/cms/src/api/category/controllers/category.ts
  • apps/cms/src/admin/vite.config.example.ts
  • apps/cms/src/admin/app.example.tsx
  • apps/cms/src/api/author/services/author.ts
  • apps/cms/src/index.ts
  • apps/cms/config/server.ts
  • apps/cms/config/admin.ts
  • apps/cms/src/api/about/routes/about.ts
  • apps/cms/src/api/category/routes/category.ts
  • apps/cms/config/api.ts
  • apps/cms/config/database.ts
  • apps/cms/config/plugins.ts
  • apps/cms/src/api/author/routes/author.ts
  • apps/cms/src/api/article/controllers/article.ts
  • apps/cms/config/middlewares.ts
infrastructure/**/*.{tf,tfvars}

📄 CodeRabbit inference engine (.cursor/rules/infrastructure.mdc)

infrastructure/**/*.{tf,tfvars}: Write concise, well-structured Terraform code with accurate examples.
Avoid hardcoded values; always use variables for flexibility.
Always run terraform fmt to maintain consistent code formatting.
Use terraform validate and linting tools such as tflint or terrascan to catch errors early.
Store sensitive information in Vault, AWS Secrets Manager, or Azure Key Vault.
Avoid hardcoding sensitive values (e.g., passwords, API keys); instead, use Vault or environment variables.

Files:

  • infrastructure/environments/prod/main.tf
  • infrastructure/environments/stage/main.tf
  • infrastructure/environments/stage/data.tf
  • infrastructure/environments/prod/data.tf
infrastructure/**/*

📄 CodeRabbit inference engine (.cursor/rules/infrastructure.mdc)

infrastructure/**/*: Organize resources by service or application domain (e.g., networking, compute).
Ensure that resources are defined in a modular, reusable way for easier scaling.

Files:

  • infrastructure/environments/prod/main.tf
  • infrastructure/environments/stage/main.tf
  • infrastructure/environments/stage/data.tf
  • infrastructure/environments/prod/data.tf
🧠 Learnings (40)
📓 Common learnings
Learnt from: mikeallisonJS
Repo: JesusFilm/core PR: 7549
File: apps/arclight/Dockerfile:20-20
Timestamp: 2025-09-04T04:01:06.341Z
Learning: In the JesusFilm/core repository, the build process for apps includes package.json with the necessary scripts, so Docker containers can safely use `pnpm start` after copying the dist directory.
📚 Learning: 2025-12-19T04:58:24.460Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-12-19T04:58:24.460Z
Learning: Pnpm is the required package manager; use `pnpm install` for dependencies and avoid npm, yarn, or bun.

Applied to files:

  • .github/workflows/worker-deploy.yml
  • .github/workflows/api-deploy-worker.yml
  • .github/workflows/ecs-frontend-deploy-stage.yml
  • .github/workflows/api-deploy-prod.yml
  • .github/workflows/main.yml
  • .github/workflows/ecs-frontend-deploy-stage-worker.yml
  • .github/workflows/danger.yml
  • .github/workflows/app-deploy.yml
  • .github/workflows/api-deploy-stage.yml
  • .github/workflows/e2e-tests.yml
  • .github/workflows/ecs-frontend-deploy-prod-worker.yml
  • .github/workflows/visual-test.yml
📚 Learning: 2025-12-19T04:58:24.460Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-12-19T04:58:24.460Z
Learning: Applies to apps/watch/apps/watch-e2e/**/*.{ts,tsx} : Reuse the workspace Playwright installation for E2E tests in `apps/watch-e2e`; never install Playwright globally or commit browser binaries.

Applied to files:

  • .github/workflows/worker-deploy.yml
  • .github/workflows/ecs-frontend-deploy-stage.yml
  • .github/workflows/app-deploy.yml
  • .github/workflows/e2e-tests.yml
  • pnpm-workspace.yaml
📚 Learning: 2025-09-04T04:02:44.231Z
Learnt from: mikeallisonJS
Repo: JesusFilm/core PR: 7549
File: apps/journeys-admin/project.json:54-59
Timestamp: 2025-09-04T04:02:44.231Z
Learning: In pnpm workspaces, dependencies (including devDependencies) installed at the root package.json are available to all workspace packages via `pnpm exec`, so individual packages don't need to declare these dependencies locally.

Applied to files:

  • .github/workflows/api-deploy-worker.yml
  • .github/workflows/ecs-frontend-deploy-stage.yml
  • pnpm-workspace.yaml
📚 Learning: 2025-12-19T19:18:43.790Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-19T19:18:43.790Z
Learning: Applies to apps/resources/**/*.graphql : After editing GraphQL documents, run `pnpm dlx nx run resources:codegen`. The task clears and regenerates `apps/resources/__generated__`, so stage those artifacts with your changes

Applied to files:

  • .github/workflows/api-deploy-worker.yml
  • .github/workflows/ecs-frontend-deploy-stage.yml
  • .github/workflows/main.yml
  • pnpm-workspace.yaml
📚 Learning: 2025-12-19T04:58:24.460Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-12-19T04:58:24.460Z
Learning: Applies to apps/watch/src/**/*.graphql : After editing GraphQL documents, run `pnpm dlx nx run watch:codegen` to regenerate artifacts in `apps/watch/__generated__` and stage those artifacts with changes.

Applied to files:

  • .github/workflows/api-deploy-worker.yml
  • .github/workflows/main.yml
  • apps/cms/project.json
  • pnpm-workspace.yaml
📚 Learning: 2025-09-04T22:08:32.297Z
Learnt from: mikeallisonJS
Repo: JesusFilm/core PR: 7549
File: package.json:5-5
Timestamp: 2025-09-04T22:08:32.297Z
Learning: In the JesusFilm/core repository, when using corepack in Dockerfiles, use `corepack prepare pnpm --activate` without specifying a version, as corepack will automatically read the version from the packageManager field in package.json. Do not hardcode pnpm versions in Dockerfiles.

Applied to files:

  • .github/workflows/ecs-frontend-deploy-stage.yml
📚 Learning: 2025-12-19T19:18:43.790Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-19T19:18:43.790Z
Learning: Reuse the workspace Playwright installation; never install Playwright globally or commit browser binaries

Applied to files:

  • .github/workflows/ecs-frontend-deploy-stage.yml
  • .github/workflows/app-deploy.yml
  • .github/workflows/e2e-tests.yml
📚 Learning: 2025-12-19T04:58:24.460Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-12-19T04:58:24.460Z
Learning: Reuse E2E coverage from `apps/watch-e2e` and its Playwright setup instead of creating new tooling.

Applied to files:

  • .github/workflows/ecs-frontend-deploy-stage.yml
📚 Learning: 2025-12-19T04:58:24.460Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-12-19T04:58:24.460Z
Learning: Extend Playwright scenarios when UI behavior shifts, and capture console logs/screenshots for regressions.

Applied to files:

  • .github/workflows/ecs-frontend-deploy-stage.yml
📚 Learning: 2025-08-29T01:42:29.242Z
Learnt from: mikeallisonJS
Repo: JesusFilm/core PR: 7560
File: apps/docs/eslint.config.mjs:5-5
Timestamp: 2025-08-29T01:42:29.242Z
Learning: In apps/docs/eslint.config.mjs, the ignore pattern 'apps/docs/.docusaurus/*' should ideally be 'apps/docs/.docusaurus/**' to cover nested directories, but the user mikeallisonJS prefers not to address this pre-existing issue during ESLint config standardization work.

Applied to files:

  • apps/cms/.gitignore
  • .gitignore
📚 Learning: 2025-12-19T19:18:43.790Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-19T19:18:43.790Z
Learning: Applies to apps/resources/**/index.ts : Export all components through index.ts files

Applied to files:

  • apps/cms/index.ts
  • apps/cms/src/index.ts
  • apps/cms/config/middlewares.ts
📚 Learning: 2025-12-19T04:58:24.460Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-12-19T04:58:24.460Z
Learning: Applies to apps/watch/src/**/*.{ts,tsx} : Export all components through index.ts files.

Applied to files:

  • apps/cms/index.ts
  • apps/cms/src/index.ts
  • apps/cms/src/admin/tsconfig.json
  • apps/cms/config/middlewares.ts
📚 Learning: 2025-12-19T04:58:24.460Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-12-19T04:58:24.460Z
Learning: Applies to apps/watch/src/**/*.{ts,tsx} : Use alphabetical order for imports and exports.

Applied to files:

  • apps/cms/index.ts
  • apps/cms/tsconfig.json
  • apps/cms/src/admin/tsconfig.json
📚 Learning: 2025-12-19T19:18:43.790Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-19T19:18:43.790Z
Learning: Applies to apps/resources/**/pages/**/*.{ts,tsx} : Progressive enhancement: ensure core flows work without client JS where feasible; render critical content on the server

Applied to files:

  • apps/cms/index.ts
📚 Learning: 2025-12-19T04:58:24.460Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-12-19T04:58:24.460Z
Learning: Applies to apps/watch/src/pages/**/*.{ts,tsx} : Ensure core flows work without client JS where feasible; render critical content on the server with progressive enhancement.

Applied to files:

  • apps/cms/index.ts
📚 Learning: 2025-12-19T04:58:24.460Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-12-19T04:58:24.460Z
Learning: Applies to apps/watch/src/**/*.{ts,tsx} : Use `'use client'` components only when necessary; follow a server-first architecture.

Applied to files:

  • apps/cms/index.ts
📚 Learning: 2025-12-19T19:18:43.790Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-19T19:18:43.790Z
Learning: Applies to apps/resources/**/*.{ts,tsx} : Follow a server-first architecture: use 'use client' components only when necessary

Applied to files:

  • apps/cms/index.ts
📚 Learning: 2025-08-29T01:43:13.476Z
Learnt from: mikeallisonJS
Repo: JesusFilm/core PR: 7560
File: apps/watch-e2e/eslint.config.mjs:1-3
Timestamp: 2025-08-29T01:43:13.476Z
Learning: The shared e2e ESLint config in libs/shared/eslint/e2e.mjs inherits TypeScript parserOptions and project settings from the common config (libs/shared/eslint/common.mjs) by spreading commonConfig in its exported array. The common config provides comprehensive TS settings including files patterns, parser, parserOptions with project references, and tsconfigRootDir configuration.

Applied to files:

  • apps/cms/tsconfig.json
  • apps/cms/src/admin/tsconfig.json
📚 Learning: 2025-08-29T01:43:13.476Z
Learnt from: mikeallisonJS
Repo: JesusFilm/core PR: 7560
File: apps/watch-e2e/eslint.config.mjs:1-3
Timestamp: 2025-08-29T01:43:13.476Z
Learning: The shared e2e ESLint config in libs/shared/eslint/e2e.mjs inherits TypeScript parserOptions and project settings from the common config (libs/shared/eslint/common.mjs) by spreading commonConfig in its exported array, eliminating the need for duplicate TypeScript configuration in the e2e-specific config.

Applied to files:

  • apps/cms/tsconfig.json
  • apps/cms/src/admin/tsconfig.json
📚 Learning: 2025-07-22T18:37:24.555Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: .cursor/rules/base.mdc:0-0
Timestamp: 2025-07-22T18:37:24.555Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Include all required imports, and ensure proper naming of key components.

Applied to files:

  • apps/cms/tsconfig.json
  • apps/cms/src/admin/tsconfig.json
📚 Learning: 2025-08-29T01:43:28.249Z
Learnt from: mikeallisonJS
Repo: JesusFilm/core PR: 7560
File: libs/nest/common/eslint.config.mjs:1-3
Timestamp: 2025-08-29T01:43:28.249Z
Learning: In the shared ESLint config (libs/shared/eslint/common.mjs), the parserOptions with explicit project and tsconfigRootDir settings work correctly through inheritance mechanisms when consumed by other packages, so no simplification to projectService-only is needed.

Applied to files:

  • apps/cms/tsconfig.json
  • apps/cms/src/admin/tsconfig.json
📚 Learning: 2025-12-19T19:18:43.790Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-19T19:18:43.790Z
Learning: Applies to apps/resources/**/*.{ts,tsx} : Use alphabetical order for imports and exports

Applied to files:

  • apps/cms/tsconfig.json
  • apps/cms/src/admin/tsconfig.json
📚 Learning: 2025-07-22T18:37:24.555Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: .cursor/rules/base.mdc:0-0
Timestamp: 2025-07-22T18:37:24.555Z
Learning: Applies to **/*.{ts,tsx} : Define a type if possible.

Applied to files:

  • apps/cms/tsconfig.json
  • apps/cms/src/admin/tsconfig.json
📚 Learning: 2025-12-19T04:58:24.460Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-12-19T04:58:24.460Z
Learning: Applies to apps/watch/src/**/*.{ts,tsx} : All components and functions must be fully typed with TypeScript.

Applied to files:

  • apps/cms/tsconfig.json
  • apps/cms/src/admin/tsconfig.json
📚 Learning: 2025-12-19T19:18:43.790Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-19T19:18:43.790Z
Learning: Use pnpm as the required package manager

Applied to files:

  • .github/workflows/ecs-frontend-deploy-stage-worker.yml
  • .github/workflows/ecs-frontend-deploy-prod-worker.yml
📚 Learning: 2025-09-04T04:01:06.341Z
Learnt from: mikeallisonJS
Repo: JesusFilm/core PR: 7549
File: apps/arclight/Dockerfile:20-20
Timestamp: 2025-09-04T04:01:06.341Z
Learning: In the JesusFilm/core repository, the build process for apps includes package.json with the necessary scripts, so Docker containers can safely use `pnpm start` after copying the dist directory.

Applied to files:

  • apps/cms/package.json
  • apps/cms/Dockerfile
📚 Learning: 2025-07-22T18:37:46.814Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: .cursor/rules/infrastructure.mdc:0-0
Timestamp: 2025-07-22T18:37:46.814Z
Learning: Applies to infrastructure/**/*.{tf} : Structure files into logical sections: main configuration, variables, outputs, and modules.

Applied to files:

  • infrastructure/environments/prod/main.tf
  • apps/cms/infrastructure/main.tf
  • apps/cms/infrastructure/locals.tf
  • infrastructure/environments/stage/main.tf
  • apps/cms/infrastructure/variables.tf
📚 Learning: 2025-07-22T18:37:46.814Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: .cursor/rules/infrastructure.mdc:0-0
Timestamp: 2025-07-22T18:37:46.814Z
Learning: Applies to infrastructure/**/*.{tf} : Use versioned modules and provider version locks to ensure consistent deployments.

Applied to files:

  • infrastructure/environments/prod/main.tf
  • apps/cms/infrastructure/main.tf
  • infrastructure/environments/stage/main.tf
📚 Learning: 2025-07-27T21:59:10.507Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: .cursor/rules/watch-modern.mdc:0-0
Timestamp: 2025-07-27T21:59:10.507Z
Learning: Applies to apps/watch-modern/**/*.{ts,tsx} : All components and functions must be fully typed with TypeScript.

Applied to files:

  • apps/cms/src/admin/tsconfig.json
📚 Learning: 2025-12-19T19:18:43.790Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-19T19:18:43.790Z
Learning: Applies to apps/resources/**/*.{ts,tsx} : All components and functions must be fully typed with TypeScript

Applied to files:

  • apps/cms/src/admin/tsconfig.json
📚 Learning: 2025-12-19T04:58:24.460Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-12-19T04:58:24.460Z
Learning: Applies to apps/watch/src/**/*.{ts,tsx} : Preserve existing contracts in components like `VideoBlock` which depend on the full provider stack, video.js, and mux metadata so autoplay, subtitles, and analytics remain intact.

Applied to files:

  • apps/cms/src/admin/tsconfig.json
  • apps/cms/config/plugins.ts
  • apps/cms/src/components/shared/media.json
📚 Learning: 2025-12-19T04:58:24.460Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-12-19T04:58:24.460Z
Learning: Applies to apps/watch/libs/shared/ui-modern/**/*.{ts,tsx} : Use the automated script `libs/shared/ui-modern/add-shadcn-component.sh` for adding new shadcn components to ensure dependencies are installed at monorepo root level, not in individual library packages.

Applied to files:

  • apps/cms/src/admin/tsconfig.json
📚 Learning: 2025-11-11T23:22:02.196Z
Learnt from: mikeallisonJS
Repo: JesusFilm/core PR: 8156
File: apis/api-journeys-modern/src/lib/google/googleAuth.ts:0-0
Timestamp: 2025-11-11T23:22:02.196Z
Learning: In apis/api-journeys-modern, use the validated `env` object from `../../env` instead of accessing `process.env` directly for environment variables that are defined in env.ts (e.g., GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, INTEGRATION_ACCESS_KEY_ENCRYPTION_SECRET). This eliminates the need for runtime validation checks since Zod validates them at application startup.

Applied to files:

  • apps/cms/config/admin.ts
📚 Learning: 2025-07-22T18:37:46.814Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: .cursor/rules/infrastructure.mdc:0-0
Timestamp: 2025-07-22T18:37:46.814Z
Learning: Applies to infrastructure/**/*.{tf,tfvars} : Avoid hardcoded values; always use variables for flexibility.

Applied to files:

  • apps/cms/infrastructure/locals.tf
  • apps/cms/infrastructure/variables.tf
📚 Learning: 2025-07-22T18:37:46.814Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: .cursor/rules/infrastructure.mdc:0-0
Timestamp: 2025-07-22T18:37:46.814Z
Learning: Applies to infrastructure/**/*.{tf} : Version control modules and follow semantic versioning for stability.

Applied to files:

  • infrastructure/environments/stage/main.tf
📚 Learning: 2025-07-22T18:37:46.814Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: .cursor/rules/infrastructure.mdc:0-0
Timestamp: 2025-07-22T18:37:46.814Z
Learning: Applies to infrastructure/**/*.{tf} : Use validation rules for variables to prevent incorrect input values.

Applied to files:

  • apps/cms/infrastructure/variables.tf
📚 Learning: 2025-07-22T18:37:46.814Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: .cursor/rules/infrastructure.mdc:0-0
Timestamp: 2025-07-22T18:37:46.814Z
Learning: Applies to infrastructure/**/*.{tf,tfvars} : Avoid hardcoding sensitive values (e.g., passwords, API keys); instead, use Vault or environment variables.

Applied to files:

  • apps/cms/infrastructure/variables.tf
📚 Learning: 2025-07-22T18:37:46.814Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: .cursor/rules/infrastructure.mdc:0-0
Timestamp: 2025-07-22T18:37:46.814Z
Learning: Applies to infrastructure/**/*.{tf} : Utilize workspaces for environment separation (e.g., dev, staging, prod).

Applied to files:

  • apps/cms/infrastructure/variables.tf
📚 Learning: 2025-07-22T18:37:46.814Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: .cursor/rules/infrastructure.mdc:0-0
Timestamp: 2025-07-22T18:37:46.814Z
Learning: Applies to infrastructure/**/*.{tf} : Follow cloud provider-specific security guidelines (e.g., AWS, Azure, GCP) for best practices.

Applied to files:

  • apps/cms/infrastructure/variables.tf
🪛 LanguageTool
apps/cms/README.md

[grammar] ~3-~3: Use a hyphen to join words.
Context: ...ed with Strapi Strapi comes with a full featured [Command Line Interface](https:...

(QB_NEW_EN_HYPHEN)


[style] ~48-~48: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... by the core team and the community. - Strapi blog - Officia...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~50-~50: Consider using a less common alternative to make your writing sound more unique and professional.
Context: ...new features and general improvements. Feel free to check out the [Strapi GitHub repository...

(FEEL_FREE_TO_STYLE_ME)


[style] ~56-~56: The preposition ‘with’ is not usually used with the verb ‘talk’. Consider using ‘speak’ instead, or replacing the preposition.
Context: ...Strapi project and get feedback or just talk with other Community members. - [Awesome Str...

(TALK_WITH)

🪛 markdownlint-cli2 (0.18.1)
apps/cms/README.md

5-5: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3

(MD001, heading-increment)


9-9: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


19-19: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


29-29: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


39-39: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: danger (22)
🔇 Additional comments (56)
.github/workflows/api-deploy-stage.yml (1)

32-32: LGTM!

Removing --silent improves debuggability by showing dependency resolution output when builds fail.

.github/workflows/e2e-tests.yml (2)

79-79: LGTM!

Verbose install output will help diagnose dependency issues in E2E test runs.


183-183: LGTM!

Consistent with the change at line 79 for the other E2E job.

.github/workflows/ecs-frontend-deploy-prod-worker.yml (1)

84-84: LGTM!

Verbose install logs are especially valuable for debugging production deployment issues.

.github/workflows/danger.yml (1)

41-41: LGTM!

Consistent with the broader workflow updates for improved CI visibility.

.github/workflows/ecs-frontend-deploy-stage.yml (2)

28-28: LGTM!

Verbose output for the affected projects detection job will aid in troubleshooting.


93-93: LGTM!

Consistent with the change in the affected job above.

.github/workflows/visual-test.yml (1)

32-33: LGTM!

Removing --silent enables verbose dependency installation output, which improves debuggability when CI builds fail. The --frozen-lockfile flag is correctly preserved.

.github/workflows/api-deploy-prod.yml (1)

31-32: LGTM!

Consistent with the repo-wide update to enable verbose install output for better CI observability.

.github/workflows/main.yml (2)

35-36: LGTM!

Verbose install output in the main build job improves CI debugging.


96-97: LGTM!

Consistent change in the test job—verbose output helps diagnose dependency-related test failures.

.github/workflows/ecs-frontend-deploy-stage-worker.yml (1)

83-84: LGTM!

Enabling verbose install output aligns with the repo-wide update for improved CI observability.

.github/workflows/api-deploy-worker.yml (1)

66-67: LGTM!

Consistent removal of --silent flag completes the repo-wide update for verbose dependency installation across all deployment workflows.

.github/workflows/app-deploy.yml (1)

34-34: LGTM! Verbose output improves CI debuggability.

Removing --silent from pnpm install commands across all jobs (affected, deploy-preview, e2e, deploy-production) enables verbose dependency installation output, which aids troubleshooting failed installs without affecting workflow functionality.

Also applies to: 100-100, 262-262, 347-347

.github/workflows/worker-deploy.yml (1)

32-32: LGTM! Consistent with other workflow changes.

Removing --silent from all pnpm install commands in this workflow aligns with the same change applied across other CI workflows, providing consistent verbose output for dependency installation debugging.

Also applies to: 68-68, 103-103

pnpm-workspace.yaml (2)

1-5: LGTM!

The workspace package globs correctly include the new apps/cms package via apps/**. This standard configuration properly integrates the Strapi CMS into the monorepo workspace.


19-19: Canvas is a confirmed direct dependency required by the CMS package for image processing.

Canvas (^3.2.1) is explicitly listed in apps/cms/package.json and is used by the strapi-blurhash plugin for image processing operations. Adding canvas to onlyBuiltDependencies is appropriate since it's a native Node.js module that requires C++ compilation during installation.

apps/cms/src/admin/vite.config.example.ts (1)

6-10: Add path import and fix absolute alias path.

The alias '@': '/src' uses an absolute filesystem path that won't resolve correctly in the Strapi admin build context. According to Strapi v5 documentation, use path.resolve(__dirname, '.') instead.

Update the file to:

import { mergeConfig, type UserConfig } from 'vite';
import path from 'path';

export default (config: UserConfig) => {
  // Important: always return the modified config
  return mergeConfig(config, {
    resolve: {
      alias: {
        '@': path.resolve(__dirname, '.'),
      },
    },
  });
};

This resolves the alias relative to the config file location, matching Strapi's official admin Vite configuration pattern.

⛔ Skipped due to learnings
Learnt from: mikeallisonJS
Repo: JesusFilm/core PR: 7560
File: apps/docs/eslint.config.mjs:5-5
Timestamp: 2025-08-29T01:42:29.242Z
Learning: In apps/docs/eslint.config.mjs, the ignore pattern 'apps/docs/.docusaurus/*' should ideally be 'apps/docs/.docusaurus/**' to cover nested directories, but the user mikeallisonJS prefers not to address this pre-existing issue during ESLint config standardization work.
Learnt from: mikeallisonJS
Repo: JesusFilm/core PR: 7560
File: libs/prisma/users/eslint.config.mjs:1-3
Timestamp: 2025-08-29T01:44:57.096Z
Learning: In libs/prisma/users/eslint.config.mjs, the centralized ESLint config doesn't cause import/no-useless-path-segments rule violations for the Prisma import patterns used in this file, so no local rule override is needed when switching to the shared config.
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: .cursor/rules/base.mdc:0-0
Timestamp: 2025-07-22T18:37:24.555Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Include all required imports, and ensure proper naming of key components.
Learnt from: tataihono
Repo: JesusFilm/core PR: 5390
File: apis/api-media/src/workers/bigQuery/importers/shortLinks/shortLinks.ts:4-4
Timestamp: 2025-03-02T23:04:53.192Z
Learning: Always ignore ESLint warnings about Prisma client import paths. The import path `.prisma/api-media-client` should not be changed to `./.prisma/api-media-client` despite ESLint flagging it as an error with the rule "import/no-useless-path-segments".
infrastructure/environments/stage/data.tf (1)

60-63: LGTM!

The new SSM parameter data source follows the established pattern used by other services in this file (api-gateway, arclight, journeys-admin, etc.) and correctly references the Doppler token for the CMS stage environment.

apps/cms/src/admin/tsconfig.json (1)

1-20: LGTM!

The TypeScript configuration is well-suited for a Strapi admin panel:

  • Modern ESNext target with Bundler module resolution aligns with Strapi's Vite-based admin build
  • Strict mode enabled for type safety
  • Include patterns correctly capture plugin admin sources
apps/cms/src/components/shared/rich-text.json (1)

1-14: LGTM!

The rich text component schema is clean and minimal. The single body field with richtext type is appropriate for use in dynamic zones across Article and About content types.

apps/cms/src/components/shared/media.json (1)

1-15: LGTM!

The Media component schema is well-structured and follows Strapi conventions. The allowedTypes configuration correctly permits images, files, and videos with single selection, which aligns with its usage as a block component in Article and About content-types.

apps/cms/tsconfig.json (1)

1-43: LGTM!

The TypeScript configuration is appropriate for a Strapi CMS application. The CommonJS module format and Node resolution are required by Strapi, and the exclusion patterns correctly separate server-side code from admin and plugin compilation.

Note: strict: false is acceptable for Strapi projects due to auto-generated types, but consider enabling stricter checks incrementally as the codebase matures.

apps/cms/config/server.ts (1)

1-7: LGTM!

Standard Strapi server configuration. The defaults align with the infrastructure configuration (port 1337, host 0.0.0.0 for container accessibility). APP_KEYS correctly has no default, ensuring the application fails fast if this required secret is missing.

apps/cms/.gitignore (1)

1-131: Comprehensive .gitignore configuration.

The ignore patterns appropriately cover OS artifacts, build outputs, secrets (.env), and Strapi-specific files. The public/uploads/.gitkeep exception correctly preserves the uploads directory structure.

One consideration: Line 40 ignores *.csv files. If CSV data files are needed for content seeding or migrations, you may need to add exceptions.

apps/cms/config/middlewares.ts (1)

1-12: Consider environment-specific middleware configuration for production hardening.

The middleware stack uses Strapi's default configuration. For production deployment, customize the CORS and security middlewares via environment-specific config at apps/cms/config/env/production/middlewares.ts:

  • strapi::cors: Configure allowed origins (e.g., cms.jesusfilm.org) from environment variables
  • strapi::security: Adjust CSP headers based on admin panel requirements

Reference the admin.ts pattern using ({ env }) => and env() helpers for environment-specific values.

apps/cms/infrastructure/locals.tf (1)

1-43: LGTM!

The locals configuration is well-structured:

  • Port is defined once and reused for container_port, host_port, and alb_target_group.port (DRY principle)
  • All sensitive values are sourced from environment variables via Doppler rather than hardcoded
  • Auto-scaling thresholds (75% CPU/memory) with min=1, max=4 capacity are reasonable for a CMS workload
  • The merge pattern for alb_target_group cleanly overrides only the port while preserving other inherited settings
infrastructure/environments/prod/data.tf (1)

65-67: LGTM!

The new SSM parameter data source follows the established naming convention (doppler_{service}_{env}_token) and path pattern (/terraform/prd/DOPPLER_{SERVICE}_PROD_TOKEN) used by other service tokens in this file.

apps/cms/src/api/about/content-types/about/schema.json (1)

1-23: LGTM!

The Strapi single-type schema for "About" is well-defined:

  • singleType is the correct choice for an About page (only one instance needed)
  • The dynamiczone pattern with shared components (shared.media, shared.quote, shared.rich-text, shared.slider) provides flexible content composition
  • All referenced components exist in apps/cms/src/components/shared
apps/cms/src/components/shared/slider.json (1)

1-17: LGTM — Schema structure is correct.

The Strapi component schema is well-formed with appropriate media constraints (multiple: true, allowedTypes: ["images"]).

Minor observation: The icon: "address-book" doesn't semantically match a slider/carousel component. Consider using an icon like "images" or "picture" for better admin UX, but this is purely cosmetic.

apps/cms/config/admin.ts (1)

1-20: LGTM — Standard Strapi admin configuration with properly externalized secrets.

The configuration correctly:

  • Loads authentication and encryption secrets from environment variables
  • Uses env.bool() with sensible defaults for feature flags
  • Follows Strapi v5 admin configuration patterns

Same optional typing suggestion applies as noted in plugins.ts.

apps/cms/project.json (1)

1-49: LGTM — Well-structured Nx project configuration.

The configuration properly defines:

  • Build target with correct output path for Nx caching
  • Serve target for local development
  • Upgrade targets (with dry-run option) for Strapi version management
  • Lint target with content-based caching strategy
apps/cms/src/components/shared/quote.json (1)

1-16: LGTM — Clean quote component schema.

The schema appropriately uses string for the title and text for the body (allowing longer content). The "indent" icon is a reasonable choice for a quote component.

Optional consideration: You may want to mark at least one field (e.g., body) as required: true to prevent empty quote components from being added to articles, but this depends on your content modeling requirements.

apps/cms/src/api/about/controllers/about.ts (1)

1-7: LGTM!

This follows the standard Strapi v5 core controller pattern correctly. The api::about.about namespace properly references the About content-type.

apps/cms/src/api/article/controllers/article.ts (1)

1-7: LGTM!

Standard Strapi v5 core controller pattern with correct namespace for the Article content-type.

apps/cms/src/api/about/routes/about.ts (1)

1-7: LGTM!

Standard Strapi v5 core router pattern. The namespace correctly matches the corresponding controller and service.

apps/cms/src/api/global/routes/global.ts (1)

1-7: LGTM!

Standard Strapi v5 core router pattern for the Global content-type, which is commonly used for site-wide configuration settings.

apps/cms/infrastructure/main.tf (1)

1-13: Module inputs all properly defined in ecs-task module.

All 10 provided inputs (ecs_config, service_config, env, doppler_token, environment_variables, alb_listener_arn, alb_dns_name, host_name, host_names, dd_source) match the module's variable declarations. The module correctly uses validation rules for service_config health check parameters (intervals, timeouts, thresholds) to enforce ALB constraints. File structure properly separates configuration into logical sections (main, data sources, locals, terraform config, variables).

apps/cms/src/api/about/services/about.ts (1)

1-7: LGTM!

This is idiomatic Strapi v5 boilerplate for a core service. The factory pattern and content-type UID (api::about.about) follow Strapi conventions correctly.

apps/cms/src/api/category/routes/category.ts (1)

1-7: LGTM!

Standard Strapi v5 core router using the factory pattern. The content-type UID and implementation are correct and consistent with other router files in the CMS app.

apps/cms/src/api/author/controllers/author.ts (1)

1-7: LGTM!

Standard Strapi v5 core controller using the factory pattern. This provides default CRUD operations for the author content-type.

apps/cms/src/api/category/controllers/category.ts (1)

1-7: LGTM!

Standard Strapi v5 core controller using the factory pattern. Consistent with the pattern used across all content-type controllers in this CMS app.

apps/cms/index.ts (1)

1-2: Entry point correctly implements Strapi pattern.

The CommonJS require with ESLint disable is the standard approach for Strapi v5 entry points. The build configuration correctly runs strapi build via package.json scripts, which produces the dist/server module referenced in the require statement. No changes needed.

apps/cms/src/api/article/routes/article.ts (1)

1-7: LGTM!

Standard Strapi v5 core router setup. The namespace api::article.article correctly aligns with the article content-type schema and related controller/service modules.

apps/cms/src/api/global/services/global.ts (1)

1-7: LGTM!

Standard Strapi v5 core service setup for the global API namespace.

apps/cms/src/api/global/controllers/global.ts (1)

1-7: LGTM!

Standard Strapi v5 core controller setup for the global API namespace.

apps/cms/src/api/author/routes/author.ts (1)

1-7: LGTM!

Standard Strapi v5 core router setup for the author API namespace.

apps/cms/src/api/article/services/article.ts (1)

1-7: LGTM!

Standard Strapi core service factory pattern with correct API UID.

apps/cms/src/api/category/services/category.ts (1)

1-7: LGTM!

Standard Strapi core service factory pattern with correct API UID.

apps/cms/src/api/author/services/author.ts (1)

1-7: LGTM!

Standard Strapi core service factory pattern with correct API UID.

apps/cms/src/index.ts (1)

1-20: LGTM!

Standard Strapi lifecycle hooks scaffolding. The commented-out type imports and parameters are conventional placeholders for future customization when register or bootstrap logic is needed.

apps/cms/src/api/global/content-types/global/schema.json (1)

1-35: LGTM for the overall schema structure.

The Global single-type is well-defined with appropriate required fields and disabled draft/publish for site-wide settings.

apps/cms/src/api/article/content-types/article/schema.json (1)

32-47: LGTM for relations and dynamic zone.

The manyToOne relations with inversedBy are correctly configured for bidirectional access, and the dynamic zone provides flexible content blocks.

apps/cms/infrastructure/variables.tf (1)

1-26: LGTM for the ecs_config variable structure.

The complex object type is well-defined with clear nested structures for VPC, ALB, and cluster configuration. The use of optional() for health_check_port provides flexibility.

infrastructure/environments/stage/main.tf (1)

157-170: LGTM for the CMS module configuration.

The module follows the established pattern for public-facing services with appropriate health check configuration (/_health on port 1337), Doppler integration for secrets properly fetched from SSM, and correct ALB wiring. The configuration aligns with existing modules like api-gateway-stage and arclight.

infrastructure/environments/prod/main.tf (1)

120-133: Approve the production CMS module configuration.

The module properly mirrors the stage environment with production-specific values and correctly references the Doppler token from the SSM parameter doppler_cms_prod_token defined in data.tf. The pattern is consistent with established conventions, and sensitive token handling follows best practices by using AWS Secrets Manager via SSM.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

- Added pnpm overrides for strapi-blurhash>canvas to version ^3.2.1 in package.json.
- Updated pnpm-lock.yaml to reflect the new dependency resolution for strapi-blurhash and canvas.
- Removed deprecated engine specifications from apps/cms/package.json.
@jesus-film-bot
Copy link

Ran Plan for dir: infrastructure workspace: default

Plan Failed: This project is currently locked by an unapplied plan from pull #6780. To continue, delete the lock from #6780 or apply that plan and merge the pull request.

Once the lock is released, comment atlantis plan here to re-plan.

@nx-cloud
Copy link

nx-cloud bot commented Jan 14, 2026

View your CI Pipeline Execution ↗ for commit 0abff07

Command Status Duration Result
nx run watch-e2e:e2e ✅ Succeeded 23s View ↗
nx run journeys-admin-e2e:e2e ✅ Succeeded 3m 18s View ↗
nx run docs-e2e:e2e ✅ Succeeded 3s View ↗
nx run journeys-e2e:e2e ✅ Succeeded 20s View ↗
nx run resources-e2e:e2e ✅ Succeeded 12s View ↗
nx run short-links-e2e:e2e ✅ Succeeded 3s View ↗
nx run videos-admin-e2e:e2e ✅ Succeeded 4s View ↗
nx run watch-modern-e2e:e2e ✅ Succeeded 4s View ↗
Additional runs (28) ✅ Succeeded ... View ↗

☁️ Nx Cloud last updated this comment at 2026-01-15 20:57:01 UTC

@github-actions
Copy link
Contributor

github-actions bot commented Jan 14, 2026

Warnings
⚠️ ❗ Big PR (12399 changes)

(change count - 12399): Pull Request size seems relatively large. If Pull Request contains multiple changes, split each into separate PR will helps faster, easier review.

Generated by 🚫 dangerJS against 0abff07

@github-actions github-actions bot temporarily deployed to Preview - watch-modern January 14, 2026 23:04 Inactive
@github-actions github-actions bot temporarily deployed to Preview - short-links January 14, 2026 23:04 Inactive
@github-actions github-actions bot temporarily deployed to Preview - videos-admin January 14, 2026 23:04 Inactive
@github-actions github-actions bot temporarily deployed to Preview - journeys-admin January 14, 2026 23:04 Inactive
@github-actions github-actions bot temporarily deployed to Preview - journeys January 14, 2026 23:04 Inactive
@github-actions github-actions bot temporarily deployed to Preview - resources January 14, 2026 23:04 Inactive
@github-actions
Copy link
Contributor

github-actions bot commented Jan 14, 2026

The latest updates on your projects.

Name Status Preview Updated (UTC)
docs ✅ Ready docs preview Fri Jan 16 09:48:16 NZDT 2026

@github-actions
Copy link
Contributor

github-actions bot commented Jan 14, 2026

The latest updates on your projects.

Name Status Preview Updated (UTC)
watch-modern ✅ Ready watch-modern preview Fri Jan 16 09:48:04 NZDT 2026

@github-actions github-actions bot temporarily deployed to Preview - resources January 15, 2026 02:34 Inactive
@github-actions github-actions bot temporarily deployed to Preview - videos-admin January 15, 2026 02:34 Inactive
@jesus-film-bot
Copy link

Ran Plan for dir: infrastructure workspace: default

Show Output
Note: Objects have changed outside of Terraform

Terraform detected the following changes made outside of Terraform since the
last "terraform apply" which may have affected this plan:

  # module.prod.module.postgresql.aws_rds_cluster.default has changed
~ resource "aws_rds_cluster" "default" {
      ~ engine_version                        = "13.18" -> "13.20"
      ~ engine_version_actual                 = "13.18" -> "13.20"
        id                                    = "jfp-core-prod"
        tags                                  = {}
        # (58 unchanged attributes hidden)

        # (1 unchanged block hidden)
    }

  # module.stage.module.postgresql.aws_rds_cluster.default has changed
~ resource "aws_rds_cluster" "default" {
      ~ engine_version                        = "13.18" -> "13.20"
      ~ engine_version_actual                 = "13.18" -> "13.20"
        id                                    = "jfp-core-stage"
        tags                                  = {}
        # (58 unchanged attributes hidden)

        # (1 unchanged block hidden)
    }


Unless you have made equivalent changes to your configuration, or ignored the
relevant attributes using ignore_changes, the following plan may include
actions to undo or respond to these changes.

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

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

Terraform will perform the following actions:

  # module.prod.module.cms.module.ecs-task.aws_alb_listener_rule.alb_listener_rule will be created
+ resource "aws_alb_listener_rule" "alb_listener_rule" {
      + arn          = (known after apply)
      + id           = (known after apply)
      + listener_arn = "arn:aws:elasticloadbalancing:us-east-2:410965620680:listener/app/jfp-public-alb-prod/7cf1f0916ed2c660/baff3356faf3dfae"
      + priority     = (known after apply)
      + region       = "us-east-2"
      + tags_all     = (known after apply)

      + action {
          + order            = (known after apply)
          + target_group_arn = (known after apply)
          + type             = "forward"
        }

      + condition {
          + host_header {
              + values = [
                  + "cms.jesusfilm.org",
                ]
            }
        }
    }

  # module.prod.module.cms.module.ecs-task.aws_alb_target_group.alb_target_group will be created
+ resource "aws_alb_target_group" "alb_target_group" {
      + arn                                = (known after apply)
      + arn_suffix                         = (known after apply)
      + connection_termination             = (known after apply)
      + deregistration_delay               = "300"
      + id                                 = (known after apply)
      + ip_address_type                    = (known after apply)
      + lambda_multi_value_headers_enabled = false
      + load_balancer_arns                 = (known after apply)
      + load_balancing_algorithm_type      = (known after apply)
      + load_balancing_anomaly_mitigation  = (known after apply)
      + load_balancing_cross_zone_enabled  = (known after apply)
      + name                               = "cms-prod-tg"
      + name_prefix                        = (known after apply)
      + port                               = 1337
      + preserve_client_ip                 = (known after apply)
      + protocol                           = "HTTP"
      + protocol_version                   = (known after apply)
      + proxy_protocol_v2                  = false
      + region                             = "us-east-2"
      + slow_start                         = 0
      + tags_all                           = (known after apply)
      + target_type                        = "ip"
      + vpc_id                             = "vpc-0b722b0a1f7789afd"

      + health_check {
          + enabled             = true
          + healthy_threshold   = 2
          + interval            = 10
          + matcher             = (known after apply)
          + path                = "/_health"
          + port                = "1337"
          + protocol            = "HTTP"
          + timeout             = 4
          + unhealthy_threshold = 4
        }

      + stickiness (known after apply)

      + target_failover (known after apply)

      + target_group_health (known after apply)

      + target_health_state (known after apply)
    }

  # module.prod.module.cms.module.ecs-task.aws_appautoscaling_policy.ecs_policy_cpu will be created
+ resource "aws_appautoscaling_policy" "ecs_policy_cpu" {
      + alarm_arns         = (known after apply)
      + arn                = (known after apply)
      + id                 = (known after apply)
      + name               = "jfp-cpu-autoscaling-prod"
      + policy_type        = "TargetTrackingScaling"
      + region             = "us-east-2"
      + resource_id        = "service/jfp-ecs-cluster-prod/cms-prod-service"
      + scalable_dimension = "ecs:service:DesiredCount"
      + service_namespace  = "ecs"

      + target_tracking_scaling_policy_configuration {
          + disable_scale_in = false
          + target_value     = 75

          + predefined_metric_specification {
              + predefined_metric_type = "ECSServiceAverageCPUUtilization"
            }
        }
    }

  # module.prod.module.cms.module.ecs-task.aws_appautoscaling_policy.ecs_policy_memory will be created
+ resource "aws_appautoscaling_policy" "ecs_policy_memory" {
      + alarm_arns         = (known after apply)
      + arn                = (known after apply)
      + id                 = (known after apply)
      + name               = "jfp-memory-autoscaling-prod"
      + policy_type        = "TargetTrackingScaling"
      + region             = "us-east-2"
      + resource_id        = "service/jfp-ecs-cluster-prod/cms-prod-service"
      + scalable_dimension = "ecs:service:DesiredCount"
      + service_namespace  = "ecs"

      + target_tracking_scaling_policy_configuration {
          + disable_scale_in = false
          + target_value     = 75

          + predefined_metric_specification {
              + predefined_metric_type = "ECSServiceAverageMemoryUtilization"
            }
        }
    }

  # module.prod.module.cms.module.ecs-task.aws_appautoscaling_target.service_autoscaling will be created
+ resource "aws_appautoscaling_target" "service_autoscaling" {
      + arn                = (known after apply)
      + id                 = (known after apply)
      + max_capacity       = 4
      + min_capacity       = 1
      + region             = "us-east-2"
      + resource_id        = "service/jfp-ecs-cluster-prod/cms-prod-service"
      + role_arn           = (known after apply)
      + scalable_dimension = "ecs:service:DesiredCount"
      + service_namespace  = "ecs"
      + tags_all           = (known after apply)

      + suspended_state (known after apply)
    }

  # module.prod.module.cms.module.ecs-task.aws_cloudwatch_log_group.ecs_cw_log_group will be created
+ resource "aws_cloudwatch_log_group" "ecs_cw_log_group" {
      + arn               = (known after apply)
      + id                = (known after apply)
      + log_group_class   = (known after apply)
      + name              = "cms-prod-logs"
      + name_prefix       = (known after apply)
      + region            = "us-east-2"
      + retention_in_days = 0
      + skip_destroy      = false
      + tags_all          = (known after apply)
    }

  # module.prod.module.cms.module.ecs-task.aws_ecr_lifecycle_policy.ecr_policy will be created
+ resource "aws_ecr_lifecycle_policy" "ecr_policy" {
      + id          = (known after apply)
      + policy      = jsonencode(
            {
              + rules = [
                  + {
                      + action       = {
                          + type = "expire"
                        }
                      + description  = "Expire more than 10 images"
                      + rulePriority = 1
                      + selection    = {
                          + countNumber = 10
                          + countType   = "imageCountMoreThan"
                          + tagStatus   = "any"
                        }
                    },
                ]
            }
        )
      + region      = "us-east-2"
      + registry_id = (known after apply)
      + repository  = "jfp-cms-prod"
    }

  # module.prod.module.cms.module.ecs-task.aws_ecr_repository.ecr_repository will be created
+ resource "aws_ecr_repository" "ecr_repository" {
      + arn                  = (known after apply)
      + id                   = (known after apply)
      + image_tag_mutability = "MUTABLE"
      + name                 = "jfp-cms-prod"
      + region               = "us-east-2"
      + registry_id          = (known after apply)
      + repository_url       = (known after apply)
      + tags_all             = (known after apply)
    }

  # module.prod.module.cms.module.ecs-task.aws_ecs_service.ecs_service will be created
+ resource "aws_ecs_service" "ecs_service" {
      + arn                                = (known after apply)
      + availability_zone_rebalancing      = "DISABLED"
      + cluster                            = "arn:aws:ecs:us-east-2:410965620680:cluster/jfp-ecs-cluster-prod"
      + deployment_maximum_percent         = 200
      + deployment_minimum_healthy_percent = 100
      + desired_count                      = 1
      + enable_ecs_managed_tags            = false
      + enable_execute_command             = true
      + iam_role                           = (known after apply)
      + id                                 = (known after apply)
      + launch_type                        = "FARGATE"
      + name                               = "cms-prod-service"
      + platform_version                   = (known after apply)
      + region                             = "us-east-2"
      + scheduling_strategy                = "REPLICA"
      + tags_all                           = (known after apply)
      + task_definition                    = (known after apply)
      + triggers                           = (known after apply)
      + wait_for_steady_state              = false

      + load_balancer {
          + container_name   = "jfp-cms-prod-app"
          + container_port   = 1337
          + target_group_arn = (known after apply)
            # (1 unchanged attribute hidden)
        }

      + network_configuration {
          + assign_public_ip = true
          + security_groups  = [
              + "sg-030c49feae781c660",
            ]
          + subnets          = [
              + "subnet-01aa708571a3e499c",
              + "subnet-0aa10af01283bbcdb",
              + "subnet-0b7c1e14af0ffb3ea",
            ]
        }
    }

  # module.prod.module.cms.module.ecs-task.aws_ecs_task_definition.ecs_task_definition will be created
+ resource "aws_ecs_task_definition" "ecs_task_definition" {
      + arn                      = (known after apply)
      + arn_without_revision     = (known after apply)
      + container_definitions    = (known after apply)
      + cpu                      = "1024"
      + enable_fault_injection   = (known after apply)
      + execution_role_arn       = "arn:aws:iam::410965620680:role/jfp-ecs-task-execution-role"
      + family                   = "jfp-cms-prod"
      + id                       = (known after apply)
      + memory                   = "2048"
      + network_mode             = "awsvpc"
      + region                   = "us-east-2"
      + requires_compatibilities = [
          + "FARGATE",
        ]
      + revision                 = (known after apply)
      + skip_destroy             = false
      + tags_all                 = (known after apply)
      + task_role_arn            = "arn:aws:iam::410965620680:role/terraform-ecs-task-role-prod"
      + track_latest             = false
    }

  # module.prod.module.cms.module.ecs-task.aws_route53_record.record will be created
+ resource "aws_route53_record" "record" {
      + allow_overwrite = (known after apply)
      + fqdn            = (known after apply)
      + id              = (known after apply)
      + name            = "cms"
      + records         = [
          + "jfp-public-alb-prod-13771523.us-east-2.elb.amazonaws.com",
        ]
      + ttl             = 300
      + type            = "CNAME"
      + zone_id         = "Z06687872LMUIKS0Y291P"
    }

  # module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["ADMIN_JWT_SECRET"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/prod/ADMIN_JWT_SECRET"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "ADMIN_JWT_SECRET"
        }
      + tags_all       = {
          + "name" = "ADMIN_JWT_SECRET"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["API_TOKEN_SALT"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/prod/API_TOKEN_SALT"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "API_TOKEN_SALT"
        }
      + tags_all       = {
          + "name" = "API_TOKEN_SALT"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["APP_KEYS"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/prod/APP_KEYS"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "APP_KEYS"
        }
      + tags_all       = {
          + "name" = "APP_KEYS"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["ENCRYPTION_KEY"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/prod/ENCRYPTION_KEY"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "ENCRYPTION_KEY"
        }
      + tags_all       = {
          + "name" = "ENCRYPTION_KEY"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_ACCESS_TOKEN_ID"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/prod/MUX_ACCESS_TOKEN_ID"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "MUX_ACCESS_TOKEN_ID"
        }
      + tags_all       = {
          + "name" = "MUX_ACCESS_TOKEN_ID"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_PLAYBACK_SIGNING_ID"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/prod/MUX_PLAYBACK_SIGNING_ID"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "MUX_PLAYBACK_SIGNING_ID"
        }
      + tags_all       = {
          + "name" = "MUX_PLAYBACK_SIGNING_ID"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_PLAYBACK_SIGNING_SECRET"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/prod/MUX_PLAYBACK_SIGNING_SECRET"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "MUX_PLAYBACK_SIGNING_SECRET"
        }
      + tags_all       = {
          + "name" = "MUX_PLAYBACK_SIGNING_SECRET"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_SECRET_KEY"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/prod/MUX_SECRET_KEY"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "MUX_SECRET_KEY"
        }
      + tags_all       = {
          + "name" = "MUX_SECRET_KEY"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_WEBHOOK_SIGNING_SECRET"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/prod/MUX_WEBHOOK_SIGNING_SECRET"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "MUX_WEBHOOK_SIGNING_SECRET"
        }
      + tags_all       = {
          + "name" = "MUX_WEBHOOK_SIGNING_SECRET"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["PG_DATABASE_URL_CMS"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/prod/PG_DATABASE_URL_CMS"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "PG_DATABASE_URL_CMS"
        }
      + tags_all       = {
          + "name" = "PG_DATABASE_URL_CMS"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["TRANSFER_TOKEN_SALT"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/prod/TRANSFER_TOKEN_SALT"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "TRANSFER_TOKEN_SALT"
        }
      + tags_all       = {
          + "name" = "TRANSFER_TOKEN_SALT"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.stage.module.arclight.module.ecs-task.aws_ecs_service.ecs_service will be updated in-place
~ resource "aws_ecs_service" "ecs_service" {
      ~ desired_count                      = 1 -> 4
        id                                 = "arn:aws:ecs:us-east-2:410965620680:service/jfp-ecs-cluster-stage/arclight-stage-service"
        name                               = "arclight-stage-service"
        tags                               = {}
        # (18 unchanged attributes hidden)

        # (4 unchanged blocks hidden)
    }

  # module.stage.module.cms.module.ecs-task.aws_alb_listener_rule.alb_listener_rule will be created
+ resource "aws_alb_listener_rule" "alb_listener_rule" {
      + arn          = (known after apply)
      + id           = (known after apply)
      + listener_arn = "arn:aws:elasticloadbalancing:us-east-2:410965620680:listener/app/jfp-public-alb-stage/27d94355c709eb16/e976ba0cdd6d17a6"
      + priority     = (known after apply)
      + region       = "us-east-2"
      + tags_all     = (known after apply)

      + action {
          + order            = (known after apply)
          + target_group_arn = (known after apply)
          + type             = "forward"
        }

      + condition {
          + host_header {
              + values = [
                  + "cms-stage.jesusfilm.org",
                ]
            }
        }
    }

  # module.stage.module.cms.module.ecs-task.aws_alb_target_group.alb_target_group will be created
+ resource "aws_alb_target_group" "alb_target_group" {
      + arn                                = (known after apply)
      + arn_suffix                         = (known after apply)
      + connection_termination             = (known after apply)
      + deregistration_delay               = "300"
      + id                                 = (known after apply)
      + ip_address_type                    = (known after apply)
      + lambda_multi_value_headers_enabled = false
      + load_balancer_arns                 = (known after apply)
      + load_balancing_algorithm_type      = (known after apply)
      + load_balancing_anomaly_mitigation  = (known after apply)
      + load_balancing_cross_zone_enabled  = (known after apply)
      + name                               = "cms-stage-tg"
      + name_prefix                        = (known after apply)
      + port                               = 1337
      + preserve_client_ip                 = (known after apply)
      + protocol                           = "HTTP"
      + protocol_version                   = (known after apply)
      + proxy_protocol_v2                  = false
      + region                             = "us-east-2"
      + slow_start                         = 0
      + tags_all                           = (known after apply)
      + target_type                        = "ip"
      + vpc_id                             = "vpc-08eeff0fe23f23079"

      + health_check {
          + enabled             = true
          + healthy_threshold   = 2
          + interval            = 10
          + matcher             = (known after apply)
          + path                = "/_health"
          + port                = "1337"
          + protocol            = "HTTP"
          + timeout             = 4
          + unhealthy_threshold = 4
        }

      + stickiness (known after apply)

      + target_failover (known after apply)

      + target_group_health (known after apply)

      + target_health_state (known after apply)
    }

  # module.stage.module.cms.module.ecs-task.aws_appautoscaling_policy.ecs_policy_cpu will be created
+ resource "aws_appautoscaling_policy" "ecs_policy_cpu" {
      + alarm_arns         = (known after apply)
      + arn                = (known after apply)
      + id                 = (known after apply)
      + name               = "jfp-cpu-autoscaling-stage"
      + policy_type        = "TargetTrackingScaling"
      + region             = "us-east-2"
      + resource_id        = "service/jfp-ecs-cluster-stage/cms-stage-service"
      + scalable_dimension = "ecs:service:DesiredCount"
      + service_namespace  = "ecs"

      + target_tracking_scaling_policy_configuration {
          + disable_scale_in = false
          + target_value     = 75

          + predefined_metric_specification {
              + predefined_metric_type = "ECSServiceAverageCPUUtilization"
            }
        }
    }

  # module.stage.module.cms.module.ecs-task.aws_appautoscaling_policy.ecs_policy_memory will be created
+ resource "aws_appautoscaling_policy" "ecs_policy_memory" {
      + alarm_arns         = (known after apply)
      + arn                = (known after apply)
      + id                 = (known after apply)
      + name               = "jfp-memory-autoscaling-stage"
      + policy_type        = "TargetTrackingScaling"
      + region             = "us-east-2"
      + resource_id        = "service/jfp-ecs-cluster-stage/cms-stage-service"
      + scalable_dimension = "ecs:service:DesiredCount"
      + service_namespace  = "ecs"

      + target_tracking_scaling_policy_configuration {
          + disable_scale_in = false
          + target_value     = 75

          + predefined_metric_specification {
              + predefined_metric_type = "ECSServiceAverageMemoryUtilization"
            }
        }
    }

  # module.stage.module.cms.module.ecs-task.aws_appautoscaling_target.service_autoscaling will be created
+ resource "aws_appautoscaling_target" "service_autoscaling" {
      + arn                = (known after apply)
      + id                 = (known after apply)
      + max_capacity       = 4
      + min_capacity       = 1
      + region             = "us-east-2"
      + resource_id        = "service/jfp-ecs-cluster-stage/cms-stage-service"
      + role_arn           = (known after apply)
      + scalable_dimension = "ecs:service:DesiredCount"
      + service_namespace  = "ecs"
      + tags_all           = (known after apply)

      + suspended_state (known after apply)
    }

  # module.stage.module.cms.module.ecs-task.aws_cloudwatch_log_group.ecs_cw_log_group will be created
+ resource "aws_cloudwatch_log_group" "ecs_cw_log_group" {
      + arn               = (known after apply)
      + id                = (known after apply)
      + log_group_class   = (known after apply)
      + name              = "cms-stage-logs"
      + name_prefix       = (known after apply)
      + region            = "us-east-2"
      + retention_in_days = 0
      + skip_destroy      = false
      + tags_all          = (known after apply)
    }

  # module.stage.module.cms.module.ecs-task.aws_ecr_lifecycle_policy.ecr_policy will be created
+ resource "aws_ecr_lifecycle_policy" "ecr_policy" {
      + id          = (known after apply)
      + policy      = jsonencode(
            {
              + rules = [
                  + {
                      + action       = {
                          + type = "expire"
                        }
                      + description  = "Expire more than 10 images"
                      + rulePriority = 1
                      + selection    = {
                          + countNumber = 10
                          + countType   = "imageCountMoreThan"
                          + tagStatus   = "any"
                        }
                    },
                ]
            }
        )
      + region      = "us-east-2"
      + registry_id = (known after apply)
      + repository  = "jfp-cms-stage"
    }

  # module.stage.module.cms.module.ecs-task.aws_ecr_repository.ecr_repository will be created
+ resource "aws_ecr_repository" "ecr_repository" {
      + arn                  = (known after apply)
      + id                   = (known after apply)
      + image_tag_mutability = "MUTABLE"
      + name                 = "jfp-cms-stage"
      + region               = "us-east-2"
      + registry_id          = (known after apply)
      + repository_url       = (known after apply)
      + tags_all             = (known after apply)
    }

  # module.stage.module.cms.module.ecs-task.aws_ecs_service.ecs_service will be created
+ resource "aws_ecs_service" "ecs_service" {
      + arn                                = (known after apply)
      + availability_zone_rebalancing      = "DISABLED"
      + cluster                            = "arn:aws:ecs:us-east-2:410965620680:cluster/jfp-ecs-cluster-stage"
      + deployment_maximum_percent         = 200
      + deployment_minimum_healthy_percent = 100
      + desired_count                      = 1
      + enable_ecs_managed_tags            = false
      + enable_execute_command             = true
      + iam_role                           = (known after apply)
      + id                                 = (known after apply)
      + launch_type                        = "FARGATE"
      + name                               = "cms-stage-service"
      + platform_version                   = (known after apply)
      + region                             = "us-east-2"
      + scheduling_strategy                = "REPLICA"
      + tags_all                           = (known after apply)
      + task_definition                    = (known after apply)
      + triggers                           = (known after apply)
      + wait_for_steady_state              = false

      + load_balancer {
          + container_name   = "jfp-cms-stage-app"
          + container_port   = 1337
          + target_group_arn = (known after apply)
            # (1 unchanged attribute hidden)
        }

      + network_configuration {
          + assign_public_ip = true
          + security_groups  = [
              + "sg-0715e664d653ce89c",
            ]
          + subnets          = [
              + "subnet-03bd7850c8bbe2ce9",
              + "subnet-0a609b33cdac65789",
              + "subnet-0c394639d255c3261",
            ]
        }
    }

  # module.stage.module.cms.module.ecs-task.aws_ecs_task_definition.ecs_task_definition will be created
+ resource "aws_ecs_task_definition" "ecs_task_definition" {
      + arn                      = (known after apply)
      + arn_without_revision     = (known after apply)
      + container_definitions    = (known after apply)
      + cpu                      = "1024"
      + enable_fault_injection   = (known after apply)
      + execution_role_arn       = "arn:aws:iam::410965620680:role/jfp-ecs-task-execution-role"
      + family                   = "jfp-cms-stage"
      + id                       = (known after apply)
      + memory                   = "2048"
      + network_mode             = "awsvpc"
      + region                   = "us-east-2"
      + requires_compatibilities = [
          + "FARGATE",
        ]
      + revision                 = (known after apply)
      + skip_destroy             = false
      + tags_all                 = (known after apply)
      + task_role_arn            = "arn:aws:iam::410965620680:role/terraform-ecs-task-role-stage"
      + track_latest             = false
    }

  # module.stage.module.cms.module.ecs-task.aws_route53_record.record will be created
+ resource "aws_route53_record" "record" {
      + allow_overwrite = (known after apply)
      + fqdn            = (known after apply)
      + id              = (known after apply)
      + name            = "cms"
      + records         = [
          + "jfp-public-alb-stage-1845039612.us-east-2.elb.amazonaws.com",
        ]
      + ttl             = 300
      + type            = "CNAME"
      + zone_id         = "Z09188583TUYV562FI49B"
    }

  # module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["ADMIN_JWT_SECRET"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/stage/ADMIN_JWT_SECRET"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "ADMIN_JWT_SECRET"
        }
      + tags_all       = {
          + "name" = "ADMIN_JWT_SECRET"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["API_TOKEN_SALT"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/stage/API_TOKEN_SALT"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "API_TOKEN_SALT"
        }
      + tags_all       = {
          + "name" = "API_TOKEN_SALT"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["APP_KEYS"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/stage/APP_KEYS"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "APP_KEYS"
        }
      + tags_all       = {
          + "name" = "APP_KEYS"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["ENCRYPTION_KEY"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/stage/ENCRYPTION_KEY"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "ENCRYPTION_KEY"
        }
      + tags_all       = {
          + "name" = "ENCRYPTION_KEY"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_ACCESS_TOKEN_ID"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/stage/MUX_ACCESS_TOKEN_ID"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "MUX_ACCESS_TOKEN_ID"
        }
      + tags_all       = {
          + "name" = "MUX_ACCESS_TOKEN_ID"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_PLAYBACK_SIGNING_ID"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/stage/MUX_PLAYBACK_SIGNING_ID"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "MUX_PLAYBACK_SIGNING_ID"
        }
      + tags_all       = {
          + "name" = "MUX_PLAYBACK_SIGNING_ID"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_PLAYBACK_SIGNING_SECRET"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/stage/MUX_PLAYBACK_SIGNING_SECRET"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "MUX_PLAYBACK_SIGNING_SECRET"
        }
      + tags_all       = {
          + "name" = "MUX_PLAYBACK_SIGNING_SECRET"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_SECRET_KEY"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/stage/MUX_SECRET_KEY"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "MUX_SECRET_KEY"
        }
      + tags_all       = {
          + "name" = "MUX_SECRET_KEY"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_WEBHOOK_SIGNING_SECRET"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/stage/MUX_WEBHOOK_SIGNING_SECRET"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "MUX_WEBHOOK_SIGNING_SECRET"
        }
      + tags_all       = {
          + "name" = "MUX_WEBHOOK_SIGNING_SECRET"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["PG_DATABASE_URL_CMS"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/stage/PG_DATABASE_URL_CMS"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "PG_DATABASE_URL_CMS"
        }
      + tags_all       = {
          + "name" = "PG_DATABASE_URL_CMS"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["TRANSFER_TOKEN_SALT"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/stage/TRANSFER_TOKEN_SALT"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "TRANSFER_TOKEN_SALT"
        }
      + tags_all       = {
          + "name" = "TRANSFER_TOKEN_SALT"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

Plan: 44 to add, 1 to change, 0 to destroy.
╷
│ Warning: Deprecated Resource
│ 
│   with module.datadog.datadog_integration_aws.sandbox,
│   on modules/aws/datadog/main.tf line 118, in resource "datadog_integration_aws" "sandbox":
│  118: resource "datadog_integration_aws" "sandbox" {
│ 
│ **This resource is deprecated - use the `datadog_integration_aws_account`
│ resource instead**:
│ https://registry.terraform.io/providers/DataDog/datadog/latest/docs/resources/integration_aws_account
╵
╷
│ Warning: Deprecated attribute
│ 
│   on .terraform/modules/datadog.datadog_log_forwarder/modules/log_forwarder/main.tf line 2, in locals:
│    2:   bucket_name = var.bucket_name != "" ? var.bucket_name : "datadog-forwarder-${data.aws_caller_identity.current.account_id}-${data.aws_region.current.name}"
│ 
│ The attribute "name" is deprecated. Refer to the provider documentation for
│ details.
│ 
│ (and 2 more similar warnings elsewhere)
╵
  • ▶️ To apply this plan, comment:
    atlantis apply -d infrastructure
  • 🚮 To delete this plan and lock, click here
  • 🔁 To plan this project again, comment:
    atlantis plan -d infrastructure

Note: Objects have changed outside of Terraform
Plan: 44 to add, 1 to change, 0 to destroy.


  • ⏩ To apply all unapplied plans from this Pull Request, comment:
    atlantis apply
  • 🚮 To delete all plans and locks from this Pull Request, comment:
    atlantis unlock

mikeallisonJS
mikeallisonJS previously approved these changes Jan 15, 2026
- Updated the cookie secret retrieval in initAuth.ts to use non-null assertions for COOKIE_SECRET_CURRENT and COOKIE_SECRET_PREVIOUS, ensuring that these values are always defined.
@jesus-film-bot
Copy link

Ran Plan for dir: infrastructure workspace: default

Show Output
Note: Objects have changed outside of Terraform

Terraform detected the following changes made outside of Terraform since the
last "terraform apply" which may have affected this plan:

  # module.prod.module.postgresql.aws_rds_cluster.default has changed
~ resource "aws_rds_cluster" "default" {
      ~ engine_version                        = "13.18" -> "13.20"
      ~ engine_version_actual                 = "13.18" -> "13.20"
        id                                    = "jfp-core-prod"
        tags                                  = {}
        # (58 unchanged attributes hidden)

        # (1 unchanged block hidden)
    }

  # module.stage.module.postgresql.aws_rds_cluster.default has changed
~ resource "aws_rds_cluster" "default" {
      ~ engine_version                        = "13.18" -> "13.20"
      ~ engine_version_actual                 = "13.18" -> "13.20"
        id                                    = "jfp-core-stage"
        tags                                  = {}
        # (58 unchanged attributes hidden)

        # (1 unchanged block hidden)
    }


Unless you have made equivalent changes to your configuration, or ignored the
relevant attributes using ignore_changes, the following plan may include
actions to undo or respond to these changes.

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

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

Terraform will perform the following actions:

  # module.prod.module.cms.module.ecs-task.aws_alb_listener_rule.alb_listener_rule will be created
+ resource "aws_alb_listener_rule" "alb_listener_rule" {
      + arn          = (known after apply)
      + id           = (known after apply)
      + listener_arn = "arn:aws:elasticloadbalancing:us-east-2:410965620680:listener/app/jfp-public-alb-prod/7cf1f0916ed2c660/baff3356faf3dfae"
      + priority     = (known after apply)
      + region       = "us-east-2"
      + tags_all     = (known after apply)

      + action {
          + order            = (known after apply)
          + target_group_arn = (known after apply)
          + type             = "forward"
        }

      + condition {
          + host_header {
              + values = [
                  + "cms.jesusfilm.org",
                ]
            }
        }
    }

  # module.prod.module.cms.module.ecs-task.aws_alb_target_group.alb_target_group will be created
+ resource "aws_alb_target_group" "alb_target_group" {
      + arn                                = (known after apply)
      + arn_suffix                         = (known after apply)
      + connection_termination             = (known after apply)
      + deregistration_delay               = "300"
      + id                                 = (known after apply)
      + ip_address_type                    = (known after apply)
      + lambda_multi_value_headers_enabled = false
      + load_balancer_arns                 = (known after apply)
      + load_balancing_algorithm_type      = (known after apply)
      + load_balancing_anomaly_mitigation  = (known after apply)
      + load_balancing_cross_zone_enabled  = (known after apply)
      + name                               = "cms-prod-tg"
      + name_prefix                        = (known after apply)
      + port                               = 1337
      + preserve_client_ip                 = (known after apply)
      + protocol                           = "HTTP"
      + protocol_version                   = (known after apply)
      + proxy_protocol_v2                  = false
      + region                             = "us-east-2"
      + slow_start                         = 0
      + tags_all                           = (known after apply)
      + target_type                        = "ip"
      + vpc_id                             = "vpc-0b722b0a1f7789afd"

      + health_check {
          + enabled             = true
          + healthy_threshold   = 2
          + interval            = 10
          + matcher             = (known after apply)
          + path                = "/_health"
          + port                = "1337"
          + protocol            = "HTTP"
          + timeout             = 4
          + unhealthy_threshold = 4
        }

      + stickiness (known after apply)

      + target_failover (known after apply)

      + target_group_health (known after apply)

      + target_health_state (known after apply)
    }

  # module.prod.module.cms.module.ecs-task.aws_appautoscaling_policy.ecs_policy_cpu will be created
+ resource "aws_appautoscaling_policy" "ecs_policy_cpu" {
      + alarm_arns         = (known after apply)
      + arn                = (known after apply)
      + id                 = (known after apply)
      + name               = "jfp-cpu-autoscaling-prod"
      + policy_type        = "TargetTrackingScaling"
      + region             = "us-east-2"
      + resource_id        = "service/jfp-ecs-cluster-prod/cms-prod-service"
      + scalable_dimension = "ecs:service:DesiredCount"
      + service_namespace  = "ecs"

      + target_tracking_scaling_policy_configuration {
          + disable_scale_in = false
          + target_value     = 75

          + predefined_metric_specification {
              + predefined_metric_type = "ECSServiceAverageCPUUtilization"
            }
        }
    }

  # module.prod.module.cms.module.ecs-task.aws_appautoscaling_policy.ecs_policy_memory will be created
+ resource "aws_appautoscaling_policy" "ecs_policy_memory" {
      + alarm_arns         = (known after apply)
      + arn                = (known after apply)
      + id                 = (known after apply)
      + name               = "jfp-memory-autoscaling-prod"
      + policy_type        = "TargetTrackingScaling"
      + region             = "us-east-2"
      + resource_id        = "service/jfp-ecs-cluster-prod/cms-prod-service"
      + scalable_dimension = "ecs:service:DesiredCount"
      + service_namespace  = "ecs"

      + target_tracking_scaling_policy_configuration {
          + disable_scale_in = false
          + target_value     = 75

          + predefined_metric_specification {
              + predefined_metric_type = "ECSServiceAverageMemoryUtilization"
            }
        }
    }

  # module.prod.module.cms.module.ecs-task.aws_appautoscaling_target.service_autoscaling will be created
+ resource "aws_appautoscaling_target" "service_autoscaling" {
      + arn                = (known after apply)
      + id                 = (known after apply)
      + max_capacity       = 4
      + min_capacity       = 1
      + region             = "us-east-2"
      + resource_id        = "service/jfp-ecs-cluster-prod/cms-prod-service"
      + role_arn           = (known after apply)
      + scalable_dimension = "ecs:service:DesiredCount"
      + service_namespace  = "ecs"
      + tags_all           = (known after apply)

      + suspended_state (known after apply)
    }

  # module.prod.module.cms.module.ecs-task.aws_cloudwatch_log_group.ecs_cw_log_group will be created
+ resource "aws_cloudwatch_log_group" "ecs_cw_log_group" {
      + arn               = (known after apply)
      + id                = (known after apply)
      + log_group_class   = (known after apply)
      + name              = "cms-prod-logs"
      + name_prefix       = (known after apply)
      + region            = "us-east-2"
      + retention_in_days = 0
      + skip_destroy      = false
      + tags_all          = (known after apply)
    }

  # module.prod.module.cms.module.ecs-task.aws_ecr_lifecycle_policy.ecr_policy will be created
+ resource "aws_ecr_lifecycle_policy" "ecr_policy" {
      + id          = (known after apply)
      + policy      = jsonencode(
            {
              + rules = [
                  + {
                      + action       = {
                          + type = "expire"
                        }
                      + description  = "Expire more than 10 images"
                      + rulePriority = 1
                      + selection    = {
                          + countNumber = 10
                          + countType   = "imageCountMoreThan"
                          + tagStatus   = "any"
                        }
                    },
                ]
            }
        )
      + region      = "us-east-2"
      + registry_id = (known after apply)
      + repository  = "jfp-cms-prod"
    }

  # module.prod.module.cms.module.ecs-task.aws_ecr_repository.ecr_repository will be created
+ resource "aws_ecr_repository" "ecr_repository" {
      + arn                  = (known after apply)
      + id                   = (known after apply)
      + image_tag_mutability = "MUTABLE"
      + name                 = "jfp-cms-prod"
      + region               = "us-east-2"
      + registry_id          = (known after apply)
      + repository_url       = (known after apply)
      + tags_all             = (known after apply)
    }

  # module.prod.module.cms.module.ecs-task.aws_ecs_service.ecs_service will be created
+ resource "aws_ecs_service" "ecs_service" {
      + arn                                = (known after apply)
      + availability_zone_rebalancing      = "DISABLED"
      + cluster                            = "arn:aws:ecs:us-east-2:410965620680:cluster/jfp-ecs-cluster-prod"
      + deployment_maximum_percent         = 200
      + deployment_minimum_healthy_percent = 100
      + desired_count                      = 1
      + enable_ecs_managed_tags            = false
      + enable_execute_command             = true
      + iam_role                           = (known after apply)
      + id                                 = (known after apply)
      + launch_type                        = "FARGATE"
      + name                               = "cms-prod-service"
      + platform_version                   = (known after apply)
      + region                             = "us-east-2"
      + scheduling_strategy                = "REPLICA"
      + tags_all                           = (known after apply)
      + task_definition                    = (known after apply)
      + triggers                           = (known after apply)
      + wait_for_steady_state              = false

      + load_balancer {
          + container_name   = "jfp-cms-prod-app"
          + container_port   = 1337
          + target_group_arn = (known after apply)
            # (1 unchanged attribute hidden)
        }

      + network_configuration {
          + assign_public_ip = true
          + security_groups  = [
              + "sg-030c49feae781c660",
            ]
          + subnets          = [
              + "subnet-01aa708571a3e499c",
              + "subnet-0aa10af01283bbcdb",
              + "subnet-0b7c1e14af0ffb3ea",
            ]
        }
    }

  # module.prod.module.cms.module.ecs-task.aws_ecs_task_definition.ecs_task_definition will be created
+ resource "aws_ecs_task_definition" "ecs_task_definition" {
      + arn                      = (known after apply)
      + arn_without_revision     = (known after apply)
      + container_definitions    = (known after apply)
      + cpu                      = "1024"
      + enable_fault_injection   = (known after apply)
      + execution_role_arn       = "arn:aws:iam::410965620680:role/jfp-ecs-task-execution-role"
      + family                   = "jfp-cms-prod"
      + id                       = (known after apply)
      + memory                   = "2048"
      + network_mode             = "awsvpc"
      + region                   = "us-east-2"
      + requires_compatibilities = [
          + "FARGATE",
        ]
      + revision                 = (known after apply)
      + skip_destroy             = false
      + tags_all                 = (known after apply)
      + task_role_arn            = "arn:aws:iam::410965620680:role/terraform-ecs-task-role-prod"
      + track_latest             = false
    }

  # module.prod.module.cms.module.ecs-task.aws_route53_record.record will be created
+ resource "aws_route53_record" "record" {
      + allow_overwrite = (known after apply)
      + fqdn            = (known after apply)
      + id              = (known after apply)
      + name            = "cms"
      + records         = [
          + "jfp-public-alb-prod-13771523.us-east-2.elb.amazonaws.com",
        ]
      + ttl             = 300
      + type            = "CNAME"
      + zone_id         = "Z06687872LMUIKS0Y291P"
    }

  # module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["ADMIN_JWT_SECRET"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/prod/ADMIN_JWT_SECRET"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "ADMIN_JWT_SECRET"
        }
      + tags_all       = {
          + "name" = "ADMIN_JWT_SECRET"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["API_TOKEN_SALT"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/prod/API_TOKEN_SALT"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "API_TOKEN_SALT"
        }
      + tags_all       = {
          + "name" = "API_TOKEN_SALT"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["APP_KEYS"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/prod/APP_KEYS"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "APP_KEYS"
        }
      + tags_all       = {
          + "name" = "APP_KEYS"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["ENCRYPTION_KEY"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/prod/ENCRYPTION_KEY"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "ENCRYPTION_KEY"
        }
      + tags_all       = {
          + "name" = "ENCRYPTION_KEY"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_ACCESS_TOKEN_ID"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/prod/MUX_ACCESS_TOKEN_ID"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "MUX_ACCESS_TOKEN_ID"
        }
      + tags_all       = {
          + "name" = "MUX_ACCESS_TOKEN_ID"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_PLAYBACK_SIGNING_ID"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/prod/MUX_PLAYBACK_SIGNING_ID"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "MUX_PLAYBACK_SIGNING_ID"
        }
      + tags_all       = {
          + "name" = "MUX_PLAYBACK_SIGNING_ID"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_PLAYBACK_SIGNING_SECRET"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/prod/MUX_PLAYBACK_SIGNING_SECRET"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "MUX_PLAYBACK_SIGNING_SECRET"
        }
      + tags_all       = {
          + "name" = "MUX_PLAYBACK_SIGNING_SECRET"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_SECRET_KEY"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/prod/MUX_SECRET_KEY"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "MUX_SECRET_KEY"
        }
      + tags_all       = {
          + "name" = "MUX_SECRET_KEY"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_WEBHOOK_SIGNING_SECRET"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/prod/MUX_WEBHOOK_SIGNING_SECRET"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "MUX_WEBHOOK_SIGNING_SECRET"
        }
      + tags_all       = {
          + "name" = "MUX_WEBHOOK_SIGNING_SECRET"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["PG_DATABASE_URL_CMS"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/prod/PG_DATABASE_URL_CMS"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "PG_DATABASE_URL_CMS"
        }
      + tags_all       = {
          + "name" = "PG_DATABASE_URL_CMS"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["TRANSFER_TOKEN_SALT"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/prod/TRANSFER_TOKEN_SALT"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "TRANSFER_TOKEN_SALT"
        }
      + tags_all       = {
          + "name" = "TRANSFER_TOKEN_SALT"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.stage.module.arclight.module.ecs-task.aws_ecs_service.ecs_service will be updated in-place
~ resource "aws_ecs_service" "ecs_service" {
      ~ desired_count                      = 1 -> 4
        id                                 = "arn:aws:ecs:us-east-2:410965620680:service/jfp-ecs-cluster-stage/arclight-stage-service"
        name                               = "arclight-stage-service"
        tags                               = {}
        # (18 unchanged attributes hidden)

        # (4 unchanged blocks hidden)
    }

  # module.stage.module.cms.module.ecs-task.aws_alb_listener_rule.alb_listener_rule will be created
+ resource "aws_alb_listener_rule" "alb_listener_rule" {
      + arn          = (known after apply)
      + id           = (known after apply)
      + listener_arn = "arn:aws:elasticloadbalancing:us-east-2:410965620680:listener/app/jfp-public-alb-stage/27d94355c709eb16/e976ba0cdd6d17a6"
      + priority     = (known after apply)
      + region       = "us-east-2"
      + tags_all     = (known after apply)

      + action {
          + order            = (known after apply)
          + target_group_arn = (known after apply)
          + type             = "forward"
        }

      + condition {
          + host_header {
              + values = [
                  + "cms-stage.jesusfilm.org",
                ]
            }
        }
    }

  # module.stage.module.cms.module.ecs-task.aws_alb_target_group.alb_target_group will be created
+ resource "aws_alb_target_group" "alb_target_group" {
      + arn                                = (known after apply)
      + arn_suffix                         = (known after apply)
      + connection_termination             = (known after apply)
      + deregistration_delay               = "300"
      + id                                 = (known after apply)
      + ip_address_type                    = (known after apply)
      + lambda_multi_value_headers_enabled = false
      + load_balancer_arns                 = (known after apply)
      + load_balancing_algorithm_type      = (known after apply)
      + load_balancing_anomaly_mitigation  = (known after apply)
      + load_balancing_cross_zone_enabled  = (known after apply)
      + name                               = "cms-stage-tg"
      + name_prefix                        = (known after apply)
      + port                               = 1337
      + preserve_client_ip                 = (known after apply)
      + protocol                           = "HTTP"
      + protocol_version                   = (known after apply)
      + proxy_protocol_v2                  = false
      + region                             = "us-east-2"
      + slow_start                         = 0
      + tags_all                           = (known after apply)
      + target_type                        = "ip"
      + vpc_id                             = "vpc-08eeff0fe23f23079"

      + health_check {
          + enabled             = true
          + healthy_threshold   = 2
          + interval            = 10
          + matcher             = (known after apply)
          + path                = "/_health"
          + port                = "1337"
          + protocol            = "HTTP"
          + timeout             = 4
          + unhealthy_threshold = 4
        }

      + stickiness (known after apply)

      + target_failover (known after apply)

      + target_group_health (known after apply)

      + target_health_state (known after apply)
    }

  # module.stage.module.cms.module.ecs-task.aws_appautoscaling_policy.ecs_policy_cpu will be created
+ resource "aws_appautoscaling_policy" "ecs_policy_cpu" {
      + alarm_arns         = (known after apply)
      + arn                = (known after apply)
      + id                 = (known after apply)
      + name               = "jfp-cpu-autoscaling-stage"
      + policy_type        = "TargetTrackingScaling"
      + region             = "us-east-2"
      + resource_id        = "service/jfp-ecs-cluster-stage/cms-stage-service"
      + scalable_dimension = "ecs:service:DesiredCount"
      + service_namespace  = "ecs"

      + target_tracking_scaling_policy_configuration {
          + disable_scale_in = false
          + target_value     = 75

          + predefined_metric_specification {
              + predefined_metric_type = "ECSServiceAverageCPUUtilization"
            }
        }
    }

  # module.stage.module.cms.module.ecs-task.aws_appautoscaling_policy.ecs_policy_memory will be created
+ resource "aws_appautoscaling_policy" "ecs_policy_memory" {
      + alarm_arns         = (known after apply)
      + arn                = (known after apply)
      + id                 = (known after apply)
      + name               = "jfp-memory-autoscaling-stage"
      + policy_type        = "TargetTrackingScaling"
      + region             = "us-east-2"
      + resource_id        = "service/jfp-ecs-cluster-stage/cms-stage-service"
      + scalable_dimension = "ecs:service:DesiredCount"
      + service_namespace  = "ecs"

      + target_tracking_scaling_policy_configuration {
          + disable_scale_in = false
          + target_value     = 75

          + predefined_metric_specification {
              + predefined_metric_type = "ECSServiceAverageMemoryUtilization"
            }
        }
    }

  # module.stage.module.cms.module.ecs-task.aws_appautoscaling_target.service_autoscaling will be created
+ resource "aws_appautoscaling_target" "service_autoscaling" {
      + arn                = (known after apply)
      + id                 = (known after apply)
      + max_capacity       = 4
      + min_capacity       = 1
      + region             = "us-east-2"
      + resource_id        = "service/jfp-ecs-cluster-stage/cms-stage-service"
      + role_arn           = (known after apply)
      + scalable_dimension = "ecs:service:DesiredCount"
      + service_namespace  = "ecs"
      + tags_all           = (known after apply)

      + suspended_state (known after apply)
    }

  # module.stage.module.cms.module.ecs-task.aws_cloudwatch_log_group.ecs_cw_log_group will be created
+ resource "aws_cloudwatch_log_group" "ecs_cw_log_group" {
      + arn               = (known after apply)
      + id                = (known after apply)
      + log_group_class   = (known after apply)
      + name              = "cms-stage-logs"
      + name_prefix       = (known after apply)
      + region            = "us-east-2"
      + retention_in_days = 0
      + skip_destroy      = false
      + tags_all          = (known after apply)
    }

  # module.stage.module.cms.module.ecs-task.aws_ecr_lifecycle_policy.ecr_policy will be created
+ resource "aws_ecr_lifecycle_policy" "ecr_policy" {
      + id          = (known after apply)
      + policy      = jsonencode(
            {
              + rules = [
                  + {
                      + action       = {
                          + type = "expire"
                        }
                      + description  = "Expire more than 10 images"
                      + rulePriority = 1
                      + selection    = {
                          + countNumber = 10
                          + countType   = "imageCountMoreThan"
                          + tagStatus   = "any"
                        }
                    },
                ]
            }
        )
      + region      = "us-east-2"
      + registry_id = (known after apply)
      + repository  = "jfp-cms-stage"
    }

  # module.stage.module.cms.module.ecs-task.aws_ecr_repository.ecr_repository will be created
+ resource "aws_ecr_repository" "ecr_repository" {
      + arn                  = (known after apply)
      + id                   = (known after apply)
      + image_tag_mutability = "MUTABLE"
      + name                 = "jfp-cms-stage"
      + region               = "us-east-2"
      + registry_id          = (known after apply)
      + repository_url       = (known after apply)
      + tags_all             = (known after apply)
    }

  # module.stage.module.cms.module.ecs-task.aws_ecs_service.ecs_service will be created
+ resource "aws_ecs_service" "ecs_service" {
      + arn                                = (known after apply)
      + availability_zone_rebalancing      = "DISABLED"
      + cluster                            = "arn:aws:ecs:us-east-2:410965620680:cluster/jfp-ecs-cluster-stage"
      + deployment_maximum_percent         = 200
      + deployment_minimum_healthy_percent = 100
      + desired_count                      = 1
      + enable_ecs_managed_tags            = false
      + enable_execute_command             = true
      + iam_role                           = (known after apply)
      + id                                 = (known after apply)
      + launch_type                        = "FARGATE"
      + name                               = "cms-stage-service"
      + platform_version                   = (known after apply)
      + region                             = "us-east-2"
      + scheduling_strategy                = "REPLICA"
      + tags_all                           = (known after apply)
      + task_definition                    = (known after apply)
      + triggers                           = (known after apply)
      + wait_for_steady_state              = false

      + load_balancer {
          + container_name   = "jfp-cms-stage-app"
          + container_port   = 1337
          + target_group_arn = (known after apply)
            # (1 unchanged attribute hidden)
        }

      + network_configuration {
          + assign_public_ip = true
          + security_groups  = [
              + "sg-0715e664d653ce89c",
            ]
          + subnets          = [
              + "subnet-03bd7850c8bbe2ce9",
              + "subnet-0a609b33cdac65789",
              + "subnet-0c394639d255c3261",
            ]
        }
    }

  # module.stage.module.cms.module.ecs-task.aws_ecs_task_definition.ecs_task_definition will be created
+ resource "aws_ecs_task_definition" "ecs_task_definition" {
      + arn                      = (known after apply)
      + arn_without_revision     = (known after apply)
      + container_definitions    = (known after apply)
      + cpu                      = "1024"
      + enable_fault_injection   = (known after apply)
      + execution_role_arn       = "arn:aws:iam::410965620680:role/jfp-ecs-task-execution-role"
      + family                   = "jfp-cms-stage"
      + id                       = (known after apply)
      + memory                   = "2048"
      + network_mode             = "awsvpc"
      + region                   = "us-east-2"
      + requires_compatibilities = [
          + "FARGATE",
        ]
      + revision                 = (known after apply)
      + skip_destroy             = false
      + tags_all                 = (known after apply)
      + task_role_arn            = "arn:aws:iam::410965620680:role/terraform-ecs-task-role-stage"
      + track_latest             = false
    }

  # module.stage.module.cms.module.ecs-task.aws_route53_record.record will be created
+ resource "aws_route53_record" "record" {
      + allow_overwrite = (known after apply)
      + fqdn            = (known after apply)
      + id              = (known after apply)
      + name            = "cms"
      + records         = [
          + "jfp-public-alb-stage-1845039612.us-east-2.elb.amazonaws.com",
        ]
      + ttl             = 300
      + type            = "CNAME"
      + zone_id         = "Z09188583TUYV562FI49B"
    }

  # module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["ADMIN_JWT_SECRET"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/stage/ADMIN_JWT_SECRET"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "ADMIN_JWT_SECRET"
        }
      + tags_all       = {
          + "name" = "ADMIN_JWT_SECRET"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["API_TOKEN_SALT"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/stage/API_TOKEN_SALT"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "API_TOKEN_SALT"
        }
      + tags_all       = {
          + "name" = "API_TOKEN_SALT"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["APP_KEYS"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/stage/APP_KEYS"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "APP_KEYS"
        }
      + tags_all       = {
          + "name" = "APP_KEYS"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["ENCRYPTION_KEY"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/stage/ENCRYPTION_KEY"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "ENCRYPTION_KEY"
        }
      + tags_all       = {
          + "name" = "ENCRYPTION_KEY"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_ACCESS_TOKEN_ID"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/stage/MUX_ACCESS_TOKEN_ID"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "MUX_ACCESS_TOKEN_ID"
        }
      + tags_all       = {
          + "name" = "MUX_ACCESS_TOKEN_ID"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_PLAYBACK_SIGNING_ID"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/stage/MUX_PLAYBACK_SIGNING_ID"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "MUX_PLAYBACK_SIGNING_ID"
        }
      + tags_all       = {
          + "name" = "MUX_PLAYBACK_SIGNING_ID"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_PLAYBACK_SIGNING_SECRET"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/stage/MUX_PLAYBACK_SIGNING_SECRET"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "MUX_PLAYBACK_SIGNING_SECRET"
        }
      + tags_all       = {
          + "name" = "MUX_PLAYBACK_SIGNING_SECRET"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_SECRET_KEY"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/stage/MUX_SECRET_KEY"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "MUX_SECRET_KEY"
        }
      + tags_all       = {
          + "name" = "MUX_SECRET_KEY"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_WEBHOOK_SIGNING_SECRET"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/stage/MUX_WEBHOOK_SIGNING_SECRET"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "MUX_WEBHOOK_SIGNING_SECRET"
        }
      + tags_all       = {
          + "name" = "MUX_WEBHOOK_SIGNING_SECRET"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["PG_DATABASE_URL_CMS"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/stage/PG_DATABASE_URL_CMS"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "PG_DATABASE_URL_CMS"
        }
      + tags_all       = {
          + "name" = "PG_DATABASE_URL_CMS"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

  # module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["TRANSFER_TOKEN_SALT"] will be created
+ resource "aws_ssm_parameter" "parameters" {
      + arn            = (known after apply)
      + data_type      = (known after apply)
      + has_value_wo   = (known after apply)
      + id             = (known after apply)
      + insecure_value = (known after apply)
      + key_id         = (known after apply)
      + name           = "/ecs/cms/stage/TRANSFER_TOKEN_SALT"
      + overwrite      = true
      + region         = "us-east-2"
      + tags           = {
          + "name" = "TRANSFER_TOKEN_SALT"
        }
      + tags_all       = {
          + "name" = "TRANSFER_TOKEN_SALT"
        }
      + tier           = (known after apply)
      + type           = "SecureString"
      + value          = (sensitive value)
      + value_wo       = (write-only attribute)
      + version        = (known after apply)
    }

Plan: 44 to add, 1 to change, 0 to destroy.
╷
│ Warning: Deprecated Resource
│ 
│   with module.datadog.datadog_integration_aws.sandbox,
│   on modules/aws/datadog/main.tf line 118, in resource "datadog_integration_aws" "sandbox":
│  118: resource "datadog_integration_aws" "sandbox" {
│ 
│ **This resource is deprecated - use the `datadog_integration_aws_account`
│ resource instead**:
│ https://registry.terraform.io/providers/DataDog/datadog/latest/docs/resources/integration_aws_account
╵
╷
│ Warning: Deprecated attribute
│ 
│   on .terraform/modules/datadog.datadog_log_forwarder/modules/log_forwarder/main.tf line 2, in locals:
│    2:   bucket_name = var.bucket_name != "" ? var.bucket_name : "datadog-forwarder-${data.aws_caller_identity.current.account_id}-${data.aws_region.current.name}"
│ 
│ The attribute "name" is deprecated. Refer to the provider documentation for
│ details.
│ 
│ (and 2 more similar warnings elsewhere)
╵
  • ▶️ To apply this plan, comment:
    atlantis apply -d infrastructure
  • 🚮 To delete this plan and lock, click here
  • 🔁 To plan this project again, comment:
    atlantis plan -d infrastructure

Note: Objects have changed outside of Terraform
Plan: 44 to add, 1 to change, 0 to destroy.


  • ⏩ To apply all unapplied plans from this Pull Request, comment:
    atlantis apply
  • 🚮 To delete all plans and locks from this Pull Request, comment:
    atlantis unlock

@tataihono
Copy link
Contributor Author

atlantis apply

@jesus-film-bot
Copy link

Ran Apply for dir: infrastructure workspace: default

Show Output
module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_PLAYBACK_SIGNING_ID"]: Creating...
module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["API_TOKEN_SALT"]: Creating...
module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_SECRET_KEY"]: Creating...
module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["ADMIN_JWT_SECRET"]: Creating...
module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["APP_KEYS"]: Creating...
module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_ACCESS_TOKEN_ID"]: Creating...
module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["TRANSFER_TOKEN_SALT"]: Creating...
module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_PLAYBACK_SIGNING_SECRET"]: Creating...
module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["PG_DATABASE_URL_CMS"]: Creating...
module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_WEBHOOK_SIGNING_SECRET"]: Creating...
module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_SECRET_KEY"]: Creation complete after 1s [id=/ecs/cms/stage/MUX_SECRET_KEY]
module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["PG_DATABASE_URL_CMS"]: Creation complete after 1s [id=/ecs/cms/stage/PG_DATABASE_URL_CMS]
module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["API_TOKEN_SALT"]: Creation complete after 1s [id=/ecs/cms/stage/API_TOKEN_SALT]
module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["ENCRYPTION_KEY"]: Creating...
module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_PLAYBACK_SIGNING_ID"]: Creation complete after 1s [id=/ecs/cms/stage/MUX_PLAYBACK_SIGNING_ID]
module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_PLAYBACK_SIGNING_SECRET"]: Creation complete after 1s [id=/ecs/cms/stage/MUX_PLAYBACK_SIGNING_SECRET]
module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["ADMIN_JWT_SECRET"]: Creation complete after 1s [id=/ecs/cms/stage/ADMIN_JWT_SECRET]
module.prod.module.cms.module.ecs-task.aws_cloudwatch_log_group.ecs_cw_log_group: Creating...
module.prod.module.cms.module.ecs-task.aws_alb_target_group.alb_target_group: Creating...
module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_ACCESS_TOKEN_ID"]: Creation complete after 1s [id=/ecs/cms/stage/MUX_ACCESS_TOKEN_ID]
module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["APP_KEYS"]: Creation complete after 1s [id=/ecs/cms/stage/APP_KEYS]
module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["TRANSFER_TOKEN_SALT"]: Creation complete after 1s [id=/ecs/cms/stage/TRANSFER_TOKEN_SALT]
module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_WEBHOOK_SIGNING_SECRET"]: Creation complete after 1s [id=/ecs/cms/stage/MUX_WEBHOOK_SIGNING_SECRET]
module.stage.module.cms.module.ecs-task.aws_alb_target_group.alb_target_group: Creating...
module.prod.module.cms.module.ecs-task.aws_route53_record.record: Creating...
module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["APP_KEYS"]: Creating...
module.stage.module.cms.module.ecs-task.aws_ecr_repository.ecr_repository: Creating...
module.stage.module.cms.module.ecs-task.aws_route53_record.record: Creating...
module.prod.module.cms.module.ecs-task.aws_ecr_repository.ecr_repository: Creating...
module.stage.module.cms.module.ecs-task.aws_cloudwatch_log_group.ecs_cw_log_group: Creating...
module.stage.module.cms.module.ecs-task.aws_cloudwatch_log_group.ecs_cw_log_group: Creation complete after 0s [id=cms-stage-logs]
module.prod.module.cms.module.ecs-task.aws_cloudwatch_log_group.ecs_cw_log_group: Creation complete after 0s [id=cms-prod-logs]
module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_PLAYBACK_SIGNING_SECRET"]: Creating...
module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_WEBHOOK_SIGNING_SECRET"]: Creating...
module.stage.module.cms.module.ecs-task.aws_ssm_parameter.parameters["ENCRYPTION_KEY"]: Creation complete after 0s [id=/ecs/cms/stage/ENCRYPTION_KEY]
module.stage.module.cms.module.ecs-task.aws_ecr_repository.ecr_repository: Creation complete after 0s [id=jfp-cms-stage]
module.prod.module.cms.module.ecs-task.aws_ecr_repository.ecr_repository: Creation complete after 0s [id=jfp-cms-prod]
module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["API_TOKEN_SALT"]: Creating...
module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_SECRET_KEY"]: Creating...
module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["ADMIN_JWT_SECRET"]: Creating...
module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["APP_KEYS"]: Creation complete after 0s [id=/ecs/cms/prod/APP_KEYS]
module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["ENCRYPTION_KEY"]: Creating...
module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_WEBHOOK_SIGNING_SECRET"]: Creation complete after 0s [id=/ecs/cms/prod/MUX_WEBHOOK_SIGNING_SECRET]
module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_ACCESS_TOKEN_ID"]: Creating...
module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_SECRET_KEY"]: Creation complete after 0s [id=/ecs/cms/prod/MUX_SECRET_KEY]
module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["TRANSFER_TOKEN_SALT"]: Creating...
module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_PLAYBACK_SIGNING_SECRET"]: Creation complete after 0s [id=/ecs/cms/prod/MUX_PLAYBACK_SIGNING_SECRET]
module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_PLAYBACK_SIGNING_ID"]: Creating...
module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["API_TOKEN_SALT"]: Creation complete after 0s [id=/ecs/cms/prod/API_TOKEN_SALT]
module.stage.module.cms.module.ecs-task.aws_alb_target_group.alb_target_group: Creation complete after 0s [id=arn:aws:elasticloadbalancing:us-east-2:410965620680:targetgroup/cms-stage-tg/3253bc770843fe67]
module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["PG_DATABASE_URL_CMS"]: Creating...
module.stage.module.cms.module.ecs-task.aws_ecr_lifecycle_policy.ecr_policy: Creating...
module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["ENCRYPTION_KEY"]: Creation complete after 0s [id=/ecs/cms/prod/ENCRYPTION_KEY]
module.prod.module.cms.module.ecs-task.aws_alb_target_group.alb_target_group: Creation complete after 0s [id=arn:aws:elasticloadbalancing:us-east-2:410965620680:targetgroup/cms-prod-tg/558eae36912ff7d4]
module.prod.module.cms.module.ecs-task.aws_ecr_lifecycle_policy.ecr_policy: Creating...
module.stage.module.cms.module.ecs-task.aws_ecr_lifecycle_policy.ecr_policy: Creation complete after 1s [id=jfp-cms-stage]
module.stage.module.cms.module.ecs-task.aws_ecs_task_definition.ecs_task_definition: Creating...
module.stage.module.cms.module.ecs-task.aws_alb_listener_rule.alb_listener_rule: Creating...
module.prod.module.cms.module.ecs-task.aws_ecr_lifecycle_policy.ecr_policy: Creation complete after 1s [id=jfp-cms-prod]
module.stage.module.arclight.module.ecs-task.aws_ecs_service.ecs_service: Modifying... [id=arn:aws:ecs:us-east-2:410965620680:service/jfp-ecs-cluster-stage/arclight-stage-service]
module.stage.module.cms.module.ecs-task.aws_ecs_task_definition.ecs_task_definition: Creation complete after 0s [id=jfp-cms-stage]
module.prod.module.cms.module.ecs-task.aws_alb_listener_rule.alb_listener_rule: Creating...
module.stage.module.cms.module.ecs-task.aws_alb_listener_rule.alb_listener_rule: Creation complete after 0s [id=arn:aws:elasticloadbalancing:us-east-2:410965620680:listener-rule/app/jfp-public-alb-stage/27d94355c709eb16/e976ba0cdd6d17a6/78b1efc27e185d01]
module.stage.module.cms.module.ecs-task.aws_ecs_service.ecs_service: Creating...
module.prod.module.cms.module.ecs-task.aws_alb_listener_rule.alb_listener_rule: Creation complete after 0s [id=arn:aws:elasticloadbalancing:us-east-2:410965620680:listener-rule/app/jfp-public-alb-prod/7cf1f0916ed2c660/baff3356faf3dfae/02c9778953c343ed]
module.stage.module.arclight.module.ecs-task.aws_ecs_service.ecs_service: Modifications complete after 0s [id=arn:aws:ecs:us-east-2:410965620680:service/jfp-ecs-cluster-stage/arclight-stage-service]
module.stage.module.cms.module.ecs-task.aws_ecs_service.ecs_service: Creation complete after 1s [id=arn:aws:ecs:us-east-2:410965620680:service/jfp-ecs-cluster-stage/cms-stage-service]
module.stage.module.cms.module.ecs-task.aws_appautoscaling_target.service_autoscaling: Creating...
module.stage.module.cms.module.ecs-task.aws_appautoscaling_target.service_autoscaling: Creation complete after 0s [id=service/jfp-ecs-cluster-stage/cms-stage-service]
module.stage.module.cms.module.ecs-task.aws_appautoscaling_policy.ecs_policy_memory: Creating...
module.stage.module.cms.module.ecs-task.aws_appautoscaling_policy.ecs_policy_cpu: Creating...
module.stage.module.cms.module.ecs-task.aws_appautoscaling_policy.ecs_policy_cpu: Creation complete after 0s [id=jfp-cpu-autoscaling-stage]
module.stage.module.cms.module.ecs-task.aws_appautoscaling_policy.ecs_policy_memory: Creation complete after 0s [id=jfp-memory-autoscaling-stage]
module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_ACCESS_TOKEN_ID"]: Creation complete after 4s [id=/ecs/cms/prod/MUX_ACCESS_TOKEN_ID]
module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["TRANSFER_TOKEN_SALT"]: Creation complete after 4s [id=/ecs/cms/prod/TRANSFER_TOKEN_SALT]
module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["PG_DATABASE_URL_CMS"]: Creation complete after 5s [id=/ecs/cms/prod/PG_DATABASE_URL_CMS]
module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["MUX_PLAYBACK_SIGNING_ID"]: Creation complete after 6s [id=/ecs/cms/prod/MUX_PLAYBACK_SIGNING_ID]
module.prod.module.cms.module.ecs-task.aws_ssm_parameter.parameters["ADMIN_JWT_SECRET"]: Creation complete after 6s [id=/ecs/cms/prod/ADMIN_JWT_SECRET]
module.prod.module.cms.module.ecs-task.aws_ecs_task_definition.ecs_task_definition: Creating...
module.prod.module.cms.module.ecs-task.aws_ecs_task_definition.ecs_task_definition: Creation complete after 0s [id=jfp-cms-prod]
module.prod.module.cms.module.ecs-task.aws_ecs_service.ecs_service: Creating...
module.prod.module.cms.module.ecs-task.aws_ecs_service.ecs_service: Creation complete after 1s [id=arn:aws:ecs:us-east-2:410965620680:service/jfp-ecs-cluster-prod/cms-prod-service]
module.prod.module.cms.module.ecs-task.aws_appautoscaling_target.service_autoscaling: Creating...
module.prod.module.cms.module.ecs-task.aws_appautoscaling_target.service_autoscaling: Creation complete after 0s [id=service/jfp-ecs-cluster-prod/cms-prod-service]
module.prod.module.cms.module.ecs-task.aws_appautoscaling_policy.ecs_policy_cpu: Creating...
module.prod.module.cms.module.ecs-task.aws_appautoscaling_policy.ecs_policy_memory: Creating...
module.prod.module.cms.module.ecs-task.aws_appautoscaling_policy.ecs_policy_memory: Creation complete after 1s [id=jfp-memory-autoscaling-prod]
module.prod.module.cms.module.ecs-task.aws_appautoscaling_policy.ecs_policy_cpu: Creation complete after 1s [id=jfp-cpu-autoscaling-prod]
module.prod.module.cms.module.ecs-task.aws_route53_record.record: Still creating... [00m10s elapsed]
module.stage.module.cms.module.ecs-task.aws_route53_record.record: Still creating... [00m10s elapsed]
module.prod.module.cms.module.ecs-task.aws_route53_record.record: Still creating... [00m20s elapsed]
module.stage.module.cms.module.ecs-task.aws_route53_record.record: Still creating... [00m20s elapsed]
module.prod.module.cms.module.ecs-task.aws_route53_record.record: Still creating... [00m30s elapsed]
module.stage.module.cms.module.ecs-task.aws_route53_record.record: Still creating... [00m30s elapsed]
module.stage.module.cms.module.ecs-task.aws_route53_record.record: Creation complete after 31s [id=Z09188583TUYV562FI49B_cms_CNAME]
module.prod.module.cms.module.ecs-task.aws_route53_record.record: Creation complete after 32s [id=Z06687872LMUIKS0Y291P_cms_CNAME]
╷
│ Warning: Deprecated attribute
│ 
│   on .terraform/modules/datadog.datadog_log_forwarder/modules/log_forwarder/main.tf line 2, in locals:
│    2:   bucket_name = var.bucket_name != "" ? var.bucket_name : "datadog-forwarder-${data.aws_caller_identity.current.account_id}-${data.aws_region.current.name}"
│ 
│ The attribute "name" is deprecated. Refer to the provider documentation for
│ details.
╵

Apply complete! Resources: 44 added, 1 changed, 0 destroyed.

@jesus-film-bot
Copy link

Automatically merging because all plans have been successfully applied.

@jesus-film-bot
Copy link

Automerging failed:

merging pull request: PUT https://api.github.com/repos/JesusFilm/core/pulls/8594/merge: 404 Not Found []

@tataihono tataihono added this pull request to the merge queue Jan 15, 2026
Merged via the queue into main with commit 33ff490 Jan 15, 2026
43 checks passed
@tataihono tataihono deleted the cursor/ai-3-set-up-strapi-cms branch January 15, 2026 21:05
@jesus-film-bot
Copy link

Locks and plans deleted for the projects and workspaces modified in this pull request:

  • dir: infrastructure workspace: default

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants