Files
turnk8s/.github/workflows/pr_cluster_workflow.yml
2024-10-04 13:18:23 +04:00

159 lines
6.8 KiB
YAML

# This workflow is designed for creating clusters using "config.yaml" and "test_config.yaml" files based on purpose of implementing GitOps solution with the help of "turnk8s".
#
# It is possible to create or delete clusters based on the creating PRs, by updating the configuration files.
# The "config.yaml" file can be updated modifications(creating, updating, or deleting clusters) of cluster(s) described within the "config.yaml" file. In simple words, it describes the existing clusters on the server.
# **Note: The clusters must not start with the "turnk8s-" prefix.
# Modifications take effect upon merging a PRs into the main branch.
# All clusters are destroyed if the "config.yaml" file is empty.
#
# For testing new features, the "test_config.yaml" file should only contain one cluster description(referred to as "test-cluster"), which must be in the "turnk8s-<PR_NUMBER>" format.
# Only one cluster can be described in test_config.yaml file.
# **Note: For merging a PR, test_config.yaml file must be empty.
# Test cluster is destroyed if "test_config.yaml" file is empty.
#
# **Attention: The workflow contains a job called "enable_merge_pr", which enable ability of merging PRs.
# As a result of the workflow, the cluster's kube-config file will be found attached in the "Artifacts" section.
name: 'Automated Cluster Deployment for Pull Requests'
on:
pull_request:
branches:
- '*'
paths:
- 'test_config.yaml'
- 'config.yaml'
env:
TF_CLOUD_ORGANIZATION: "infraheads"
TF_API_TOKEN: "${{ secrets.TF_API_TOKEN }}"
TF_VAR_proxmox_token_id: "${{ secrets.PROXMOX_TOKEN_ID }}"
TF_VAR_proxmox_token_secret: "${{ secrets.PROXMOX_TOKEN_SECRET }}"
TF_VAR_github_token: "${{ secrets.TOKEN_GITHUB }}"
TF_VAR_netris_controller_host: "${{ vars.NETRIS_CONTROLLER_HOST }}"
TF_VAR_netris_controller_login: "${{ secrets.NETRIS_CONTROLLER_LOGIN }}"
TF_VAR_netris_controller_password: "${{ secrets.NETRIS_CONTROLLER_PASSWORD }}"
TF_VAR_argocd_admin_password: "${{ secrets.ARGOCD_ADMIN_PASSWORD }}"
TF_VAR_config_file_path: "../../test_config.yaml"
TF_VAR_cluster_name: "turnk8s-${{ github.event.number }}"
jobs:
pr_workflow:
runs-on: self-hosted
permissions:
contents: read
pull-requests: write
container:
image: ${{ vars.RUNNER_IMAGE }}
defaults:
run:
working-directory: "terraform/infrastructure"
outputs:
config_is_empty: ${{ steps.check_config.outputs.config_is_empty }}
steps:
- uses: actions/checkout@v4
- name: Checks if test config is empty
id: check_config
shell: bash
run: |
set -e
if [ -z "$(grep -v '^\s*$' ${GITHUB_WORKSPACE}/test_config.yaml)" ];
then
echo "config_is_empty=true" >> $GITHUB_OUTPUT
# check how many clusters should be updated: only one cluster must be updated through each PR
echo "The test_config.yaml file is empty and the PR is ready to merge."
else
echo "config_is_empty=false" >> $GITHUB_OUTPUT
echo "The test_config.yaml file is not empty. For merging PRs it must be empty."
fi
# Validates YAML configuration files: structure, empty lines, keys, etc.
- name: Ensure validity of the configuration files
run: |
# in case of empty test_confi file, it must validate config.yaml file
if ${{ steps.check_config.outputs.config_is_empty == 'true' }}; then
python3 ${GITHUB_WORKSPACE}/scripts/python/validate_yaml.py --yaml-path=${GITHUB_WORKSPACE}/config.yaml
else
python3 ${GITHUB_WORKSPACE}/scripts/python/validate_yaml.py --yaml-path=${GITHUB_WORKSPACE}/test_config.yaml --cluster-name=${{ env.TF_VAR_cluster_name }}
fi
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
cli_config_credentials_token: ${{ secrets.TF_API_TOKEN }}
terraform_version: 1.7.5
- name: Configure Terraform Cache
run: echo "TF_PLUGIN_CACHE_DIR=$HOME/.terraform.d/plugin-cache" >> "$GITHUB_ENV"
- name: Initializing Terraform
run: |
terraform init -upgrade
env:
TF_WORKSPACE: "default-ws"
# Test PR cluster is removed in case of empty test_config.yaml file
- name: Destroying test cluster
if: ${{ steps.check_config.outputs.config_is_empty == 'true' }}
run: |
if terraform workspace list | grep -w "${{ github.event.number }}-infrastructure"; then
bash ${GITHUB_WORKSPACE}/scripts/terraform/destroy.sh ${{ env.TF_VAR_cluster_name }}
fi
# Apply cluster's infrastructure changes
- name: Infrastructure updates
if: ${{ steps.check_config.outputs.config_is_empty == 'false' }}
run: |
bash ${GITHUB_WORKSPACE}/scripts/terraform/apply.sh infrastructure ${{ env.TF_VAR_cluster_name }}
- name: Initializing Terraform
if: ${{ steps.check_config.outputs.config_is_empty == 'false' }}
run: |
cd ${GITHUB_WORKSPACE}/terraform/cluster
terraform init -upgrade
env:
TF_WORKSPACE: "default-ws"
# Apply cluster's applications and tools changes
- name: Cluster updates
if: ${{ steps.check_config.outputs.config_is_empty == 'false' }}
run: |
cd ${GITHUB_WORKSPACE}/terraform/cluster
bash ${GITHUB_WORKSPACE}/scripts/terraform/apply.sh cluster ${{ env.TF_VAR_cluster_name }}
- name: Generating kube-config as Artifact
if: ${{ steps.check_config.outputs.config_is_empty == 'false' }}
uses: actions/upload-artifact@v4
with:
name: kube-config-${{ env.TF_VAR_cluster_name }}
path: /opt/kubeconfig/${{ env.TF_VAR_cluster_name }}
compression-level: 0
- name: Generating Markdown
if: ${{ steps.check_config.outputs.config_is_empty == 'false' }}
run: |
echo "### turnk8s" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Push your Kubernetes service manifests to [GitHub URL](https://github.com/infraheads/${{ env.TF_VAR_cluster_name }}) to get them deployed on the cluster. :star_struck:" >> $GITHUB_STEP_SUMMARY
echo "Use the 'kubeconfig' file to connect to the cluster, which is attached in 'Artifacts' section." >> $GITHUB_STEP_SUMMARY
enable_merge_pr:
needs: pr_workflow
runs-on: self-hosted
permissions:
contents: read
pull-requests: write
container:
image: ${{ vars.RUNNER_IMAGE }}
steps:
# PR can be merged in case of empty test_config.yaml
- name: Enable merge PR
run: |
set -e
if ${{ needs.pr_workflow.outputs.config_is_empty == 'false' }}; then
echo "The test_config.yaml file is not empty. For merging PRs the file must be empty."
exit 1
fi