Skip to content
Snippets Groups Projects
Unverified Commit de2d94fc authored by Timo Furrer's avatar Timo Furrer
Browse files

Add state cleaner scripts and pipeline job

parent 28f197f8
Branches
Tags
No related merge requests found
...@@ -8,6 +8,7 @@ stages: ...@@ -8,6 +8,7 @@ stages:
- test-integration - test-integration
- deploy - deploy
- release - release
- cleanup
.opentofu-versions: .opentofu-versions:
parallel: parallel:
...@@ -102,3 +103,18 @@ create-release: ...@@ -102,3 +103,18 @@ create-release:
release: release:
tag_name: $CI_COMMIT_TAG tag_name: $CI_COMMIT_TAG
description: "Release $CI_COMMIT_TAG of components repository $CI_PROJECT_PATH" description: "Release $CI_COMMIT_TAG of components repository $CI_PROJECT_PATH"
old-states:
image: alpine:latest
stage: cleanup
variables:
REMOVE_STATES_UNTIL: 1 week ago
GITLAB_TOKEN: $GITLAB_STATE_CLEANER_TOKEN
before_script:
- apk add --update coreutils curl jq
- export FETCH_OLDER_THAN=$(date '+%Y-%m-%dT%H:%M:%SZ' -d "${REMOVE_STATES_UNTIL}")
script:
- echo "Going to remove Terraform States older than '$FETCH_OLDER_THAN'"
- ./.gitlab/scripts/fetch-states.sh | sed -n '1d;p' | ./.gitlab/scripts/remove-states.sh
rules:
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE == "schedule" && STATE_CLEANER == "true"'
#!/usr/bin/env sh
#
# Script to fetch all Terraform States of a project,
# optionally filter states which are older than a given
# date time.
#
# The output is in CSV and contains a header line
# containing the names of the columns.
# You can easily store it as CSV using:
# `fetch-states.sh > states.csv`
# or stream it to another script, e.g. without the header line:
# `fetch-states.sh | sed -n '1d;p' | ...`
#
# The script is optimized to run in a GitLab pipeline
# and therefore uses environment variables which are
# defined there by default.
#
# It requires an additional `GITLAB_TOKEN` variable, which
# contains a valid GitLab token with permissions to read
# Terraform states.
#
if [ -z "$FETCH_OLDER_THAN" ]; then
FETCH_OLDER_THAN=$(date "+%Y-%m-%dT%H:%M:%SZ")
fi
after="null"
has_next_page=true
echo "state,updatedAt"
while $has_next_page; do
# shellcheck disable=SC2016
data=$(curl --silent --show-error --fail -H "Authorization: Bearer $GITLAB_TOKEN" -H "Content-Type: application/json" \
"$CI_API_GRAPHQL_URL" \
-X POST \
--data '[{ "operationName": "getStates", "variables": { "projectPath": "'$CI_PROJECT_PATH'", "first": 100, "after":'"$after"', "last": null, "before": null }, "query": "query getStates($projectPath: ID!, $first: Int, $last: Int, $before: String, $after: String) { project(fullPath: $projectPath) { id terraformStates(first: $first, last: $last, before: $before, after: $after) { count nodes { name updatedAt } pageInfo { hasNextPage endCursor } } } } " } ] '
)
echo "$data" | jq --arg date "$FETCH_OLDER_THAN" -r '.[0]["data"]["project"]["terraformStates"]["nodes"][] | select(.updatedAt < $date) | "\(.name),\(.updatedAt)"'
has_next_page=$(echo "$data" | jq -r '.[0]["data"]["project"]["terraformStates"]["pageInfo"]["hasNextPage"] == true')
after='"'$(echo "$data" | jq -r '.[0]["data"]["project"]["terraformStates"]["pageInfo"]["endCursor"]')'"'
done
#!/usr/bin/env sh
#
# Script to remove the given Terraform States.
# The states are read from stdin in the format:
# `<state-name>,<last-updated-at>`
#
# The script is optimized to run in a GitLab pipeline
# and therefore uses environment variables which are
# defined there by default.
#
# It requires an additional `GITLAB_TOKEN` variable, which
# contains a valid GitLab token with permissions to delete
# Terraform states.
#
GITLAB_BASE_TF_ADDRESS="${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/terraform/state"
cat - | while read -r line; do
echo "Processing $(echo "$line" | tr -d '\n')"
TF_ADDRESS="${GITLAB_BASE_TF_ADDRESS}/$(echo "$line" | cut -d, -f1)"
curl --header "Private-Token: $GITLAB_TOKEN" --request DELETE "$TF_ADDRESS"
done
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment