orange-openSource--aws-terr.../automation/jinja2/templates/.gitlab-ci.yml.j2
Fabien Gaubert 5cf2ac0217 Init
2023-06-21 14:41:43 +02:00

468 lines
13 KiB
Django/Jinja

---
variables:
PHASE: BUILD
CICD_MODE: "true"
GIT_SUBMODULE_STRATEGY: "recursive"
PRINT_DEBUG: "false"
{% if TF_TOKEN_MODULE_ACCESS %}
{{ TF_TOKEN_MODULE_ACCESS_KEY }}: {{ TF_TOKEN_MODULE_ACCESS_VALUE }}
{% endif %}
# Docker Image Tag
TFLINT_IMAGE_TAG: {{ environ('TFLINT_IMAGE_TAG') }}
PRECOMMIT_IMAGE_TAG: {{ environ('PRECOMMIT_IMAGE_TAG') }}
TFENV_IMAGE_TAG: {{ environ('TFENV_IMAGE_TAG') }}
DRIFTCTL_IMAGE_TAG: {{ environ('DRIFTCTL_IMAGE_TAG') }}
# NEED TO BE CHANGED FOR EACH PROJECT
PROJECT_NAME: {{ environ('PROJECT_NAME') }}
REGION: {{ environ('REGION') }}
TF_VAR_assume_role: {{ environ('CICD_ROLE_NAME') }}
TF_VAR_backend_bucket_name: {{ environ('TF_VAR_backend_bucket_name') }}
TF_VAR_backend_bucket_region: {{ environ('REGION') }}
TF_VAR_backend_dynamodb_table: {{ environ('TF_VAR_backend_dynamodb_table')}}
TF_VAR_backend_bucket_access_role: "arn:aws:iam::{{ environ('ACCOUNT_ID') }}:role/{{ environ('CICD_ROLE_NAME') }}"
PLAN_BINARY_FILE: {{ environ('PLAN_BINARY_FILE') }}
PLAN_JSON_FILE: {{ environ('PLAN_JSON_FILE') }}
ACCOUNT_ID: {{ environ('ACCOUNT_ID') }}
CICD_ROLE_NAME: {{ environ('CICD_ROLE_NAME') }}
{%- set plans_install = environ('PLAN_INSTALL_LIST').split(',') -%}
{%- set plans_delete = environ('PLAN_DELETE_LIST').split(',') %}
{%- set runners = environ('CICD_RUNNER_TAGS').split(',') %}
cache:
key: $CI_COMMIT_REF_SLUG
paths:
- creds.env
stages:
- aws-creds
- quality-checks
- drift
- plan
- tests
- apply
- delete
- clean-cache
########################################################################################################################
# FUNCTIONS
########################################################################################################################
.aws-cli:
before_script:
- yum install -y jq
image:
name: amazon/aws-cli:latest
entrypoint:
- '/usr/bin/env'
- 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
tags:
{% for runner in runners %}
- {{ runner }}
{% endfor %}
.aws_get_creds: &aws_get_creds
script: |
#!/usr/bin/env bash
echo "Getting temporary credentials associated to assume role"
STS_CREDS=$(aws sts assume-role --role-arn arn:aws:iam::903534291474:role/Vocalcom-CiCd-CrossAccountRole --role-session-name ${CI_COMMIT_SHA})
AWS_ACCESS_KEY_ID=$(echo $STS_CREDS | jq -r '.Credentials.AccessKeyId')
AWS_SECRET_ACCESS_KEY=$(echo $STS_CREDS | jq -r '.Credentials.SecretAccessKey')
AWS_SESSION_TOKEN=$(echo $STS_CREDS | jq -r '.Credentials.SessionToken')
echo "export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID" > creds.env
echo "export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY" >> creds.env
echo "export AWS_SESSION_TOKEN=$AWS_SESSION_TOKEN" >> creds.env
.terraform-base:
before_script:
- rm -rf .terraform
image:
name: marmarama/tfenv:$TFENV_IMAGE_TAG
entrypoint:
- '/usr/bin/env'
- 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/tfenv/bin/'
tags:
{% for runner in runners %}
- {{ runner }}
{% endfor %}
{% if GITLAB_JOBS["terraform-trivy"] %}
.terraform-trivy:
before_script:
- rm -rf .terraform
- . ./creds.env
- apk --no-cache --update add make
image:
name: aquasec/trivy:latest
entrypoint:
- '/usr/bin/env'
- 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/tfenv/bin/'
tags:
{% for runner in runners %}
- {{ runner }}
{% endfor %}
{% endif %}
{% if GITLAB_JOBS["terraform-lint"] %}
.terraform-lint:
image:
name: ghcr.io/terraform-linters/tflint:${TFLINT_IMAGE_TAG}
entrypoint:
- '/usr/bin/env'
- 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
before_script:
- apk --no-cache --update add make
tags:
{% for runner in runners %}
- {{ runner }}
{% endfor %}
{% endif %}
{% if GITLAB_JOBS["shell-lint"] %}
.shelllint:
image:
name: pipelinecomponents/shellcheck:latest
entrypoint:
- '/usr/bin/env'
- 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
tags:
{% for runner in runners %}
- {{ runner }}
{% endfor %}
{% endif %}
{% if GITLAB_JOBS["precommit"] %}
.precommit:
image:
name: ghcr.io/antonbabenko/pre-commit-terraform:${PRECOMMIT_IMAGE_TAG}
entrypoint:
- '/usr/bin/env'
- 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
tags:
{% for runner in runners %}
- {{ runner }}
{% endfor %}
{% endif %}
{% if GITLAB_JOBS["yaml-lint"] %}
.yamllint:
image:
name: pipelinecomponents/yamllint:latest
entrypoint:
- '/usr/bin/env'
- 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
before_script:
- apk --no-cache --update add make
tags:
{% for runner in runners %}
- {{ runner }}
{% endfor %}
{% endif %}
{% if GITLAB_JOBS["terraform-compliance"] %}
.terraform-compliance:
image:
name: eerkunt/terraform-compliance:latest
entrypoint:
- '/usr/bin/env'
- 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
before_script:
- apt-get update && apt-get install -y make
- . ./creds.env
tags:
{% for runner in runners %}
- {{ runner }}
{% endfor %}
{% endif %}
{% if GITLAB_JOBS["terraform-terrascan"] %}
.terraform-terrascan:
image:
name: tenable/terrascan:latest
entrypoint:
- '/usr/bin/env'
- 'PATH=/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
before_script:
- . ./creds.env
tags:
{% for runner in runners %}
- {{ runner }}
{% endfor %}
{% endif %}
{% if GITLAB_JOBS["md-lint"] %}
.md_lint:
image:
name: pipelinecomponents/markdownlint:latest
entrypoint:
- '/usr/bin/env'
- 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/app/bin'
before_script:
- apk --no-cache --update add make
- . ./creds.env
tags:
{% for runner in runners %}
- {{ runner }}
{% endfor %}
{% endif %}
########################################################################################################################
# COMMONS
########################################################################################################################
{% if GITLAB_JOBS["aws-creds"] %}
aws-creds:
extends: .aws-cli
stage: aws-creds
<<: *aws_get_creds
{% endif %}
{% if GITLAB_JOBS["terraform-compliance"] %}
########################################################################################################################
# TESTS
########################################################################################################################
terraform-compliance:
needs: [plan_all]
extends: .terraform-compliance
allow_failure: true
stage: tests
script:
- make terraform_compliance
{% endif %}
########################################################################################################################
# QUALITY CHECKS
########################################################################################################################
{% if GITLAB_JOBS["terraform-lint"] %}
terraform-lint:
needs: []
extends: .terraform-lint
allow_failure: true
stage: quality-checks
script:
- make lint
{% endif %}
{% if GITLAB_JOBS["precommit"] %}
precommit:
needs: []
extends: .precommit
allow_failure: true
stage: quality-checks
before_script:
- apk --no-cache --update add make
script:
- make precommit
{% endif %}
{% if GITLAB_JOBS["terraform-format"] %}
terraform-format:
needs: []
extends: .terraform-base
allow_failure: true
stage: quality-checks
script:
- make format
{% endif %}
{% if GITLAB_JOBS["terraform-validate"] %}
terraform-validate:
needs: []
extends: .terraform-base
allow_failure: true
before_script:
- . ./creds.env
stage: quality-checks
script:
- make validate
{% endif %}
{% if GITLAB_JOBS["terraform-terrascan"] %}
terraform-terrascan:
needs: []
extends: .terraform-terrascan
allow_failure: true
stage: quality-checks
script:
- terrascan scan -i terraform --verbose --config-path=./.terrascan_config.toml {% for plan_name in plans_install %} --iac-dir={{ plan_name }}{% endfor %}
{% endif %}
{% if GITLAB_JOBS["md-lint"] %}
md-lint:
needs: []
extends: .md_lint
allow_failure: true
stage: quality-checks
script:
- make markdown_lint
{% endif %}
{% if GITLAB_JOBS["shell-lint"] %}
shell-lint:
needs: []
extends: .shelllint
allow_failure: true
before_script:
- . ./creds.env
- apk --no-cache --update add make
stage: quality-checks
script:
- make shell_lint
{% endif %}
{% if GITLAB_JOBS["yaml-lint"] %}
yaml-lint:
needs: []
extends: .yamllint
allow_failure: true
stage: quality-checks
script:
- make yaml_lint
{% endif %}
{% if GITLAB_JOBS["terraform-trivy"] %}
terraform-trivy:
needs: []
extends: .terraform-trivy
allow_failure: true
stage: quality-checks
script:
- make trivy
{% endif %}
{% if GITLAB_JOBS["driftctl"] %}
########################################################################################################################
# DRIFT Detection
########################################################################################################################
driftctl:
stage: drift
needs: [aws-creds]
allow_failure: true
image:
name: snyk/driftctl:$DRIFTCTL_IMAGE_TAG
entrypoint: [""]
variables:
AWS_DEFAULT_REGION: $REGION
ROLE_TO_ASSUME: ${TF_VAR_backend_bucket_access_role}
AWS_ROLE_SESSION_NAME: "sessiondrifctl"
before_script:
- . ./creds.env
- apk add --no-cache aws-cli
- apk add --no-cache jq
script: |
#!/usr/bin/env bash
echo "Getting temporary credentials associated to assume role"
aws sts get-caller-identity
STS_CREDS=$(aws sts assume-role --role-arn ${ROLE_TO_ASSUME} --role-session-name ${AWS_ROLE_SESSION_NAME})
AWS_ACCESS_KEY_ID=$(echo $STS_CREDS | jq -r '.Credentials.AccessKeyId')
AWS_SECRET_ACCESS_KEY=$(echo $STS_CREDS | jq -r '.Credentials.SecretAccessKey')
AWS_SESSION_TOKEN=$(echo $STS_CREDS | jq -r '.Credentials.SessionToken')
aws sts get-caller-identity
driftctl scan --only-managed --from tfstate+s3://"${TF_VAR_backend_bucket_name}"/*.tfstate
{% endif %}
########################################################################################################################
# PLAN
########################################################################################################################
.plan_job: &plan_job
extends: .terraform-base
stage: plan
needs: [aws-creds]
allow_failure: false
before_script:
- . ./creds.env
{% for plan_name in plans_install +%}
{% set path = plan_name.split('/') %}
{% set slug = plan_name.replace('/',"_") %}
plan_{{ slug }}:
<<: *plan_job
script:
- make plan_{{ slug }}
artifacts:
paths:
- {{ plan_name }}/{{ environ('PLAN_BINARY_FILE') }}
- {{ plan_name }}/{{ environ('PLAN_JSON_FILE') }}
only:
changes:
- {{ plan_name }}/**/*
{% endfor %}
{% if GITLAB_JOBS["plan_all"] %}
plan_all:
<<: *plan_job
script:
- make plan_all
artifacts:
paths:
- ./**/{{ environ('PLAN_BINARY_FILE') }}
- ./**/{{ environ('PLAN_JSON_FILE') }}
{% endif %}
########################################################################################################################
# APPLY
########################################################################################################################
.apply_job: &apply_job
extends: .terraform-base
stage: apply
allow_failure: false
when: manual
before_script:
- . ./creds.env
{% for plan_name in plans_install +%}
{% set path = plan_name.split('/') %}
{% set slug = plan_name.replace('/',"_") %}
apply_{{ slug }}:
<<: *apply_job
needs: [plan_{{ slug }}]
script:
- make install_{{ slug }}
only:
{% if TF_APPLY_ONLY_MAIN %}
refs:
- main
{% endif %}
changes:
- {{ plan_name }}/**/*
{% endfor %}
{% if GITLAB_JOBS["apply_all"] %}
apply_all:
<<: *apply_job
needs: [plan_all]
script:
- make install_all
{% if TF_APPLY_ONLY_MAIN %}
only:
refs:
- main
{% endif %}
{% endif %}
########################################################################################################################
# DELETE
########################################################################################################################
.delete_job: &delete_job
extends: .terraform-base
allow_failure: false
stage: delete
when: manual
before_script:
- . ./creds.env
only:
variables:
- $PHASE == "DESTROY"
{% for plan_name in plans_delete +%}
{% set path = plan_name.split('/') %}
{% set slug = plan_name.replace('/',"_") %}
delete_{{ slug}}:
<<: *delete_job
script:
- make delete_{{ slug }}
{% endfor %}
{% if GITLAB_JOBS["delete_all"] %}
delete_all:
<<: *delete_job
script:
- make delete_all
{% endif %}