Практичне завдання
Мета
Налаштування Terraform IaC у GitLab
Критерії приймання
- Використання власних модулів у Terraform (мінімум треба розбити на модулі:
network,instance) - Має бути 1 production енвайромент і безліч динамічних під кожну гілку
- Динамічний енваромент має вимикатися через 55хв після створення
- Terraform-стейт має зберігатися у GitLab
Надання відповіді
Результати надати у вигляді MR в Google Classroom
Приклад
# Terraform/Base
#
# The purpose of this template is to provide flexibility to the user so
# they are able to only include the jobs that they find interesting.
#
# Therefore, this template is not supposed to run any jobs. The idea is to only
# create hidden jobs. See: https://docs.gitlab.com/ee/ci/jobs/#hide-jobs
#
# There is a more opinionated template which we suggest the users to abide,
# which is the lib/gitlab/ci/templates/Terraform.gitlab-ci.yml
image:
name: "$CI_TEMPLATE_REGISTRY_HOST/gitlab-org/terraform-images/releases/1.1:v0.43.0"
variables:
TF_ROOT: ${CI_PROJECT_DIR}/terraform/envs/prod # The relative path to the root directory of the Terraform project
TF_STATE_NAME: ${CI_COMMIT_REF_SLUG} # The name of the state file used by the GitLab Managed Terraform state backend
TF_VAR_stage: ${CI_COMMIT_REF_SLUG}
# CI_DEBUG_TRACE: "true"
cache:
key: "${CI_COMMIT_REF_SLUG}"
paths:
- ${TF_ROOT}/.terraform/
- ${TF_ROOT}/*.pem
- ${TF_ROOT}/.terraform.lock.hcl
- ${TF_ROOT}/deploy.env
stages:
- validate
- build
- deploy
- provision
- cleanup
terraform_fmt:
stage: validate
script:
- cd "${TF_ROOT}"
- gitlab-terraform fmt
allow_failure: true
rules:
- if: $CI_MERGE_REQUEST_ID
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
- if: $CI_PIPELINE_SOURCE == "web"
terraform_validate:
stage: validate
script:
- cd "${TF_ROOT}"
- gitlab-terraform validate
rules:
- if: $CI_MERGE_REQUEST_ID
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
- if: $CI_PIPELINE_SOURCE == "web"
docker_build:
image: docker:latest
stage: build
services:
- docker:dind
before_script:
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
script:
- docker pull $CI_REGISTRY_IMAGE:latest || true
- docker build --cache-from $CI_REGISTRY_IMAGE:latest -t "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG" .
- docker tag $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG $CI_REGISTRY_IMAGE:latest
- docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG"
- docker push $CI_REGISTRY_IMAGE:latest
rules:
- if: $CI_MERGE_REQUEST_ID
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
- if: $CI_PIPELINE_SOURCE == "web"
terraform_build:
stage: build
script:
- cd "${TF_ROOT}"
- gitlab-terraform plan
- gitlab-terraform plan-json
resource_group: ${TF_STATE_NAME}
artifacts:
paths:
- ${TF_ROOT}/plan.cache
reports:
terraform: ${TF_ROOT}/plan.json
rules:
- if: $CI_MERGE_REQUEST_ID
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
- if: $CI_PIPELINE_SOURCE == "web"
review_app:
stage: deploy
script:
- cd "${TF_ROOT}"
- gitlab-terraform apply
resource_group: ${TF_STATE_NAME}
environment:
name: review/$CI_COMMIT_REF_SLUG
url: $DYNAMIC_ENVIRONMENT_URL
on_stop: cleanup_job
auto_stop_in: 55 minutes
artifacts:
paths:
- ${TF_ROOT}/*.pem
- ${TF_ROOT}/deploy.env
expire_in: 1 day
reports:
dotenv: ${TF_ROOT}/deploy.env
rules:
- if: $CI_MERGE_REQUEST_ID
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
- if: $CI_PIPELINE_SOURCE == "web"
review_app_provision:
image: ubuntu:22.04
stage: provision
script:
- apt-get update && DEBIAN_FRONTEND=noninteractive apt install -y git git-secret gpg ansible rsync
- echo "$GPG_PRIVATE_KEY" | tr ',' '\n' > ./private_key.gpg
- gpg --batch --yes --pinentry-mode loopback --import private_key.gpg
- git secret reveal
- cd "${TF_ROOT}"
- source deploy.env
- ANSIBLE_CONFIG=../../../ansible/ansible.cfg ansible-playbook --user=ubuntu -e host=$DYNAMIC_ENVIRONMENT_IP -e key=$TF_ROOT/$DYNAMIC_ENVIRONMENT_KEY -e ci_registry_image=$CI_REGISTRY_IMAGE -e ci_commit_ref_slug=$CI_COMMIT_REF_SLUG -e ci_registry=$CI_REGISTRY -e ci_registry_user=$CI_REGISTRY_USER -e ci_registry_password=$CI_REGISTRY_PASSWORD ../../../ansible/deploy.yaml
resource_group: ${TF_STATE_NAME}
variables:
ANSIBLE_FORCE_COLOR: "true"
rules:
- if: $CI_MERGE_REQUEST_ID
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
- if: $CI_PIPELINE_SOURCE == "web"
cleanup_job:
stage: cleanup
script:
- cd "${TF_ROOT}"
- gitlab-terraform destroy
resource_group: ${TF_STATE_NAME}
environment:
name: review/$CI_COMMIT_REF_SLUG
action: stop
rules:
- if: $CI_MERGE_REQUEST_ID
when: manual
allow_failure: true
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
when: manual
allow_failure: true
- if: $CI_PIPELINE_SOURCE == "web"
when: manual
allow_failure: true