Skip to content

Commit

Permalink
initial framework, converted for AWS
Browse files Browse the repository at this point in the history
  • Loading branch information
kpeder committed Apr 9, 2024
1 parent b40284e commit a2d20e7
Show file tree
Hide file tree
Showing 22 changed files with 792 additions and 0 deletions.
57 changes: 57 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
.PHONY: help
help:
@echo 'make <target>'
@echo ''
@echo 'Targets:'
@echo ' help Show this help'
@echo ' pre-commit Run pre-commit checks'
@echo ''
@echo ' aws_gitlab_clean Clean up state files'
@echo ' aws_gitlab_configure Configure the deployment'
@echo ' aws_gitlab_deploy Deploy configured resources'
@echo ' aws_gitlab_init Initialize modules, providers'
@echo ' aws_gitlab_install Install Terraform, Terragrunt'
@echo ' aws_gitlab_lint Run Go linters'
@echo ' aws_gitlab_plan Show deployment plan'
@echo ' aws_gitlab_test Run deployment tests'
@echo ''

.PHONY: pre-commit
pre-commit:
@pre-commit run -a

.PHONY: aws_gitlab_clean
aws_gitlab_clean:
@cd aws/gitlab && chmod +x ./scripts/prune_caches.sh && ./scripts/prune_caches.sh .
@cd aws/gitlab/test && rm -f go.mod go.sum

.PHONY: aws_gitlab_configure
aws_gitlab_configure:
@cd aws/gitlab && ./scripts/configure.sh -e dev -o kpeder -p us-east-1 -s us-west-1 -t devops

.PHONY: aws_gitlab_deploy
aws_gitlab_deploy: aws_gitlab_configure aws_gitlab_init
@cd aws/gitlab/test && go test -v

.PHONY: aws_gitlab_init
aws_gitlab_init: aws_gitlab_configure
@cd aws/gitlab && terragrunt run-all init
@cd aws/gitlab/test && go mod init aws_gitlab_test.go; go mod tidy

