> **Page index:** https://km.oslo.systems/llms.txt lists every page on this site, with a link to its Markdown version.

# Add plan workflow

Add the CI/CD foundation and a Terraform plan workflow to your infrastructure repository.

## Step 1: Create a branch

repo-iac/

```
git checkout -b add-plan-workflow
```

## Step 2: Set up CI/CD common

The `cicd-common` stack creates the IAM roles and resources needed for GitHub Actions to run Terraform in your AWS accounts. You need it in **every environment** that you want to run GitHub Actions workflows against.

> [!NOTE]
>
> The examples below use a `dev` environment. Change the directory paths to match your own environment and directory structure.

Install the stack in your environment directory:

repo-iac/environments/dev/

```
ok pkg add cicd-common
cd cicd-common
ok pkg install
```

Update `config_override.tf`:

repo-iac/environments/dev/cicd-common/config\_override.tf

```
locals {
  trusted_repositories = [
    {
      name = "<repo-name>"
      type = "infra"
    },
  ]
}
```

| Field | Description | Example |
| --- | --- | --- |
| `<repo-name>` | Name of your IaC repository | `pirates-iac` |

Apply the stack locally so the IAM roles are available before the workflow runs:

repo-iac/environments/dev/cicd-common/

```
terraform init
terraform apply
```

Repeat for each remaining environment, such as `prod`.

## Step 3: Add configuration files

### Step 3.1: Add `.gp.cicd.json`

Download [.gp.cicd.json](<https://github.com/oslokommune/golden-path-templates/blob/main/templates/gh-terraform-iac/.gp.cicd.json>) to the repository root:

repo-iac/

```
gh api repos/oslokommune/golden-path-templates/contents/templates/gh-terraform-iac/.gp.cicd.json \
  --jq '.content' | base64 -d > .gp.cicd.json
```

Update these values (you can find them in `common-config.yml` in each of your environment directories):

| Field | Description | Example |
| --- | --- | --- |
| `<team-name>` | Your team name | `pirates` |
| `<dev-aws-account-id>` | AWS account ID for `dev` | `123456789012` |
| `<dev-environment-name>` | Name of your `dev` AWS environment | `pirates-dev` |
| `<prod-aws-account-id>` | AWS account ID for `prod` | `987654321098` |
| `<prod-environment-name>` | Name of your `prod` AWS environment | `pirates-prod` |
| `<aws-region>` | Your AWS region | `eu-west-1` |

### Step 3.2: Add CODEOWNERS

Add a `CODEOWNERS` file to define who owns the repository and approves PRs:

repo-iac/.github/CODEOWNERS

```
* @oslokommune/<github-team-name>
```

| Field | Description | Example |
| --- | --- | --- |
| `<github-team-name>` | The name of your [GitHub team](<https://github.com/orgs/oslokommune/teams>) | `utviklerflyt` |

### Step 3.3: Add Renovate configuration

Download [renovate.json5](<https://github.com/oslokommune/golden-path-templates/blob/main/templates/gh-terraform-iac/renovate.json5>) to the repository root:

repo-iac/

```
gh api repos/oslokommune/golden-path-templates/contents/templates/gh-terraform-iac/renovate.json5 \
  --jq '.content' | base64 -d > renovate.json5
```

This overwrites any existing `renovate.json5`. If you have custom Renovate configuration, merge it into the downloaded file.

> [!NOTE]
>
> **What is Renovate?**
>
> Renovate automatically creates pull requests to keep your dependencies up to date. Think of it as a better Dependabot. Learn more in the [Renovate reference documentation](<https://km.oslo.systems/terraform-automation/renovate/index.md>).

## Step 4: Add the plan workflow

Download [`terraform-pr.yml`](<https://github.com/oslokommune/golden-path-templates/blob/main/templates/gh-terraform-iac/.github/workflows/terraform-pr.yml>) to `.github/workflows/terraform-pr.yml`:

repo-iac/

```
mkdir -p .github/workflows
gh api repos/oslokommune/golden-path-templates/contents/templates/gh-terraform-iac/.github/workflows/terraform-pr.yml \
  --jq '.content' | base64 -d > .github/workflows/terraform-pr.yml
```

Update these values:

| Field | Description | Example |
| --- | --- | --- |
| `<dev-iac-directory>` | The directory containing IaC for your `dev` environment | `stacks/dev` |

## Step 5: Create a pull request

Push the branch and create a pull request.

## Step 6: Verify the plan workflow in the PR

The plan workflow should run automatically in the PR. Verify that the **Plan / Summarize** check runs and completes successfully.

## Step 7: Merge the pull request

Merge the pull request.

## Step 8: Verify the plan workflow against all stacks

Manually trigger the plan workflow against all stacks to detect any issues:

1. Go to **Actions \> Terraform PR \> Run workflow**
2. Input `**` as the stack pattern
3. Run the workflow

Once the run finishes, you'll get a summary of running `terraform plan` against all stacks in your repository. Review the results. Ideally all plans report *No changes*.

If any stacks have issues or unexpected drift, either fix them before continuing, or make a note of which stacks are affected — you add them to an ignore list in the next guide.

> [!TIP]
>
> See the [`terraform-pr.yml` reference](<https://github.com/oslokommune/reusable-terraform-pr?tab=readme-ov-file#inputs>) for available configuration options, including `ignored-stacks`.

## Next steps

[Add the apply workflow](<https://km.oslo.systems/terraform-automation/migrate-to-latest-workflows/add-apply-workflow/index.md>) to enable automated Terraform apply on pushes to your default branch.
