This repository demonstrates a complete, automated lifecycle of a web application deployment. It covers infrastructure provisioning, configuration management, containerization, and a fully automated CI/CD pipeline delivering the workload to a Kubernetes cluster.
- Cloud Provider: Yandex Cloud (Compute Cloud, VPC)
- Infrastructure as Code (IaC): Terraform (Provisioning 2 VMs: GitLab Runner & k3s Master Node)
- Configuration Management: Ansible (Environment bootstrapping, Docker & k3s installation)
- Container Registry: GitLab Container Registry
- Orchestration: Kubernetes (k3s lightweight distribution)
- CI/CD: GitLab CI/CD
The .gitlab-ci.yml pipeline consists of two primary stages:
- Build (
build_image): Uses Docker-in-Docker (DinD) to build the application image and pushes it to the GitLab Container Registry. - Deploy (
deploy_to_k8s): Uses a lightweight Alpine container equipped with an SSH client. It authenticates to the target K8s node via a passwordless Deploy Key, applies the latest manifests (deployment.yaml,service.yaml), and triggers a rolling restart to pull thelatestimage tag.
During the implementation of this pipeline, several real-world engineering challenges were resolved:
- Securing Terraform State: Configured a strict
.gitignoreto prevent the leakage ofterraform.tfstatefiles containing sensitive cloud credentials and IP addresses. - DinD TLS Verification Failure: Encountered
Cannot connect to the Docker daemon at tcp://docker:2375during the CI build stage. Resolved by explicitly disabling TLS verification (DOCKER_TLS_CERTDIR: "") and running the GitLab Runner inprivileged = truemode. - Automated K8s Authentication: Standard SSH keys with passphrases blocked automated deployment jobs. Solved by generating a dedicated, passwordless
ed25519Deploy Key and securely injecting its private counterpart into the pipeline via GitLab CI/CD Masked Variables.
To deploy this infrastructure in your own Yandex Cloud environment:
- Provision Infrastructure:
cd terraform
terraform init && terraform apply- Configure Servers:
Update
ansible/inventory.iniwith the new external IP addresses and run:
ansible-playbook -i ansible/inventory.ini ansible/playbook.yml- Trigger Pipeline:
Push the code to GitLab. Ensure CI/CD variables (
SSH_PRIVATE_KEY) are properly configured in the repository settings.