Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
andreygubarev committed May 16, 2024
1 parent 79df0ab commit 5835bbb
Show file tree
Hide file tree
Showing 30 changed files with 282 additions and 0 deletions.
32 changes: 32 additions & 0 deletions .github/workflows/github-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Github Release

on:
pull_request:
branches:
- main
push:
branches:
- main
tags:
- "v*.*.*"

jobs:
release:
permissions:
contents: write
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Check if pre-release
id: prerelease
run: |
echo "prerelease=$(if [[ "${{ github.ref }}" == *"-rc"* ]]; then echo "true"; else echo "false"; fi)" >> "$GITHUB_OUTPUT"
- name: Release
uses: softprops/action-gh-release@v2
with:
prerelease: ${{ steps.prerelease.outputs.prerelease }}
generate_release_notes: true
9 changes: 9 additions & 0 deletions cookiecutter.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"templates": {
"terraform": {
"path": "./terraform/",
"title": "Terraform",
"description": "Templates for Terraform"
}
}
}
111 changes: 111 additions & 0 deletions terraform/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# Cookiecutter Template for Terragrunt

Template supports the following features:

- `direnv` for environment variables management
- `tfenv` for Terraform version management
- `tgenv` for Terragrunt version management
- `sops` for secrets management
- `yaml` based configuration (for better multi-line values support)

## Usage

1. Generate your project from the project template using latest version:

```bash
cookiecutter gh:andreygubarev/cookiecutter-terraform
```

2. Put your SOPS configuration into `.sops.yaml` file. For example:

```yaml
---
creation_rules:
- pgp:
```

3. Encode your secrets using `sops`:

```bash
find . -name "*.tfvars.sops.yaml" | xargs -I {} sops -e -i {}
```

4. Enable `direnv`:

```bash
direnv allow .
```

5. Put your Terraform backend configuration into `workspaces/<workspace>/terraform.tf` file.

6. Put your Terraform providers into `modules/<module>/providers.tf` file.

7. Initialize your project:

```bash
make workspace
cd workspaces/<workspace>
# tfenv install
terragrunt init
terragrunt apply
```

## Documentation

### Directory Structure

#### Encryption

Git is used as a storage for encrypted secrets. SOPS is used to encrypt/decrypt secrets:

`.sops.yaml` - SOPS configuration file

Note: Git repository must not contain any unencrypted secrets.

#### Environment

Environment variables are primarily used to configure Terraform providers (e.g. AWS credentials).

`.env` - user environment variables

Direnv is used to manage environment variables and automatically load them when changing directories.

`.envrc` - direnv configuration file

#### Versioning

Terraform and Terragrunt versions are managed using `tfenv` and `tgenv` respectively.

`.terraform-version` - Terraform version

`.terragrunt-version` - Terragrunt version

#### Terragrunt Workspaces

Workspaces are used to separate environments (e.g. dev, stage, prod) and instances of the same environment (e.g. dev1, dev2, dev3). Workspaces are stored in `workspaces` directory. Terraform workspaces are not used directly. Instead, separate folders are used for each workspace.

#### Terraform Modules

Terraform modules are stored in `modules` directory. Each module is stored in a separate folder. Module name is used as a folder name. Module folder should follow the structure: https://developer.hashicorp.com/terraform/language/modules/develop/structure

Using modules allows to reuse Terraform code across different workspaces. Every workspace uses single module which is configured in `workspaces/<workspace>/terragrunt.hcl` file in `terraform` block.

#### Terraform Variables

Terraform variables are stored in `workspaces/<workspace>/terraform.tfvars.yaml` file. Each workspace has its own variables file. Variables file is a YAML file. YAML format allows to use multi-line values.

SOPS is used to encrypt/decrypt variables files (`.tfvars.yaml.sops`).

Variables are passed to Terraform module using `input` block in `terragrunt.hcl` file. Terraform module variables are stored in `modules/<module>/variables.tf` file.

#### Terraform Backend

Terraform backend configuration is stored in `workspaces/<workspace>/terraform.tf` file. Each workspace has its own backend configuration file.

## Reference