.PHONY: aws_gitlab_install
aws_gitlab_install:
@chmod +x ./scripts/*.sh
@sudo ./scripts/install_terraform.sh -v ./aws/gitlab/versions.yaml
@sudo ./scripts/install_terragrunt.sh -v ./aws/gitlab/versions.yaml

.PHONY: aws_gitlab_lint
aws_gitlab_lint: aws_gitlab_configure aws_gitlab_init
@cd aws/gitlab/test && golangci-lint run --print-linter-name --verbose aws_gitlab_test.go

.PHONY: aws_gitlab_plan
aws_gitlab_plan: aws_gitlab_configure aws_gitlab_init
@cd aws/gitlab && terragrunt run-all plan

.PHONY: aws_gitlab_test
aws_gitlab_test: aws_gitlab_configure aws_gitlab_lint
@cd aws/gitlab/test && go test -v -destroy
51 changes: 51 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
## Terragrunt Deployment Example
Example Terragrunt deployment that includes Go test routines using Terratest.

### Decision Records
This repository uses architecture decision records to record design decisions about important elements of the solution.

The ADR index is available [here](./docs/decisions/index.md).

### Requirements
Tested on Go version 1.21 on Ubuntu Linux.

Uses installed packages:
```
awscli
golangci-lint
make
pre-commit
terraform
terragrunt
```

### Configuration
1. Install the packages listed above.
1. Make a copy of the aws/aws.yaml file, named local.aws.yaml, and fill in the fields with configuration values for the target platform.
1. Configure an AWS access key for Terraform provider to use to access the platform:
```
$ aws configure
```
1. It's recommended to deploy a build project and folder first, and to use this project in the configuration for additional deployments. The build project can be deployed and managed using this framework with a couple of additional steps to create a local state configuration and then to migrate state to a remote state configuration after the project and bucket are created. ALternatively, the build resources can be pre-created and then imported into the framework using the import command. These considerations are not addressed in this example.
### Deployment
Automated installation configuration, and deployment steps are managed using Makefile targets. Use ```make help``` for a list of configured targets:
```
$ make help
make <target>

Targets:
help Show this help
pre-commit Run pre-commit checks

aws_gitlab_clean Clean up state files
aws_gitlab_configure Configure the deployment
aws_gitlab_deploy Deploy configured resources
aws_gitlab_init Initialize modules, providers
aws_gitlab_install Install Terraform, Terragrunt
aws_gitlab_lint Run Go linters
aws_gitlab_plan Show deployment plan
aws_gitlab_test Run deployment tests
```
Note that additional targets can be added in order to configure multiple environments, for example to create development and production environments.
2 changes: 2 additions & 0 deletions aws/aws.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
prefix: "" # prefix to use to uniquely identify and name resources managed under this structure, should be 3-5 characters in length
40 changes: 40 additions & 0 deletions aws/aws_gitlab_terragrunt.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# configure gcs bucket dynamically.
remote_state {
backend = "gcs"
config = {
bucket = format("%s-%s-terraform-state", local.platform.prefix, format("%s-environment", local.environment.environment))
prefix = path_relative_to_include()
location = local.multiregion.region
project = local.platform.build_project
skip_bucket_creation = false
skip_bucket_versioning = false
}
}

locals {
default_yaml_path = find_in_parent_folders("empty.yaml") # terragrunt function for input search (not implemented).
platform = fileexists(find_in_parent_folders("local.gcp.yaml")) ? yamldecode(file(find_in_parent_folders("local.gcp.yaml"))) : yamldecode(file(find_in_parent_folders("gcp.yaml")))
environment = yamldecode(file(find_in_parent_folders("env.yaml")))
multiregion = yamldecode(file(find_in_parent_folders("reg-multi/region.yaml")))
versions = yamldecode(file(find_in_parent_folders("versions.yaml")))
}

terragrunt_version_constraint = "${format("~> %s.0", local.versions.terragrunt_binary_version)}"
terraform_version_constraint = "${format("~> %s.0", local.versions.terraform_binary_version)}"

generate "provider" {
path = "provider_override.tf"
if_exists = "overwrite"
contents = <<EOF
terraform {
required_providers {
google = {
version = "${format("~> %s.0", local.versions.google_provider_version)}"
}
google-beta = {
version = "${format("~> %s.0", local.versions.google_provider_version)}"
}
}
}
EOF
}
1 change: 1 addition & 0 deletions aws/empty.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
---
23 changes: 23 additions & 0 deletions aws/gitlab/env.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
environment: dev
labels:
deployment: kped
environment: dev
owner: kpeder
team: devops
locations:
multiregion: MREGION
primary: PREGION
secondary: SREGION

dependencies:
example_folder_dependency_path: "global/folders/example"
example_folder_mock_outputs:
id: "123456789012"
name: "kped-dev-example-folder"

example_project_dependency_path: "global/projects/example"
example_project_mock_outputs:
project_id: "kped-dev-example"
project_name: "kped-dev-example"
project_number: "123456789012"
4 changes: 4 additions & 0 deletions aws/gitlab/reg-primary/region.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
region: "us-east-2"
location: "us-east-2"
zone_preference: "a"
4 changes: 4 additions & 0 deletions aws/gitlab/reg-secondary/region.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
region: "us-west-2"
location: "us-west-2"
zone_preference: "a"
82 changes: 82 additions & 0 deletions aws/gitlab/scripts/configure.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#!/bin/bash

set -e

function exit_with_msg {
echo "${1}"
exit 1
}

while [ $# -gt 0 ]; do
case "${1}" in
-e|--environment)
ENVIRONMENT="${2}"
shift
;;
-h|--help)
echo "Usage:"
echo "$0 \\"
echo " -e|--environment <environment_name>"
echo " [-h|--help]"
echo " -o|--owner <owner>"
echo " -p|--primaryregion <primary_region>"
echo " -s|--secondaryregion <secondary_region>"
echo " -t|--team <team>"
exit 0
;;
-o|--owner)
OWNER="${2}"
shift
;;
-p|--primaryregion)
PREGION="${2}"
shift
;;
-s|--secondaryregion)
SREGION="${2}"
shift
;;
-t|--team)
TEAM="${2}"
shift
;;
*)
exit_with_msg "Error: Invalid argument '${1}'."
esac
shift
done

if [[ -f ../local.aws.yaml ]]; then
PREFIX=$(cat ../local.aws.yaml | grep ^prefix | awk -F '[: #"]+' '{print $2}')
else
PREFIX=$(cat ../aws.yaml | grep ^prefix | awk -F '[: #"]+' '{print $2}')
fi

[[ -z ${PREFIX} ]] && exit_with_msg "Can't locate deployment prefix. Exiting."
[[ ${#PREFIX} > 5 ]] && exit_with_msg "Prefix '${PREFIX}' is too long. Exiting."

[[ -z ${ENVIRONMENT} ]] && exit_with_msg "-e|--environment is a required parameter. Exiting."
[[ -z ${OWNER} ]] && exit_with_msg "-o|--owner is a required parameter. Exiting."
[[ -z ${PREGION} ]] && exit_with_msg "-p|--primaryregion is a required parameter. Exiting."
[[ -z ${SREGION} ]] && exit_with_msg "-s|--secondaryregion is a required parameter. Exiting."
[[ -z ${TEAM} ]] && exit_with_msg "-t|--team is a required parameter. Exiting."

echo "Deployment Owner: ${OWNER}"
echo "Environment: ${ENVIRONMENT}"
echo "Name Prefix: ${PREFIX}"
echo "Primary Region: ${PREGION}"
echo "Secondary Region: ${SREGION}"
echo "Support Team: ${TEAM}"

cp templates/env.tpl env.yaml
cp templates/region.tpl reg-primary/region.yaml
cp templates/region.tpl reg-secondary/region.yaml

sed -i -e "s:ENVIRONMENT:${ENVIRONMENT}:g" env.yaml
sed -i -e "s:OWNER:${OWNER}:g" env.yaml
sed -i -e "s:PREFIX:${PREFIX}:g" env.yaml
sed -i -e "s:REGION:${PREGION}:g" reg-primary/region.yaml
sed -i -e "s:ZONE:a:g" reg-primary/region.yaml
sed -i -e "s:REGION:${SREGION}:g" reg-secondary/region.yaml
sed -i -e "s:ZONE:a:g" reg-secondary/region.yaml
sed -i -e "s:TEAM:${TEAM}:g" env.yaml
32 changes: 32 additions & 0 deletions aws/gitlab/scripts/prune_caches.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/bin/bash

set -e

function exit_with_msg {
echo "${1}"
exit 1
}

while [ $# -gt 0 ]; do
case "${1}" in
-h|--help)
echo "Usage:"
echo "$0 \\"
echo " [-h : --help]"
echo " [<target directory>]"
exit 0
;;
*)
[[ -d ${1} ]] || exit_with_msg "directory ${1} not found"
TARGET=${1}
esac
shift
done

if [[ -z ${TARGET} ]]; then
TARGET=.
echo "Directory not specified; using current directory."
fi

find ${TARGET} -type d -name ".terragrunt-cache" -prune -exec rm -rf {} \;
find ${TARGET} -type f -name ".terraform.lock.hcl" -prune -exec rm -rf {} \;
12 changes: 12 additions & 0 deletions aws/gitlab/templates/env.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
environment: ENVIRONMENT
labels:
deployment: PREFIX
environment: ENVIRONMENT
owner: OWNER
team: TEAM
locations:
primary: PREGION
secondary: SREGION

dependencies:
4 changes: 4 additions & 0 deletions aws/gitlab/templates/region.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
region: "REGION"
location: "REGION"
zone_preference: "ZONE"
Loading

0 comments on commit a2d20e7

Please sign in to comment.