This project is part of the "End of Module Project" for KapsuleKorp. Its goal is to fully automate the lifecycle of the company's infrastructure using an Infrastructure as Code (IaC) approach.
It provisions a scalable architecture on Google Cloud Platform (GCP) using Terraform and configures the software stack (LEMP) using Ansible.
- Architecture
- Prerequisites
- Configuration & setup
- Usage & deployment
- Project structure
- Security notes
- Authors
The infrastructure simulates a professional development lifecycle with two distinct environments:
- Staging: 2 Web Servers + 1 Database Server.
- Production: 3 Web Servers + 1 Database Server.
Technological Stack:
- Cloud Provider: Google Cloud Platform (GCP)
- OS: Ubuntu 22.04 LTS
- Web Server: Nginx
- Database: MySQL 8.0
- Language: PHP 8.1 (FPM)
- IaC: Terraform (Infrastructure) & Ansible (Configuration)
Ensure you have the following installed on your control machine:
- Terraform (v1.0+)
- Ansible (v2.9+)
- Google Cloud SDK (gcloud)
- SSH Key Pair: Generate one if needed (
ssh-keygen -t ed25519 -f ~/.ssh/iac_esgi)
-
Create a Service Account on GCP with
Compute AdminandStorage Object Adminpermissions. -
Download the JSON key file.
-
Rename it to
gcp_service_account_key.json. -
Place it in the root of the
terraform/directory. -
Set the
GOOGLE_APPLICATION_CREDENTIALSenvironment variable to point to this file:export GOOGLE_APPLICATION_CREDENTIALS="./terraform/gcp_service_account_key.json"
IMPORTANT: Ensure this file is listed in
.gitignore.
To store the state securely, you must create a GCS bucket manually before running Terraform:
# Replace with a unique name
gsutil mb -l europe-west9 gs://iac-esgi-tfstate-UNIQUE_NAME
gsutil versioning set on gs://iac-esgi-tfstate-UNIQUE_NAMEThen, update the
bucketname interraform/provider.tf.
Create a terraform.tfvars file in the terraform/ directory to define your project ID:
project_id = "your-gcp-project-id"Update the database secrets in ansible/group_vars/all/vault.yml and encrypt the file:
ansible-vault encrypt ansible/group_vars/all/vault.yml
# Define a vault password when promptedNavigate to the terraform directory to create the servers, network, and firewalls. This will automatically generate the inventory.ini file for Ansible.
cd terraform
# Initialize Terraform (and download providers)
terraform init
# Preview changes
terraform plan
# Apply changes (provision VMs)
terraform applyOnce infrastructure is ready, switch to the ansible directory to deploy the LEMP stack.
cd ../ansible
# Deploy using the generated inventory
ansible-playbook -i inventory.ini site.yml --ask-vault-pass.
├── ansible/
│ ├── group_vars/all/vault.yml # Encrypted secrets
│ ├── roles/ # Reusable roles (db, web)
│ ├── inventory.ini # Generated by Terraform
│ └── site.yml # Main Playbook
├── terraform/
│ ├── main.tf # VM definitions
│ ├── network.tf # VPC & Firewall rules
│ ├── provider.tf # GCP & Backend config
│ └── inventory.tf # Logic to generate inventory.ini
└── README.md
- Firewall:
- SSH (22) is open to all for management.
- HTTP (80) is open for web servers.
- MySQL (3306) is restricted to internal traffic from web servers only.
- State: Terraform state is stored remotely in a GCS Bucket.
- Secrets: Database passwords are encrypted using Ansible Vault.
| Nom | Prénom | |
|---|---|---|
| LANCELOT | Romain | rlancelot@myges.fr |
| DUFRESNE | Jordan | jdufresne3@myges.fr |
| FRANCOIS | Ethan | efrancois13@myges.fr |