# Set up Terraform workflows

Add GitHub Actions workflows for automated Terraform plan and apply.

## Before you begin

Familiarize yourself with [the key points from the risk assessment analysis (ROS)](https://github.com/oslokommune/golden-path-docs-internal/blob/main/oppsummering-ros-nytt-cicd-oppsett.md).

## Step 1: Add Terraform workflows

### Step 1.1: Create the workflow directory

```bash title="repo-iac/"
mkdir -p .github/workflows
```

### Step 1.2: Add workflow for running Terraform plan

Download [`terraform-pr.yml`](https://github.com/oslokommune/golden-path-templates/blob/main/templates/gh-terraform-iac/.github/workflows/terraform-pr.yml){:target="_blank"} to `.github/workflows/terraform-pr.yml`:

```bash title="repo-iac/"
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
```

### Step 1.3: Add workflow for running Terraform apply

Download [`terraform-apply.yml`](https://github.com/oslokommune/golden-path-templates/blob/main/templates/gh-terraform-iac/.github/workflows/terraform-apply.yml){:target="_blank"} to `.github/workflows/terraform-apply.yml`:

```bash title="repo-iac/"
gh api repos/oslokommune/golden-path-templates/contents/templates/gh-terraform-iac/.github/workflows/terraform-apply.yml \
  --jq '.content' | base64 -d > .github/workflows/terraform-apply.yml
```

<!-- prettier-ignore-start -->
!!! Tip
    It is possible to configure these workflows to never run against certain stacks. This can be useful if you have broken stacks you temporarily don't want to run against while you fix them. Example:

    ```yaml
    # ...
    with:
      ignored-stacks: "environments/dev/some-broken-stack,environments/prod/**"
    ```

    - [`terraform-pr.yml` reference](https://github.com/oslokommune/reusable-terraform-pr?tab=readme-ov-file#inputs)
    - [`terraform-apply.yml` reference](https://github.com/oslokommune/reusable-terraform-apply?tab=readme-ov-file#inputs)
<!-- prettier-ignore-end -->

## Step 2: Add configuration files

### Step 2.1: Add GitHub workflow configuration

Download [.gp.cicd.json](https://github.com/oslokommune/golden-path-templates/blob/main/templates/gh-terraform-iac/.gp.cicd.json){:target="_blank"} to the repository's root:

```bash title="repo-iac/"
gh api repos/oslokommune/golden-path-templates/contents/templates/gh-terraform-iac/.gp.cicd.json \
  --jq '.content' | base64 -d | jq 'del(.prod)' > .gp.cicd.json
```

Update the values referenced in the table below. You can find them in `common-config.yml` in each of your environment
directories in your IaC repository. Values for `prod` can be ignored for now, unless you apply this guide for your
production environment.

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

### Step 2.2: Add Renovate configuration

Download [renovate.json5](https://github.com/oslokommune/golden-path-templates/blob/main/templates/gh-terraform-iac/renovate.json5){:target="_blank"} to the repository's root:

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

<!-- prettier-ignore-start -->
!!! info "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](../terraform-automation/renovate.md).
<!-- prettier-ignore-end -->

### Step 2.3: Add code owners configuration

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

```text title="repo-iac/.github/CODEOWNERS"
* @oslokommune/<github-team-name>
```

Update these values:

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

## Step 3: Protect your default branch

Your repository automatically inherits a set of branch rulesets from the GitHub organization when you add a specific
custom property to it. These rulesets add a set of required guardrails to your repository.
It is **required** to set up these to protect your default branch (typically `main`).

1. In your repository, go to **Settings > Custom properties** and set `gp-repository-type` to `infra`.
1. After setting the custom property, verify that **Settings > Rulesets** have rules inherited from the organization.

## Step 4: Review repository access

Go to **Settings > Collaborators and teams** and ensure that only a limited number of users, such as your product team, have write access to your repository.

## Step 5: Create a pull request

Add a comment to `config_override.tf` in `cicd-common`.

Create a pull request containing all the files edited in this guide.

## Step 6: Verify plan workflow

Verify that the plan workflow runs and comments on the PR with a Terraform plan for `cicd-common`.

## Step 7: Merge

Merge the PR.

## Step 8: Verify apply workflow

Verify that the apply workflow triggers and applies the `cicd-common` stack.

<!-- prettier-ignore-start -->
!!! Tip
    You can manually trigger the workflows on-demand. Running the `terraform-pr.yml` against all stacks in your
    repository (**Actions > Terraform PR > Run workflow** > `**`) can be especially useful to detect broken or
    drifted stacks.
<!-- prettier-ignore-end -->

## Next step

Set up [AWS Backup](set-up-aws-backup.md) to schedule daily backups of your databases and S3 buckets.
