Problem to solve
I am trying to setup simple CICD pipeline in Gitlab to deploy resources in AWS using Terraform IAC. All Terraform commands are working fine if running locally on laptop and able to deploy all resources to AWS as expected. However, same setup if I try to run it through GitLab is not working.
Our requirement: We have separate GitLab instances for Dev and Prod. I have separate folder under env directory for prod and dev respectively where I am running terraform commands. So we want to configure pipeline to deploy terraform IAC with condition if $CI_SERVER_URL is prod URL then run got to env/prod directory and run terraform command else go to env/dev directory and run terraform command.
Gitlab directory is stored in root directory of the project i.e. .project
Steps to reproduce
I am sharing my .gitlab-ci.yml
file and output I am getting in Gitlab logs through DBUG_MODE.
Configuration
Folder Structure
Project
├── README.md
├── .gitlab-ci.yml.md
├── .gitignore
├── __init__.py
├── env
│ ├── dev
│ │ ├── main.tf
│ │ ├── outputs.tf
│ │ ├── terraform.tfvars
│ │ ├── tfplan.json
│ │ └── variables.tf
│ ├── prod
│ │ ├── main.tf
│ │ ├── outputs.tf
│ │ ├── terraform.tfvars
│ │ ├── tfplan.json
│ │ └── variables.tf
│ └── stage
│ ├── main.tf
│ ├── outputs.tf
│ ├── terraform.tfvars
│ ├── tfplan.json
│ └── variables.tf
└── modules
├── __init__.py
├── api_gateway
│ ├── main.tf
│ ├── outputs.tf
│ └── variables.tf
├── dynamodb
│ ├── main.tf
│ ├── outputs.tf
│ └── variables.tf
GitLab Configuration File
variables:
AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID}
AWS_SECRET_ACCESS_KEY : ${AWS_SECRET_ACCESS_KEY}
AWS_DEFAULT_REGION: ${AWS_DEFAULT_REGION}
# CI_DEBUG_TRACE: "true"
image:
name: registry.gitlab.com/gitlab-org/gitlab-build-images:terraform
entrypoint:
- '/usr/bin/env'
- 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} AWS_DEFAULT_REGION=${AWS_DEFAULT_REGION}’'
stages:
- .pre
- validate
- plan
- apply
# Define the job to set the environment folder in the init stage
set_env_folder:
stage: .pre
script:
- echo "starting setting CI_ENV_FOLDER"
- pwd
- |
if [ "$CI_SERVER_URL" == "https://gitlab.prod.com" ]; then
echo "Running on production GitLab"
export CI_ENV_FOLDER="env/prod"
else
echo "Running on development GitLab"
export CI_ENV_FOLDER="env/dev"
fi
echo "Using CI_ENV_FOLDER=$CI_ENV_FOLDER" > .env
artifacts:
reports:
dotenv: .env
cache:
paths:
- $CI_ENV_FOLDER/.terraform
before_script:
- echo "Sourcing .env file:"
- cat .env
- source .env
- echo "The secret API key is $CI_ENV_FOLDER"
- pwd
- cd $CI_ENV_FOLDER
- pwd
- terraform --version
- terraform init
validate:
stage: validate
script:
- echo "Inside plan"
- pwd
- terraform validate
plan:
stage: plan
script:
- echo "Inside plan"
- pwd
- terraform plan -out="plan.tfplan"
dependencies:
- validate
artifacts:
paths:
- $CI_ENV_FOLDER/plan.tfplan
apply:
stage: apply
script:
- terraform apply "$CI_ENV_FOLDER/plan.tfplan"
dependencies:
- plan
when: manual
GitLab Output:
+ export 'RUNNER_TEMP_PROJECT_DIR=/builds/service.tmp'
+ cd /builds/service
+ echo '$ echo "Sourcing .env file:"'
$ echo "Sourcing .env file:"
+ echo 'Sourcing .env file:'
Sourcing .env file:
+ echo '$ cat .env'
$ cat .env
+ cat .env
cat: can't open '.env': No such file or directory
+ runner_script_trap
+ exit_code=1
+ out_json='{"command_exit_code": 1, "script": "/scripts-1234-1234/step_script"}'
+ echo
+ echo '{"command_exit_code": 1, "script": "/scripts-1234-1234/step_script"}'
+ exit 0
Uploading artifacts for failed job
.
.
.
.
++ /usr/bin/gitlab-runner-helper --version
++ echo 'Uploading artifacts...'
Uploading artifacts...
++ /usr/bin/gitlab-runner-helper artifacts-uploader --url https://gitlab.com/ --token [MASKED] --id 1234 --path .env --name .env --artifact-format gzip --artifact-type dotenv
WARNING: .env: no matching files. Ensure that the artifact path is relative to the working directory (/builds/service)
ERROR: No files to upload
+ exit 0
+ runner_script_trap
+ exit_code=0
+ out_json='{"command_exit_code": 0, "script": "/scripts-1234-1234/upload_artifacts_on_failure"}'
+ echo ''
+ echo '{"command_exit_code": 0, "script": "/scripts-1234-1234/upload_artifacts_on_failure"}'
+ exit 0
Cleaning up project directory and file based variables
Versions
Please select whether options apply, and add the version information.
- Self-managed