Skip to content

Commit

Permalink
terraform: Update README.md
Browse files Browse the repository at this point in the history
Signed-off-by: Henri Rosten <henri.rosten@unikie.com>
  • Loading branch information
henrirosten committed Oct 21, 2024
1 parent 340fe39 commit 5b2fada
Showing 1 changed file with 22 additions and 30 deletions.
52 changes: 22 additions & 30 deletions terraform/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,12 @@ terraform
│   ├── binary-cache-sigkey
│   ├── binary-cache-storage
│   ├── builder-ssh-key
│   ├── resources
│   └── workspace-specific
├── state-storage
│   └── tfstate-storage.tf
├── modules
│   ├── arm-builder-vm
│   ├── azurerm-linux-vm
│   └── azurerm-nix-vm-image
├── binary-cache.tf
Expand All @@ -65,55 +67,44 @@ terraform
└── main.tf
```
- The `terraform` directory contains the root terraform deployment files with the VM configurations `binary-cache.tf`, `builder.tf`, and `jenkins-controller.tf` matching the components described in [README-azure.md](./README-azure.md) in its [components section](./README-azure.md#components).
- The `terraform/persistent` directory contains the terraform configuration for parts of the infrastructure that are considered persistent - resources defined under `terraform/persistent` will not be removed even if the ghaf-infra instance is otherwise removed. An example of such persistent ghaf-infra resource is the binary cache storage as well as the binary cache signing key. There may be many 'persistent' infrastructure instances - currently `dev` and `prod` deployments have their own instances of the persistent resources. Section [Multiple Environments with Terraform Workspaces](./README.md#multiple-environments-with-terraform-workspaces) discusses this topic with more details.
- The `terraform/persistent` directory contains the terraform configuration for parts of the infrastructure that are considered persistent - resources defined under `terraform/persistent` will not be removed even if the ghaf-infra instance is otherwise removed. An example of such persistent ghaf-infra resource is the binary cache storage as well as the binary cache signing key. There may be many 'persistent' infrastructure instances - currently `priv` `dev/prod` and `release` deployments have their own instances of the persistent resources. Section [Multiple Environments with Terraform Workspaces](./README.md#multiple-environments-with-terraform-workspaces) discusses this topic with more details.
- The `terraform/state-storage` directory contains the terraform configuration for the ghaf-infra remote backend state storage using Azure storage blob. See section [Initializing Azure State and Persistent Data](./README.md#initializing-azure-state-and-persistent-data) for more details.
- The `terraform/modules` directory contains terraform modules used from the ghaf-infra VM configurations to build, upload, and spin up Azure nix images.

## Initializing Azure State and Persistent Data
This project stores the terraform state in a remote storage in an azure storage blob as configured in [tfstate-storage.tf](./state-storage/tfstate-storage.tf). The benefits of using such remote storage setup are well outlined in [storing state in azure storage](https://learn.microsoft.com/en-us/azure/developer/terraform/store-state-in-azure-storage) and [terraform backend configuration](https://developer.hashicorp.com/terraform/language/settings/backends/configuration).

To initialize the backend storage, use the `terraform-init-sh`:

## Initializing Ghaf-Infra Environment
```bash
# Inside the terraform directory
$ ./terraform-init.sh
# Replace 'workspacename' with the name of the workspace you are going to work with
$ ./terraform-init.sh -w workspacename
[+] Initializing state storage
[+] Initializing persistent data
...
[+] Running terraform init
```
`terraform-init.sh` will not do anything if the initialization has already been done. In other words, it's safe to run the script many times; it will not destroy or re-initialize anything if the init was already executed.

In addition to the shared terraform state, some of the infrastructure resources are also shared between the ghaf-infra instances. `terraform-init.sh` initializes the persistent configuration defined under `terraform/persistent`. There may be many 'persistent' infrastructure instances: currently `dev` and `prod` deployments have their own instances of the persistent resources. Section [Multiple Environments with Terraform Workspaces](./README.md#multiple-environments-with-terraform-workspaces) discusses this topic with more details.

## Multiple Environments with Terraform Workspaces

To support infrastructure development in isolated environments, this project uses [terraform workspaces](https://developer.hashicorp.com/terraform/cli/workspaces).
The main reasons for using terraform workspaces include:
- Different workspaces allow deploying different instances of ghaf-infra. Each instance has a completely separate state data, making it possible to deploy `dev`, `prod`, or even private development instances of ghaf-infra. This makes it possible to first develop and test infrastructure changes in a private development environment, before proposing changes to shared (e.g. `dev` or `prod`) environments. The configuration codebase is the same between all the environments, with the differentiation options defined in the [`main.tf`](./main.tf#L69).
- Parts of the ghaf-infra infrastructure are persistent and shared between different environments. As an example, private `dev` environments share the binary cache storage. This arrangement makes it possible to treat, for instance, `dev` and private ghaf-infra instances dispensable: ghaf-infra instances can be temporary and short-lived as it's easy to spin-up new environments without losing any valuable data. The persistent data is configured outside the root ghaf-infra terraform deployment in the `terraform/persistent` directory. There may be many 'persistent' infrastructure instances - currently `dev` and `prod` deployments have their own instances of the persistent resources. This means that `dev` and `prod` instances of ghaf-infra do **not** share any persistent data. As an example, `dev` and `prod` deployments of ghaf-infra have a separate binary cache storage. The binding to persistent resources from ghaf-infra is done in the [`main.tf`](./main.tf#L166) based on the terraform workspace name and resource location. Persistent data initialization is automatically done with `terraform-init.sh` script.
- Currently, the following resources are defined 'persistent', meaning `dev` and `prod` instances do not share the following resources:
- Binary cache storage: [`binary-cache-storage.tf`](./persistent/binary-cache-storage/binary-cache-storage.tf)
- Binary cache signing key: [`binary-cache-sigkey.ft`](./persistent/binary-cache-sigkey/binary-cache-sigkey.tf)
- Builder ssh key: [`builder-ssh-key.tf`](./persistent/builder-ssh-key/builder-ssh-key.tf)
- Different workspaces allow deploying different instances of ghaf-infra. Each instance has a completely separate state data, making it possible to deploy `dev`, `prod`, `release` or even private development instances of ghaf-infra. This makes it possible to first develop and test infrastructure changes in a private development environment, before proposing changes to shared (e.g. `dev` or `prod`) environments. The configuration codebase is the same between all the environments, with the differentiation options defined in the [`main.tf`](./main.tf#L105).
- Parts of the ghaf-infra infrastructure are persistent and shared between different environments. As an example, private environments share the binary cache storage. This arrangement makes it possible to treat, for instance, private ghaf-infra instances dispensable: ghaf-infra instances can be temporary and short-lived as it's easy to spin-up new environments without losing any valuable data. The persistent data is configured outside the root ghaf-infra terraform deployment in the `terraform/persistent` directory. There may be many 'persistent' infrastructure instances - currently `priv`, `dev/prod` and `release` deployments have their own instances of the persistent resources. This means that `priv`, `dev/prod` and `release` instances of ghaf-infra do **not** share any persistent data. As an example, `priv` and `prod` deployments of ghaf-infra have a separate binary cache storage. The binding to persistent resources from ghaf-infra is done in the [`main.tf`](./main.tf) based on the terraform workspace name and resource location. Persistent data initialization is automatically done with `terraform-init.sh` script.

To help facilitate the usage of terraform workspaces in setting-up distinct copies of ghaf-infra, one can [use terraform workspaces from the command line](https://developer.hashicorp.com/terraform/cli/workspaces#managing-cli-workspaces) or consider using the helper script provided at [`terraform-playground.sh`](./terraform-playground.sh). Below, for the sake of example, we use the [`terraform-playground.sh`](./terraform-playground.sh) to setup a private deployment instance of ghaf-infra:
To help facilitate the usage of terraform workspaces in setting-up distinct copies of ghaf-infra, one can [use terraform workspaces from the command line](https://developer.hashicorp.com/terraform/cli/workspaces#managing-cli-workspaces). Below, for the sake of example, we setup a private deployment instance of ghaf-infra:

```bash
# Activate private development environment
$ ./terraform-playground.sh activate
# ...
[+] Done, use terraform [validate|plan|apply] to work with your dev infra
```
Which sets-up a terraform workspace for your private development environment:
```bash
# List the current terraform worskapce
$ terraform workspace list
Terraform workspaces:
# Activate private development environment 'henri'
❯ ./terraform-init.sh -w henri
[+] Using state 'ghaf-infra-0-state-eun'
[+] Using persistent 'ghaf-infra-0-persistent-eun'
[+] Initializing workspace-specific persistent
[+] Initializing workspace
[+] Listing workspaces:
default
dev
* henrirosten # <-- indicates active workspace
dev0
* henri # <-- indicates active workspace
prod
release
```

## Terraform workflow
Expand All @@ -134,9 +125,10 @@ $ terraform validate
# Use terraform workspace select <workspace_name> to switch workspaces
$ terraform workspace list
default
dev
* henrirosten # <== This example deploys to private dev environment
dev0
* henri # <== This example deploys to private dev environment
prod
release

# Show what actions terraform would take on apply:
$ terraform plan
Expand Down

0 comments on commit 5b2fada

Please sign in to comment.