There is a one missing step - terraform keeps the state (like uuid after creation) in terraform.tfstate file. It's quite important because running the pipeline second time may fail due to name conflicts.
So, after running the CI Pipeline we should commit this file to the repository.
Example solution:
# add artifact in the previous stage:
terraform-apply:
...
artifacts:
when: always # in case of faile add the artifcat too - this could be a partial fail
paths:
- ./*.{tfstate}
# requirements to use this stage:
# TERRAFORM_WRITE_KEY - project access token with RW scope
# GITLAB_PATH - speaks for itself
# REPO_PATH - speaks for itself
# A writing directly to master should be allowed for the service account.
terraform-commit:
stage: terraform
image:
name: alpine/git:latest
entrypoint:
- /usr/bin/env # let's change the entrypoint, using commands with git is more readable
before_script:
- git config --global user.name "${GITLAB_USER_NAME}"
- git config --global user.email "${GITLAB_USER_EMAIL}"
script:
- git remote set-url origin https://git:$TERRAFORM_WRITE_KEY@$GITLAB_PATH/$REPO_PATH
- echo "commiting terraform changes; commit-id `(git rev-parse HEAD)`"
- git add *.tfstate
- git commit --allow-empty -m "[terraform] commiting changes from $CI_PIPELINE_ID"
- git push origin HEAD:master
needs:
- terraform-apply
There is another problem too, but it's not so trivial - concurrent pipelines. Solving that is much more complicated - but the easiest way is to limit the number of concurrent pipelines to 1. The "good" way would be sharing the lock file between runners.
There is a one missing step - terraform keeps the state (like uuid after creation) in
terraform.tfstate
file. It's quite important because running the pipeline second time may fail due to name conflicts.So, after running the CI Pipeline we should commit this file to the repository.
Example solution:
There is another problem too, but it's not so trivial - concurrent pipelines. Solving that is much more complicated - but the easiest way is to limit the number of concurrent pipelines to 1. The "good" way would be sharing the lock file between runners.
It is not a good practice to commit the state to the repository, instead keep the state on AWS or in gitlab