Skip to main content
Latest Documentation
This is the latest documentation for the Cloud Posse Reference Architecture. To determine which version you're currently using, please see Version Identification.

Software Delivery

Software delivery is the process of moving your applications from development to production. This involves building, testing, deploying, and promoting them through environments like dev, staging, and production, with approval gates at each stage. Whether you're using EKS, ECS, or Lambdas, the solutions may vary slightly, but we maintain a consistent, reusable pattern across all applications.

1 Deploy all Backing Services & Databases

Ensure all the backing services that your applications depend on are deployed and running. This includes databases, caches, and message queues, etc.

Get Started

2 Implement CI/CD

Choose a path for delivery of your services with GitHub Actions. The reference architecture supports deployment to AWS EKS, Amazon ECS, and Lambda functions.

Deploy containerized applications to AWS ECS Fargate using Atmos for configuration orchestration and OpenTofu for infrastructure-as-code. This approach provides a self-contained, elegant solution with automated CI/CD pipelines that leverage Atmos stack configurations for multi-environment deployments.

Get Started
AI generated voice

Once you're done deploying your apps, it's time to start monitoring everything. We'll show you how to do that next.


Our Examples

The app-on-ecs-v2 example demonstrates a self-contained approach where workflows are defined directly in the application repository. This approach uses Atmos for configuration orchestration and OpenTofu for infrastructure management.

With this approach, you need only a few workflows in your application repository:

  1. feature-branch.yml - Build and deploy to preview environments
  2. preview-cleanup.yml - Clean up preview environments when PRs close
  3. main-branch.yaml - Build, deploy to dev, and create draft release
  4. release.yaml - Promote and deploy to staging/production
  5. (optional) validate.yml - Run validation checks
  6. (optional) labeler.yaml - Auto-label PRs
app-on-ecs-v2/
├── .github/
│ └── workflows/
│ ├── feature-branch.yml
│ ├── preview-cleanup.yml
│ ├── main-branch.yaml
│ ├── release.yaml
│ ├── validate.yml
│ └── labeler.yaml
├── app/
│ ├── main.go
│ └── Dockerfile
├── terraform/
│ ├── components/
│ │ └── ecs-task/
│ └── stacks/
│ ├── dev.yaml
│ ├── staging.yaml
│ ├── prod.yaml
│ └── preview.yaml
└── .opentofu-version

ECS with Ecspresso (Deprecated)

warning

The ecspresso-based approach is deprecated. For new projects, use ECS with Atmos instead.

View deprecated ecspresso workflow structure

We've consolidated all the workflows into the example applications, including the GitHub reusable workflows. We've done this to make it easier for Developers to understand how the example leverages all the workflows. In practice, we recommend moving the reusable workflows into a centralized repository, where they can be shared by other application repositories.

For example, we would recommend moving all the ecspresso-* and all workflow-* workflow files to a centralized repository (e.g. a repository named github-action-workflows, alternatively the infrastructure repository directly). The best solution will depend on your GitHub Organization structure and team size. Pick what works for you and your team.

When your workflows are consolidated, you will need only 3 inside an application repository:

  1. feature-branch.yaml
  2. main-branch.yaml
  3. release.yaml
  4. (optional) hotfix-branch.yaml
  5. (optional) hotfix-enabled.yaml
  6. (optional) hotfix-release.yaml

The remaining workflows are the reusable/shared implementation. This approach makes it easier to define a standardized CI/CD interface for all of your services.

.github
├── configs/
│ ├── draft-release.yml
│ └── environment.yaml
└── workflows/
├── ecspresso-feature-branch.yml
├── ecspresso-hotfix-branch.yml
├── ecspresso-hotfix-mixin.yml
├── ecspresso-hotfix-release.yml
├── ecspresso-main-branch.yml
├── ecspresso-release.yml
├── feature-branch.yml
├── main-branch.yaml
├── release.yaml
├── workflow-cd-ecspresso.yml
├── workflow-cd-preview-ecspresso.yml
├── workflow-ci-dockerized-app-build.yml
├── workflow-ci-dockerized-app-promote.yml
├── workflow-controller-draft-release.yml
├── workflow-controller-hotfix-reintegrate.yml
├── workflow-controller-hotfix-release-branch.yml
└── workflow-controller-hotfix-release.yml

After moving to a centralized workflow repository, you should have a setup like the following:

Application Repository
├── .github
│ ├── configs/
│ │ └── draft-release.yml
│ └── workflows/
│ ├── feature-branch.yml
│ ├── main-branch.yaml
│ └── release.yaml
└── ...
github-action-workflows
├── .github/
│ └── workflows
│ ├── ecspresso-feature-branch.yml
│ ├── ecspresso-hotfix-branch.yml
│ ├── ecspresso-hotfix-mixin.yml
│ ├── ecspresso-hotfix-release.yml
│ ├── ecspresso-main-branch.yml
│ ├── ecspresso-release.yml
│ ├── workflow-cd-ecspresso.yml
│ ├── workflow-cd-preview-ecspresso.yml
│ ├── workflow-ci-dockerized-app-build.yml
│ ├── workflow-ci-dockerized-app-promote.yml
│ ├── workflow-controller-draft-release.yml
│ ├── workflow-controller-hotfix-reintegrate.yml
│ ├── workflow-controller-hotfix-release-branch.yml
│ └── workflow-controller-hotfix-release.yml
└── ...