---
title: Terraform-based deployment of EDP
linkTitle: Terraform
weight: 10
description: >
  As-code definitions of EDP clusters, so they can be deployed reliably and consistently on OTC whenever needed.
---

## Overview

The [infra-deploy](https://edp.buildth.ing/DevFW/infra-deploy) and [infra-catalogue](https://edp.buildth.ing/DevFW/infra-catalogue) repositories work together to provide a framework for deploying Edge Developer Platform instances.

`infra-catalogue` contains individual, atomic infrastructure components: `terraform` modules and `terragrunt` [units](https://edp.buildth.ing/DevFW/infra-catalogue/src/branch/main/units) and [stacks](https://edp.buildth.ing/DevFW/infra-catalogue/src/branch/main/stacks), such as [Kubernetes clusters](https://edp.buildth.ing/DevFW/infra-catalogue/src/branch/main/modules/kubernetes) and [Postgres databases](https://edp.buildth.ing/DevFW/infra-catalogue/src/branch/main/units/postgres/terragrunt.hcl).

`infra-deploy` then contains full [definitions](https://edp.buildth.ing/DevFW/infra-deploy/src/branch/main/prod) of stacks built using these components - such as the production site at [edp.buildth.ing](https://edp.buildth.ing/DevFW/infra-deploy/src/branch/main/prod/edp). It also includes [scripts](https://edp.buildth.ing/DevFW/infra-deploy/src/branch/main/scripts) with which to deploy these stacks.

Note that both repositories rely on the wide range of features available on [OTC](https://console.otc.t-systems.com). Several of these features, such as S3-compatible storage and on-demand managed Postgres instances, are not yet available on more sovereign clouds such as [Edge](https://hub.apps.edge.platform.mg3.mdb.osc.live/), so these are not currently supported.

## Key Features

* 'Catalogue' of infrastructure stacks to be used in deployments
* Definition of deployment stacks for each environment in prod or dev
* Scripts to govern deployment, installation and drift-correction of EDP

## Purpose in EDP

For our Edge Developer Platform to be reliable it must be deployable in a consistent manner. When errors occur, or after any manual alterations, the system can then be safely reset to a working state. This state should be provided in code to allow for automated validation and deployment, and to allow it to be deployed from an always-identical CI/CD pipeline rather than a variable local deployment environment.

## Repositories

**Infra-deploy**: [https://edp.buildth.ing/DevFW/infra-deploy](https://edp.buildth.ing/DevFW/infra-deploy)

**Infra-catalogue**: [https://edp.buildth.ing/DevFW/infra-catalogue](https://edp.buildth.ing/DevFW/infra-catalogue)

## Getting Started

### Prerequisites

* [Docker](https://docs.docker.com/)
* [Kubernetes management](https://kubernetes.io/docs/reference/kubectl/)
* Access to [OTC](https://console.otc.t-systems.com/console/)
* HashiCorp [Terraform](https://developer.hashicorp.com/terraform) or its open-source equivalent, [OpenTofu](https://opentofu.org/)
* [Terragrunt](https://terragrunt.gruntwork.io/), an orchestrator for Terraform stacks

### Quick Start

1. Set up OTC credentials per [README section](https://edp.buildth.ing/DevFW/infra-deploy#installation-on-otc)
2. Set cluster environment and run install script per [README section](https://edp.buildth.ing/DevFW/infra-deploy#using-the-edpbuilder)

Alternatively, manually trigger automated [deployment pipeline](https://edp.buildth.ing/DevFW/infra-deploy/actions?workflow=deploy.yaml).
- You will be asked for essential information like the deployment name and tenant.
- Any fields marked `INITIAL` only need to be set when first creating an environment
- Thereafter, the cached values are used and the `INITIAL` values provided to the pipeline are ignored.
    - Specifically, they are cached in a `terragrunt.values.hcl` file within `infra-deploy/<tenant>/<cluster-name>`, where both variables are set in the pipeline
    - e.g. [prod/edp](https://edp.buildth.ing/DevFW/infra-deploy/src/branch/main/prod/edp/terragrunt.values.hcl) or [nonprod/garm-provider-test](https://edp.buildth.ing/DevFW/infra-deploy/src/commit/189632811944d3d3bc41e26c09262de8f215f82b/non-prod/garm-provider-test/terragrunt.values.hcl)

### Verification

After the deploymenet completes, and a short startup time, you should be able to access your Forgejo instance at `<cluster-name>.buildth.ing` (production tenant) or `<cluster-name>.t09.de` (non-prod tenant). `<cluster-name>` is the name you provided in the deployment pipeline, or the $CLUSTER_ENVIRONMENT variable when running manually.

For example, the primary production cluster is called [edp](https://edp.buildth.ing/DevFW/infra-deploy/src/branch/main/prod/edp) and can be accessed at [edp.buildth.ing](https://edp.buildth.ing).

#### Screens

Deployment using production pipeline:

![Running the deployment pipeline](../deploy-pipeline.png)
...
![Successful deploy pipeline logs](../deploy-pipeline-success.png)

## Configuration

Configuration of clusters is done in two ways. The first, mentioned above, is to provide `INITIAL` configuration when creating a new cluster. Thereafter, configuration is done within the relevant `infra-deploy/<tenant>` directory (e.g. [prod/edp](https://edp.buildth.ing/DevFW/infra-deploy/src/branch/main/prod/edp)). Variables may be changed within the [terragrunt.values.hcl](https://edp.buildth.ing/DevFW/infra-deploy/src/branch/main/prod/edp/terragrunt.values.hcl) file, but equally the [terragrunt.stack.hcl](https://edp.buildth.ing/DevFW/infra-deploy/src/branch/main/prod/edp/terragrunt.stack.hcl) file contains references to the lower-level code set up in `infra-catalogue`.

These are organised in layers, according to Terragrunt's natural structure. First is a [stack](https://edp.buildth.ing/DevFW/infra-catalogue/src/branch/main/stacks), a high-level abstraction for a whole cluster. This in turn [references](https://edp.buildth.ing/DevFW/infra-catalogue/src/branch/main/stacks/forgejo/terragrunt.stack.hcl) terragrunt [units](https://edp.buildth.ing/DevFW/infra-catalogue/src/branch/main/units), which in turn are wrappers around standard _Terraform_ [modules](https://edp.buildth.ing/DevFW/infra-catalogue/src/branch/main/modules).
When deployed, the Terraform modules require a `provider.tf` file which is automatically generated by Terragrunt using [tenant-level](https://edp.buildth.ing/DevFW/infra-deploy/src/branch/main/prod/tenant.hcl) and [global](https://edp.buildth.ing/DevFW/infra-deploy/src/branch/main/root.hcl) configuration stored in `infra-deploy`.

When deploying manually (e.g. with [install.sh](https://edp.buildth.ing/DevFW/infra-deploy/src/branch/main/install.sh)), you can observe these layers as Terragrunt will cache them on your machine, within the `.terragrunt-stack/` directory generated within [/\<tenant\>/\<cluster-name\>/](https://edp.buildth.ing/DevFW/infra-deploy/src/branch/main/prod/edp).

## Troubleshooting

### Version updates

**Problem**: Updates to `infra-catalogue` are not immediately reflected in deployed clusters, even after running [deploy](https://edp.buildth.ing/DevFW/infra-deploy/actions?workflow=deploy.yaml).

**Solution**: Versions must be updated.
Each cluster deployment specifies a [catalogue version](https://edp.buildth.ing/DevFW/infra-deploy/src/commit/189632811944d3d3bc41e26c09262de8f215f82b/prod/edp/terragrunt.values.hcl#L7) in its `terragrunt.values.hcl`; this refers to a tag in [infra-catalogue](https://edp.buildth.ing/DevFW/infra-catalogue/releases/tag/v2.0.6). Within `infra-catalogue`, stacks reference units and modules from the same tag.

Thus, to test a new change to `infra-catalogue`, first make a new [tag](https://edp.buildth.ing/DevFW/infra-catalogue/tags), then update the relevant [values file](https://edp.buildth.ing/DevFW/infra-deploy/src/branch/main/prod/edp/terragrunt.values.hcl) to point to it.


## Status

**Maturity**: TRL-9

## Additional Resources

- [Terraform](https://developer.hashicorp.com/terraform)
- [OpenTofu](https://opentofu.org/), the community-driven replacement for Terraform
- [Terragrunt](https://terragrunt.gruntwork.io/)