- Terraform: https://www.terraform.io/
- Terragrunt: https://terragrunt.gruntwork.io/
- tfenv: https://github.com/tfutils/tfenv
- tgenv: https://github.com/cunymatthieu/tgenv
- SOPS: https://github.com/getsops/sops
8 changes: 8 additions & 0 deletions terraform/cookiecutter-terragrunt.code-workspace
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"folders": [
{
"path": "."
}
],
"settings": {}
}
19 changes: 19 additions & 0 deletions terraform/cookiecutter.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"templates": {
"terraform": {
"path": "./templates/terraform/",
"title": "Terraform Project",
"description": "Template for Terraform Project"
},
"terraform_module": {
"path": "./templates/terraform_module/",
"title": "Terraform Module",
"description": "Template for Terraform Module"
},
"terraform_workspace": {
"path": "./templates/terraform_workspace/",
"title": "Terraform Workspace",
"description": "Template for Terraform Workspace"
}
}
}
5 changes: 5 additions & 0 deletions terraform/templates/terraform/cookiecutter.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "",
"terraform_version": "1.5.6",
"terragrunt_version": "0.48.7"
}
15 changes: 15 additions & 0 deletions terraform/templates/terraform/{{ cookiecutter.name }}/.envrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env bash

### direnv ####################################################################
dotenv_if_exists

WORKDIR=$(CDPATH="cd -- $(dirname -- "$0")" && pwd -P)
export WORKDIR

### terraform #################################################################
export TF_PLUGIN_CACHE_DIR=${WORKDIR}/.terraform
mkdir -p "${TF_PLUGIN_CACHE_DIR}"

### terragrunt ################################################################
export TERRAGRUNT_DOWNLOAD=${WORKDIR}/.terragrunt-cache
mkdir -p "${TERRAGRUNT_DOWNLOAD}"
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Environment
.env

# Terraform
.terraform
.terragrunt-cache
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
# TODO: add SOPS config
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{ cookiecutter.terraform_version }}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{ cookiecutter.terragrunt_version }}
29 changes: 29 additions & 0 deletions terraform/templates/terraform/{{ cookiecutter.name }}/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
.DEFAULT_GOAL := help
.PHONY: help
help: ## Show this help
@egrep -h '\s##\s' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'

.PHONY: format
format: ## Format Terraform files
terraform fmt -recursive

.PHONY: install
install: ## Install Terraform and Terragrunt
tfenv install
tgenv install

.PHONY: prerequisities
prerequisities: ## Install Prerequisities
brew install direnv sops tfenv tgenv

.PHONY: module
module: ## Create a new Terraform Module
cookiecutter gh:andreygubarev/cookiecutter-terraform \
--directory=templates/terraform_module \
--output-dir=modules

.PHONY: workspace
workspace: ## Create a new Terraform Workspace
cookiecutter gh:andreygubarev/cookiecutter-terraform \
--directory=templates/terraform_workspace \
--output-dir=workspaces
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
inputs = merge(
yamldecode(file("${get_terragrunt_dir()}/terraform.tfvars.yaml")),
yamldecode(sops_decrypt_file("${get_terragrunt_dir()}/terraform.tfvars.sops.yaml")),
)
Empty file.
5 changes: 5 additions & 0 deletions terraform/templates/terraform_module/cookiecutter.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "",
"terraform_version": "1.5.6",
"terragrunt_version": "0.48.7"
}
Empty file.
Empty file.
Empty file.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
terraform {
required_version = "{{ cookiecutter.terraform_version }}"

required_providers {

}
}
Empty file.
Empty file.
5 changes: 5 additions & 0 deletions terraform/templates/terraform_workspace/cookiecutter.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "",
"terraform_version": "1.5.6",
"terragrunt_version": "0.48.7"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env bash

### direnv ####################################################################
source_up
dotenv_if_exists

# env_vars_required AWS_PROFILE

### terraform #################################################################
export TF_DATA_DIR="$PWD/.terraform"
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{ cookiecutter.terraform_version }}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
terraform {
# TODO: add backend
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
---
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
---
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
include "root" {
path = find_in_parent_folders("terragrunt.hcl")
}

terraform {
source = "${path_relative_from_include()}//modules/{{ cookiecutter.name }}/"
}

0 comments on commit 5835bbb

Please sign in to comment.