Interface ApplicationSpec

All Known Subinterfaces:
CmsSpec
All Known Implementing Classes:
BagistoApplicationSpec, ConcreteCmsApplicationSpec, DolphinApplicationSpec, DroneApplicationSpec, DrupalApplicationSpec, FlarumApplicationSpec, GiteaApplicationSpec, GitLabApplicationSpec, GrafanaApplicationSpec, HarborApplicationSpec, JenkinsApplicationSpec, JoomlaApplicationSpec, MagentoApplicationSpec, MattermostApplicationSpec, MattermostTeamApplicationSpec, MediaWikiApplicationSpec, MetabaseApplicationSpec, MoodleApplicationSpec, MyBBApplicationSpec, NexusApplicationSpec, OctoberCmsApplicationSpec, OpenCartApplicationSpec, PhpBBApplicationSpec, PostgreSQLApplicationSpec, PrestaShopApplicationSpec, PrometheusApplicationSpec, RedisApplicationSpec, SuiteCrmApplicationSpec, SupersetApplicationSpec, SyliusApplicationSpec, Typo3ApplicationSpec, VaultApplicationSpec, WooCommerceApplicationSpec, WordPressApplicationSpec

public interface ApplicationSpec
Application specification interface defining application-specific configuration. This enables CloudForge to deploy any application (Jenkins, GitLab, Vault, etc.) using the same infrastructure patterns.

Implementations provide configuration for both container (Fargate) and EC2 deployments, supporting both EFS and EBS storage strategies.

CloudForge 3.0.0: Universal Application Support

Example implementations:

  • JenkinsApplicationSpec: Jenkins CI/CD automation server
  • GitLabApplicationSpec: GitLab DevOps platform
  • GrafanaApplicationSpec: Grafana metrics visualization
  • PostgreSQLApplicationSpec: PostgreSQL database
  • VaultApplicationSpec: HashiCorp Vault secrets management
  • + 9 more built-in applications

Plugin Metadata:

Implementations should be annotated with ApplicationPlugin for auto-discovery and metadata support:

