# CloudFormation

Source: https://docs.ops0.com/docs/iac/cloudformation

ops0 supports AWS CloudFormation as a first-class IaC engine alongside Terraform and OpenTofu. Write CloudFormation templates, deploy stacks across multiple regions and accounts with change sets, enforce policies, and migrate to Terraform when you're ready.

---

## Creating a CloudFormation Project

### Navigate to IaC
Click **IaC** in the sidebar and then **+ New Project**.

### Select CloudFormation
In the **IaC Type** dropdown, choose **CloudFormation**.

### Connect AWS
Select the AWS integration to use for deployments.

### Create
Click **Create** to open the editor.

---

## Writing Templates

The editor supports YAML and JSON CloudFormation templates with syntax highlighting. Use the AI assistant to generate templates from natural language:

```
Create a CloudFormation template for an ECS Fargate service with
an ALB, target group, security groups, and CloudWatch log group
```

### Template Structure

```yaml
AWSTemplateFormatVersion: "2010-09-09"
Description: "ECS Fargate service with ALB"

Parameters:
  Environment:
    Type: String
    Default: production

Resources:
  ALB:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Scheme: internet-facing
      Subnets: !Ref PublicSubnets

  ECSService:
    Type: AWS::ECS::Service
    Properties:
      Cluster: !Ref ECSCluster
      TaskDefinition: !Ref TaskDefinition
      DesiredCount: 2
      LaunchType: FARGATE

Outputs:
  LoadBalancerDNS:
    Value: !GetAtt ALB.DNSName
```

---

## Deploying Stacks

CloudFormation deployments in ops0 use **change sets** — AWS creates a preview of the changes before any resources are modified.

### Deployment Flow

### Click Deploy
Click the **Deploy** button in the editor toolbar.

### Change Set Created
ops0 calls `CreateChangeSet` on AWS. For a new stack this uses `CREATE`; for an existing stack it uses `UPDATE`.

### Review Changes
The change set shows every resource that will be added, modified, or deleted — equivalent to `terraform plan`.

### Policy Check
Policies attached to the project are evaluated against the template.

### Apply
Click **Apply** to execute the change set. Stack events stream in real time.

### Completion
Stack reaches `CREATE_COMPLETE` or `UPDATE_COMPLETE`. Outputs are available immediately.

### Stack Event Streaming

During apply, CloudFormation stack events are streamed to the deployment log:

```
CREATE_IN_PROGRESS   AWS::CloudFormation::Stack   MyStack
CREATE_IN_PROGRESS   AWS::EC2::VPC                VPC
CREATE_COMPLETE      AWS::EC2::VPC                VPC
CREATE_IN_PROGRESS   AWS::EC2::Subnet             PublicSubnet1
CREATE_COMPLETE      AWS::EC2::Subnet             PublicSubnet1
CREATE_COMPLETE      AWS::CloudFormation::Stack   MyStack

Stack creation complete. 4 resources created.
```

---

## Multi-Region Deployments

Deploy the same CloudFormation template to multiple AWS regions in a single deployment run.

### Configuring Multi-Region

In the deployment panel, expand **Regions** and select all target regions:

```
✓ us-east-1  (primary)
✓ us-west-2
✓ eu-west-1
```

### How It Works

ops0 creates and executes change sets in each selected region in parallel:

| Region | Status |
|--------|--------|
| us-east-1 | ✓ CREATE_COMPLETE |
| us-west-2 | ✓ CREATE_COMPLETE |
| eu-west-1 | ✗ ROLLBACK_COMPLETE (error shown) |

Each region's change set and stack events are tracked independently. A failure in one region does not automatically roll back other regions.

---

## StackSets

StackSets let you deploy CloudFormation stacks to multiple AWS accounts and regions from a single operation. ops0 supports both permission models.

### Permission Models

| Model | When to Use |
|-------|-------------|
| **SELF_MANAGED** | You manually grant CloudFormation execution roles in each target account |
| **SERVICE_MANAGED** | AWS Organizations manages permissions automatically (requires trusted access) |

### Deploying a StackSet

### Enable StackSet mode
In the deployment panel, toggle **Deploy as StackSet**.

### Select permission model
Choose **Self-Managed** or **Service-Managed**.

### Configure targets
For Self-Managed: enter target account IDs and regions.
For Service-Managed: select an Organizational Unit (OU) and regions.

### Deploy
ops0 creates the StackSet and deploys stack instances to all targets.

### StackSet Deployment Tracking

Progress is tracked per account and per region:

```
StackSet: MyInfraStackSet
├── 123456789012 / us-east-1   ✓ CURRENT
├── 123456789012 / eu-west-1   ✓ CURRENT
├── 987654321098 / us-east-1   ⟳ RUNNING
└── 987654321098 / eu-west-1   ○ PENDING
```

### Destroying StackSets

Destroying a StackSet first calls `DeleteStackInstances` to remove all stack instances across all accounts and regions, then calls `DeleteStackSet` to remove the StackSet itself.

---

## Policy Checking

CloudFormation templates are evaluated against policies before any change set is executed. Policies are authored using OPA/Rego and can check for:

- Required resource properties (encryption, logging, tags)
- Prohibited resource types
- Parameter value constraints
- Security group rules
- IAM permission boundaries

See [Policy Checking](https://docs.ops0.com/docs/iac/deployments/policies) for how to create and attach policies.

---

## Migrating to Terraform

If you want to migrate an existing CloudFormation project to Terraform or OpenTofu, ops0 provides a one-click migration path.

### Running the Migration

1. Open the CloudFormation project
2. Open the project **⋮** menu
3. Select **Migrate to Terraform** or **Migrate to OpenTofu**
4. A progress modal shows migration status

### What Gets Migrated

| Item | Outcome |
|------|---------|
| **CloudFormation template** | Converted to equivalent HCL resources |
| **Parameters** | Mapped to Terraform variables |
| **Outputs** | Mapped to Terraform outputs |
| **Resource types** | Mapped to equivalent `aws_*` Terraform resources |
| **IaC type** | Project is updated from CloudFormation to Terraform/OpenTofu |

**Review generated code**

Automated migration handles common resource types but complex templates with custom resources (`AWS::CloudFormation::CustomResource`) or nested stacks may require manual adjustment after migration.

---

## Related

- [Deployments](https://docs.ops0.com/docs/iac/deployments): Deployment flow, approval workflows, and deployment history

- [Policy Checking](https://docs.ops0.com/docs/iac/deployments/policies): Enforce security and compliance policies before deploying

- [AWS Integration](https://docs.ops0.com/docs/settings/integrations/aws): Connect your AWS account to ops0

- [Migrate Engine](https://docs.ops0.com/docs/iac/migrate): Switch between Terraform and OpenTofu
