Pré-requisitos
Access Keys AWS
GitLab
Serviços AWS
SQS
S3
Usamos SQS e S3 a título de exemplo nesse laboratório.
Construção
- Os passos abaixo são basicamente para preparar o repositório no GitLab, criando a branch 'development' e fazendo commit e push dos arquivos para ela:
- Criamos também a branch 'staging':
- No GitLab, crie o environment 'default', também 'development' e 'staging' caso ainda não tenha sido criados após o primero push:
- Crie as variáveis no GitLab, onde cada 'AWS_ACCESS_KEY_ID' e 'AWS_SECRET_ACCESS_KEY' correspondem as contas de destino do provisionamento de acordo com environment:
Cuidado com essas informações de chave!
- Execute o pipeline para a branch 'development'. Abaixo executamos manualmente, porém esse processo é automático assim que enviamos atualizações para branch:
- Execute o pipeline para a branch ‘staging’:
- Merge request de 'staging' para 'main', esse é o deploy em produção:
- Verifique os recursos provisionados em cada conta AWS. Note que, os recursos de development e staging estão na mesma conta, é porque utilizamos a mesma chave para os dois ambientes. Já os recursos de produção, estão em outra conta AWS:
- Podemos também acionar manualmente o stage cleanup que realiza o terraform destroy:
- Veja que o GitLab está cuidando dos Terraform states para nós:
O arquivo gitlab-ci.yml é responsável por toda orquestração do pipeline:
image: registry.gitlab.com/gitlab-org/terraform-images/stable:latest
workflow:
rules:
- if: $CI_COMMIT_BRANCH == "main"
variables:
ENV: "production"
- if: $CI_COMMIT_BRANCH == "development"
variables:
ENV: "development"
- if: $CI_COMMIT_BRANCH == "staging"
variables:
ENV: "staging"
variables:
TF_ROOT: ${CI_PROJECT_DIR}
TF_ADDRESS: ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/terraform/state/${ENV}_tf_state
cache:
key: ${ENV}_tf_state
paths:
- ${TF_ROOT}/.terraform
before_script:
- cd ${TF_ROOT}
stages:
- init
- validate
- build
- deploy
- cleanup
init_dev:
stage: init
script:
- gitlab-terraform init
environment:
name: development
only:
- development
validate_dev:
stage: validate
script:
- gitlab-terraform validate
environment:
name: development
only:
- development
plan_dev:
stage: build
script:
- gitlab-terraform plan -var-file=${ENV}.tfvars
- gitlab-terraform plan-json -var-file=${ENV}.tfvars
artifacts:
name: plan
paths:
- ${TF_ROOT}/plan.cache
reports:
terraform: ${TF_ROOT}/plan.json
environment:
name: development
only:
- development
apply_dev:
stage: deploy
script:
- gitlab-terraform apply
dependencies:
- plan_dev
environment:
name: development
only:
- development
destroy_dev:
stage: cleanup
script:
- gitlab-terraform destroy -var-file=${ENV}.tfvars
dependencies:
- plan_dev
- apply_dev
when: manual
environment:
name: development
only:
- development
init_qas:
stage: init
script:
- gitlab-terraform init
environment:
name: staging
only:
- staging
validate_qas:
stage: validate
script:
- gitlab-terraform validate
environment:
name: staging
only:
- staging
plan_qas:
stage: build
script:
- gitlab-terraform plan -var-file=${ENV}.tfvars
- gitlab-terraform plan-json -var-file=${ENV}.tfvars
artifacts:
name: plan
paths:
- ${TF_ROOT}/plan.cache
reports:
terraform: ${TF_ROOT}/plan.json
environment:
name: staging
only:
- staging
apply_qas:
stage: deploy
script:
- gitlab-terraform apply
dependencies:
- plan_qas
environment:
name: staging
only:
- staging
destroy_qas:
stage: cleanup
script:
- gitlab-terraform destroy -var-file=${ENV}.tfvars
dependencies:
- plan_qas
- apply_qas
when: manual
environment:
name: staging
only:
- staging
init_prd:
stage: init
script:
- gitlab-terraform init
environment:
name: default
only:
- main
validate_prd:
stage: validate
script:
- gitlab-terraform validate
environment:
name: default
only:
- main
plan_prd:
stage: build
script:
- gitlab-terraform plan -var-file=${ENV}.tfvars
- gitlab-terraform plan-json -var-file=${ENV}.tfvars
artifacts:
name: plan
paths:
- ${TF_ROOT}/plan.cache
reports:
terraform: ${TF_ROOT}/plan.json
environment:
name: default
only:
- main
apply_prd:
stage: deploy
script:
- gitlab-terraform apply
dependencies:
- plan_prd
environment:
name: default
only:
- main
destroy_prd:
stage: cleanup
script:
- gitlab-terraform destroy -var-file=${ENV}.tfvars
dependencies:
- plan_prd
- apply_prd
when: manual
environment:
name: default
only:
- main
Este bloco definido como workflow, é responsável por identificar os ambientes com base na branch onde foi realizado o commit, inserindo essa informação na variável ENV:
workflow:
rules:
- if: $CI_COMMIT_BRANCH == "main"
variables:
ENV: "production"
- if: $CI_COMMIT_BRANCH == "development"
variables:
ENV: "development"
- if: $CI_COMMIT_BRANCH == "staging"
variables:
ENV: "staging"
Nos scripts de cada stage, utilizamos a variável ENV para determinar qual arquivo tfvars será utilizado, de acordo com cada environment (development.tfvars, staging.tfvars, production.tfvars):
script:
- gitlab-terraform plan -var-file=${ENV}.tfvars
- gitlab-terraform plan-json -var-file=${ENV}.tfvars
Happy building!
Top comments (0)