@ApplicationPlugin(
    value = "jenkins",
    category = "cicd",
    displayName = "Jenkins",
    description = "Open-source automation server for CI/CD"
)
public class JenkinsApplicationSpec implements ApplicationSpec {
    // ...
}
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Interface
    Description
    static final record 
    Optional service port that can be enabled via deployment configuration.
    static final record 
    Declares an always-running, same-Fargate-task companion container: ContainerFactory adds it to the same task definition as this app's own container, wires the main container to wait for it (a startup dependency on HEALTHY, not SUCCESS — unlike the SAML certificate init container this deliberately isn't modeled after, a sidecar never exits), and gives it its own CloudWatch log stream.
  • Method Summary

    Modifier and Type
    Method
    Description
    default String
    The container environment variable name the ALB's own ARN should be bound to when this application is deployed with authMode=alb-oidc, or null (the default) if this application has no need to know it (e.g.
    Returns a unique identifier for this application.
    int
    Returns the primary application port.
    default String
    The container environment variable name a generated initial-admin-password secret should be bound to, or null (the default) if this application has no such variable.
    default String
    Get the application category from the ApplicationPlugin annotation.
    default String
    The container environment variable name a generated AES cipher-key secret should be bound to, or null (the default) if this application has no such need.
    void
    Configure EC2 UserData script for application installation and setup.
    Returns the container path where application data is stored.
    default Map<String,String>
    containerEnvironmentVariables(String fqdn, boolean sslEnabled, String authMode)
    Configures application-specific environment variables for the container.
    Returns the container user (UID:GID) to run as.
    Returns the CPU architecture this application's container image is built for, so a Fargate task definition requests matching compute rather than silently defaulting to X86_64.
    default String
    The container environment variable name a provisioned database's password secret should be bound to, overriding ContainerFactory's own per-applicationId() switch (and its DATABASE_PASSWORD fallback for any application not in it) when non-null.
    Returns the default container image for this application.
    default int
    Get the default Fargate CPU units.
    default int
    Get the recommended health check grace period for this application.
    default String
    Get the default EC2 instance type.
    default int
    Get the default Fargate memory in MB.
    default String[]
    Default admin/developer group names for an external-OIDC-provider deployment, used when the deployment context doesn't override them (cognitoAdminGroupName/ cognitoUserGroupName).
    default String
    The container environment variable name the resolved deployment target (aws/localstack/ministack) should be bound to, or null (the default) if this application has no need to distinguish targets at runtime.
    default String
    Get the application description.
    default String
    Get the human-readable display name for this application.
    Returns the EBS device name for EC2 instances when not using EFS.
    Returns the EC2 data path where application stores persistent data.
    Returns CloudWatch log file paths for EC2 monitoring.
    Returns the EFS path for this application's data.
    Returns the EFS permissions for the access point.
    Returns the OIDC integration handler for this application.
    default String
    Returns the recommended (default) authentication mode for this application.
    default String
    getRecommendedAuthMode(String deploymentTarget)
    Recommended auth mode for a deployment target.
    default List<String>
    Returns the list of supported authentication modes for this application.
    default List<String>
    getSupportedAuthModes(String deploymentTarget)
    Auth modes allowed for a deployment target (aws, ministack, localstack).
    default String
    Returns the health check path for ALB/ELB health checks.
    default String
    The container environment variable name a deploy-time-supplied license key should be bound to, or null (the default) if this application has no license key concept.
    default String
    The container environment variable name an application-OIDC client secret should be bound to, overriding ContainerFactory's own per-applicationId() switch (and its <APP>_OIDC_CLIENT_SECRET fallback naming for any application not in it) when non-null.
    Returns optional ports that can be enabled via deployment configuration.
    default List<String>
    Returns paths that require authentication when using ALB-level OIDC.
    default List<String>
    Returns paths that should always be public (no authentication required).
    default String
    The container environment variable name a "was this deployment's public endpoint reachable over a publicly-trusted TLS certificate" boolean signal should be bound to, or null (the default) if this application has no such need.
    default boolean
    Whether this application writes a role edit through to its Cognito user pool's real group membership at runtime (e.g.
    default boolean
    Whether this application requires a managed database (RDS) in the canonical template.
    default boolean
    Whether this application's persistence can't safely tolerate the brief two-task overlap a normal zero-downtime rolling ECS deployment creates (new task starts before the old one stops) — e.g.
    default boolean
    Whether this application needs a Redis-backed session store (ElastiCache), provisioned by ApplicationFactory and delivered as redisSessionStoreEndpoint/ redisSessionStorePort in SystemContext.
    default String[]
    The four container environment variable names a provisioned Redis session-store connection should be bound to (mode/host/port/TLS-enabled, in that order), or null (the default) if this application has no session-store concept — same gate requiresSessionStore() uses for whether to provision the cluster at all; this only names where its connection details land once provisioned.
    Returns same-task sidecar containers this application needs alongside its own container.
    default boolean
    Check if this application supports EC2 deployment.
    default boolean
    Check if this application supports Fargate deployment.
    default boolean
    Returns whether this application supports OIDC integration.
    Returns the volume name for this application.
  • Method Details

    • applicationId

      String applicationId()
      Returns a unique identifier for this application. Used for logging, metrics, and resource naming.
      Returns:
      application identifier (e.g., "jenkins", "gitlab", "vault")
    • defaultContainerImage

      String defaultContainerImage()
      Returns the default container image for this application. Can be overridden by deployment context configuration.
      Returns:
      container image string (e.g., "jenkins/jenkins:lts")
    • applicationPort

      int applicationPort()
      Returns the primary application port. This is the port the application listens on inside the container.
      Returns:
      application port (e.g., 8080 for Jenkins)
    • containerDataPath

      String containerDataPath()
      Returns the container path where application data is stored. This is where the volume will be mounted inside the container.
      Returns:
      container mount path (e.g., "/var/jenkins_home")
    • efsDataPath

      String efsDataPath()
      Returns the EFS path for this application's data. This is the path within the EFS filesystem.
      Returns:
      EFS path (e.g., "/jenkins")
    • volumeName

      String volumeName()
      Returns the volume name for this application. Used to reference the volume in task definitions.
      Returns:
      volume name (e.g., "jenkinsHome")
    • containerUser

      String containerUser()
      Returns the container user (UID:GID) to run as. Important for file permissions when using EFS.
      Returns:
      user in format "UID:GID" (e.g., "1000:1000")
    • efsPermissions

      String efsPermissions()
      Returns the EFS permissions for the access point.
      Returns:
      permissions string (e.g., "750")
    • cpuArchitecture

      default CpuArchitecture cpuArchitecture()
      Returns the CPU architecture this application's container image is built for, so a Fargate task definition requests matching compute rather than silently defaulting to X86_64.

      Defaults to X86_64 -- almost every built-in application image (Jenkins, GitLab, Grafana, etc.) is x86_64-only or x86_64-primary today. Override only when the image is confirmed to actually support the declared architecture; a mismatch fails the task at startup with no fallback, since Fargate provisions the underlying compute from this value before it ever pulls the image.

      Returns:
      the target CPU architecture, defaulting to X86_64
    • containerEnvironmentVariables

      default Map<String,String> containerEnvironmentVariables(String fqdn, boolean sslEnabled, String authMode)
      Configures application-specific environment variables for the container.

      Applications can override this to provide custom environment variables based on deployment configuration (FQDN, SSL, authMode, etc.). The infrastructure passes the FQDN, SSL settings, and authentication mode for applications that need reverse proxy configuration or authentication-specific setup.

      Example use cases:

      • Jenkins: JAVA_OPTS, JENKINS_OPTS for reverse proxy configuration, skip setup wizard for application-oidc
      • GitLab: GITLAB_OMNIBUS_CONFIG for external URL configuration and OIDC setup
      • Vault: VAULT_ADDR for API endpoint configuration
      Parameters:
      fqdn - The fully qualified domain name (may be null)
      sslEnabled - Whether SSL is enabled
      authMode - The authentication mode (may be null, e.g., "none", "alb-oidc", "application-oidc")
      Returns:
      Map of environment variable key-value pairs (never null, may be empty)
    • healthCheckPath

      default String healthCheckPath()
      Returns the health check path for ALB/ELB health checks.

      Different applications expose health endpoints at different paths:

      • Jenkins: /login
      • GitLab: /users/sign_in
      • Grafana: /api/health
      • Metabase: /api/health
      Returns:
      health check path (e.g., "/login", "/api/health")
    • ebsDeviceName

      String ebsDeviceName()
      Returns the EBS device name for EC2 instances when not using EFS. This is the device that will be formatted and mounted for application data.
      Returns:
      EBS device path (e.g., "/dev/xvdh")
    • ec2DataPath

      String ec2DataPath()
      Returns the EC2 data path where application stores persistent data. This may differ from containerDataPath depending on application packaging.
      Returns:
      EC2 mount path (e.g., "/var/lib/jenkins")
    • ec2LogPaths

      List<String> ec2LogPaths()
      Returns CloudWatch log file paths for EC2 monitoring. These files will be streamed to CloudWatch Logs for centralized logging.
      Returns:
      list of absolute log file paths (e.g., ["/var/log/jenkins/jenkins.log"])
    • configureUserData

      void configureUserData(UserDataBuilder builder, Ec2Context context)
      Configure EC2 UserData script for application installation and setup.

      The implementation should use the UserDataBuilder to add application-specific installation commands while leveraging infrastructure helpers for storage mounting and CloudWatch configuration.

      The infrastructure handles:

      • System updates
      • EFS vs EBS storage mounting (based on availability)
      • CloudWatch Agent installation and configuration
      • File permissions and ownership

      The application provides:

      • Application installation commands (yum/dnf install, etc.)
      • Application configuration
      • Service startup commands
      Parameters:
      builder - The UserDataBuilder providing infrastructure helpers
      context - The Ec2Context providing runtime information
    • supportsOidcIntegration

      default boolean supportsOidcIntegration()
      Returns whether this application supports OIDC integration.

      Applications with built-in OIDC support (GitLab, Grafana, SonarQube) or plugin support (Jenkins) should return true.

      Returns:
      true if application can integrate with OIDC providers
    • getOidcIntegration

      default OidcIntegration getOidcIntegration()
      Returns the OIDC integration handler for this application.

      This provides application-specific configuration for integrating with Cognito or IAM Identity Center OIDC.

      Returns:
      OIDC integration handler, or null if not supported
    • getSupportedAuthModes

      default List<String> getSupportedAuthModes()
      Returns the list of supported authentication modes for this application.

      CloudForge supports three authentication modes:

      • application-oidc: OIDC authentication integrated within the application (requires getOidcIntegration() != null)
      • alb-oidc: OIDC authentication at ALB level (works for all applications)
      • none: No authentication (public access or manually configured)

      The list is ordered by preference. The first mode is the recommended default.

      Default behavior:

      • If application has OIDC integration → ["application-oidc", "alb-oidc", "none"]
      • If application claims OIDC support but lacks integration → ["alb-oidc", "none"]
      • If application doesn't support OIDC → ["none"]
      Returns:
      List of supported auth modes in order of preference (never null, never empty)
    • getSupportedAuthModes

      default List<String> getSupportedAuthModes(String deploymentTarget)
      Auth modes allowed for a deployment target (aws, ministack, localstack).

      Default: same as getSupportedAuthModes(). Specs may restrict Cognito/OIDC on MiniStack while keeping it optional on LocalStack/AWS.

      Parameters:
      deploymentTarget - target id, or null/blank for the default list
      Returns:
      non-empty list of auth mode strings
    • getRecommendedAuthMode

      default String getRecommendedAuthMode()
      Returns the recommended (default) authentication mode for this application.

      This is the first mode from getSupportedAuthModes().

      Returns:
      the recommended auth mode (e.g., "application-oidc", "alb-oidc", "none")
    • getRecommendedAuthMode

      default String getRecommendedAuthMode(String deploymentTarget)
      Recommended auth mode for a deployment target.
      Parameters:
      deploymentTarget - target id (aws, ministack, localstack)
      Returns:
      first entry from getSupportedAuthModes(String)
    • protectedPaths

      default List<String> protectedPaths()
      Returns paths that require authentication when using ALB-level OIDC.

      When this list is non-empty and authMode is "alb-oidc", the ALB will:

      • Require OIDC authentication for requests matching these paths
      • Allow unauthenticated access to all other paths

      When this list is empty (default), ALL paths require authentication.

      Path patterns support ALB path-pattern syntax:

      • Exact: "/admin"
      • Prefix wildcard: "/admin/*"
      • Extension: "*.php"

      Example for phpBB (protect admin and installer):

      @Override
      public List<String> protectedPaths() {
          return List.of("/adm/*", "/install/*");
      }
      

      Example for WordPress (protect wp-admin):

      @Override
      public List<String> protectedPaths() {
          return List.of("/wp-admin/*", "/wp-login.php");
      }
      

      Users can override these defaults via DeploymentContext:

      • protectedPaths: Override/replace the application defaults
      • additionalProtectedPaths: Add to the application defaults
      • publicPaths: Explicitly mark paths as public (overrides protected)
      Returns:
      list of path patterns requiring authentication (empty = protect everything)
      See Also:
    • publicPaths

      default List<String> publicPaths()
      Returns paths that should always be public (no authentication required).

      These paths are excluded from authentication even when they would otherwise be protected. Useful for health checks, public APIs, etc.

      Common use cases:

      • Health check endpoints: "/health", "/api/health"
      • Public API endpoints: "/api/public/*"
      • Static assets: "/static/*", "/assets/*"
      Returns:
      list of path patterns that should be public (empty by default)
    • optionalPorts

      default List<ApplicationSpec.OptionalPort> optionalPorts()
      Returns optional ports that can be enabled via deployment configuration.

      These ports are NOT exposed by default. Users must set the corresponding configKey to true in their deployment configuration to enable each port.

      Example implementation for Mattermost:

      @Override
      public List<OptionalPort> optionalPorts() {
          return List.of(
              OptionalPort.outboundTcp(587, "enableSmtp", "SMTP Email"),
              OptionalPort.inboundTcp(8074, "enableClustering", "Cluster Gossip")
          );
      }
      

      User enables in deployment-context.json:

      {
        "enableSmtp": true,
        "enableClustering": true
      }
      
      Returns:
      list of optional ports (empty by default - most apps only need primary port)
    • sidecarContainers

      default List<ApplicationSpec.SidecarContainer> sidecarContainers()
      Returns same-task sidecar containers this application needs alongside its own container.

      Empty for every application by default — this exists for cloudforge-manager's cloudforge-synth-service sidecar (see that spec's own override), not a general-purpose extension point most applications need.

      Returns:
      list of sidecar containers (empty by default)
    • category

      default String category()
      Get the application category from the ApplicationPlugin annotation.
      Returns:
      the category (e.g., "cicd", "monitoring", "database")
    • displayName

      default String displayName()
      Get the human-readable display name for this application.
      Returns:
      the display name, defaulting to capitalized applicationId() if not specified
    • description

      default String description()
      Get the application description.
      Returns:
      the application description
    • defaultCpu

      default int defaultCpu()
      Get the default Fargate CPU units.
      Returns:
      the default CPU units (256, 512, 1024, 2048, 4096)
    • defaultMemory

      default int defaultMemory()
      Get the default Fargate memory in MB.
      Returns:
      the default memory in MB
    • defaultInstanceType

      default String defaultInstanceType()
      Get the default EC2 instance type.
      Returns:
      the default instance type (e.g., "t3.small")
    • supportsFargate

      default boolean supportsFargate()
      Check if this application supports Fargate deployment.
      Returns:
      true if Fargate is supported
    • supportsEc2

      default boolean supportsEc2()
      Check if this application supports EC2 deployment.
      Returns:
      true if EC2 is supported
    • requiresDatabase

      default boolean requiresDatabase()
      Whether this application requires a managed database (RDS) in the canonical template.

      Reads ApplicationPlugin.requiresDatabase() when present; defaults to false.

    • defaultHealthCheckGracePeriod

      default int defaultHealthCheckGracePeriod()
      Get the recommended health check grace period for this application.

      The grace period is how long ECS/ALB waits before starting health checks after a container starts. Applications with longer initialization times (like GitLab) need longer grace periods.

      Default values:

      • Most applications: 300 seconds (5 minutes)
      • GitLab: 600 seconds (10 minutes) - due to database migrations and initialization
      • Other database-heavy apps may also need longer periods
      Returns:
      recommended health check grace period in seconds
    • autoAdminPasswordEnvVar

      default String autoAdminPasswordEnvVar()
      The container environment variable name a generated initial-admin-password secret should be bound to, or null (the default) if this application has no such variable.

      Mirrors CmsSpec.databaseEnvVars's existing pattern for the database password specifically: a database connection's host/port/name/user travel as plain strings through containerEnvironmentVariables(String, boolean, String), but the password itself is never a plaintext value an app spec method returns — it's delivered as a Secrets Manager-backed ECS Secret, which needs a CDK construct only cloudforge-api can build. This method is the same shape, generalized to any application whose official image supports a fully non-interactive first-run install once its site name/admin account/admin password are all present (Joomla's own docker-entrypoint.sh is the first example — see JoomlaApplicationSpec), instead of a per-application name check hardcoded into ApplicationFactory/ ContainerFactory.

      Returns:
      the env var name (e.g. "JOOMLA_ADMIN_PASSWORD"), or null
    • requiresSessionStore

      default boolean requiresSessionStore()
      Whether this application needs a Redis-backed session store (ElastiCache), provisioned by ApplicationFactory and delivered as redisSessionStoreEndpoint/ redisSessionStorePort in SystemContext. Same generalization shape as autoAdminPasswordEnvVar() — an application declares the need through this contract rather than ApplicationFactory recognizing it by applicationId().
      Returns:
      true if a Redis session store should be provisioned
    • cipherKeySecretEnvVar

      default String cipherKeySecretEnvVar()
      The container environment variable name a generated AES cipher-key secret should be bound to, or null (the default) if this application has no such need. Same shape as autoAdminPasswordEnvVar(): ApplicationFactory provisions the Secrets Manager entry and ContainerFactory binds it as an ECS Secret under this name, without either needing to recognize a specific applicationId().
      Returns:
      the env var name (e.g. "CFC_MANAGER_ACCOUNT_SECRET_KEY"), or null
    • licenseKeySecretEnvVar

      default String licenseKeySecretEnvVar()
      The container environment variable name a deploy-time-supplied license key should be bound to, or null (the default) if this application has no license key concept. Same shape as cipherKeySecretEnvVar() — the value itself still comes from whatever deployment-context field the application's own deployment contract declares; this only names the delivery env var.
      Returns:
      the env var name (e.g. "CFC_MANAGER_LICENSESEAT_LICENSE_KEY"), or null
    • requiresSequentialDeploymentWithoutDatabase

      default boolean requiresSequentialDeploymentWithoutDatabase()
      Whether this application's persistence can't safely tolerate the brief two-task overlap a normal zero-downtime rolling ECS deployment creates (new task starts before the old one stops) — e.g. a single-writer embedded-file database with no real concurrent-access support. Only takes effect when this application also has no managed database connection provisioned (see DatabaseSpec) — once one is, a real database safely handles that overlap and this no longer applies regardless of what this method returns.
      Returns:
      true if this application needs a stop-then-start deployment replacement instead of ECS's own rolling default, when running without a managed database
    • albSignerArnEnvVar

      default String albSignerArnEnvVar()
      The container environment variable name the ALB's own ARN should be bound to when this application is deployed with authMode=alb-oidc, or null (the default) if this application has no need to know it (e.g. to validate an ALB-signed OIDC token itself).
      Returns:
      the env var name, or null
    • publicTlsTrustedEnvVar

      default String publicTlsTrustedEnvVar()
      The container environment variable name a "was this deployment's public endpoint reachable over a publicly-trusted TLS certificate" boolean signal should be bound to, or null (the default) if this application has no such need.
      Returns:
      the env var name, or null
      See Also:
    • deploymentTargetEnvVar

      default String deploymentTargetEnvVar()
      The container environment variable name the resolved deployment target (aws/localstack/ministack) should be bound to, or null (the default) if this application has no need to distinguish targets at runtime.
      Returns:
      the env var name, or null
    • sessionStoreEnvVars

      default String[] sessionStoreEnvVars()
      The four container environment variable names a provisioned Redis session-store connection should be bound to (mode/host/port/TLS-enabled, in that order), or null (the default) if this application has no session-store concept — same gate requiresSessionStore() uses for whether to provision the cluster at all; this only names where its connection details land once provisioned. The TLS-enabled var is always told "false" — the cluster this provisions has no TLS listener.
      Returns:
      [modeEnvVar, hostEnvVar, portEnvVar, tlsEnabledEnvVar], or null
    • databasePasswordEnvVar

      default String databasePasswordEnvVar()
      The container environment variable name a provisioned database's password secret should be bound to, overriding ContainerFactory's own per-applicationId() switch (and its DATABASE_PASSWORD fallback for any application not in it) when non-null. Most built-in applications are covered by that switch already and don't need this — it exists for an application declared outside cloudforge-api entirely, which the switch can't have a case for.
      Returns:
      the env var name, or null to use the switch/fallback instead
    • oidcClientSecretEnvVar

      default String oidcClientSecretEnvVar()
      The container environment variable name an application-OIDC client secret should be bound to, overriding ContainerFactory's own per-applicationId() switch (and its <APP>_OIDC_CLIENT_SECRET fallback naming for any application not in it) when non-null. Same reasoning as databasePasswordEnvVar() — exists for an application declared outside cloudforge-api entirely, whose expected env var name doesn't match that generic <APP>_ naming convention.
      Returns:
      the env var name, or null to use the switch/fallback instead
    • requiresCognitoGroupManagementIam

      default boolean requiresCognitoGroupManagementIam()
      Whether this application writes a role edit through to its Cognito user pool's real group membership at runtime (e.g. AdminAddUserToGroup) rather than only updating its own local cache — CognitoAuthenticationFactory grants the corresponding IAM actions on the pool's task role only when this is true, since most applications never call those APIs at all and shouldn't carry the grant.
      Returns:
      true if the Cognito admin group-management IAM actions should be granted
    • defaultOidcGroupNames

      default String[] defaultOidcGroupNames()
      Default admin/developer group names for an external-OIDC-provider deployment, used when the deployment context doesn't override them (cognitoAdminGroupName/ cognitoUserGroupName).
      Returns:
      [adminGroupName, developerGroupName], defaulting to ["Admins", "Developers"]