push terraform

This commit is contained in:
Grégory Lebreton 2023-04-12 14:54:46 +02:00
commit 0ac73c6cdb
10 changed files with 251 additions and 0 deletions

70
README.md Normal file
View File

@ -0,0 +1,70 @@
# TERRAFORM / GCP
Demo Terraform déployant une application Flask dans un conteneur Docker sur GCP
## PRE REQUIS
- [COMPTE GCP](https://cloud.google.com/?hl=fr)
- [TERRAFORM](https://www.terraform.io/)
## PREPARATION
### MACHINE LOCALE
- Installer Terraform:
```bash
# LINUX INSTALL
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
sudo apt-get update && sudo apt-get install terraform
```
- Créer une paire de clé ssh dédiée pour Terraform dans ~/.ssh
```bash
# NOMMER LE CLE TERRAFORM
ssh-keygen -t rsa -b 4096
```
### DASHBOARD GCP
- Créer un projet "terraform-demo"
- Séletionner le projet créé puis créer un compte de service dans l'onglet [IAM et administration](https://console.cloud.google.com/projectselector2/iam-admin/serviceaccounts?hl=fr) de la console GCP
- Ajouter les rôles suivant:
- Compute admin
- Compute network admin
- Service account admin
- Activer les APIs nécessaires (compute engine API, storage API, cloud billing API)
![SERVICES ACCOUNT](docs/service-account.png)
- Créer une clé au sein du compte de service avec les droits sur le compute engine (pour créer les VMs), et télécharger le fichier json contenant la clé pour le mettre dans le dossier auth/
### TERRAFORM.TFVARS
- Modifier le fichier terraform.tfvars en fonction de votre environnement (gcp_project_id et gcp_auth_file)
## UTILISATION
- Initialiser Terraform:
```bash
cd terraform-demo
terraform init
```
- Dry run:
```bash
terraform plan
```
- Lançer Terraform:
```bash
terraform apply
# Saisir yes quand demandé
```
> Visiter l'adresse fournie en output du terraform apply (Web-server-URL = "http://SERVER_IP:5000")
- Stopper Terraform:
```bash
terraform destroy
```

7
app/Dockerfile Normal file
View File

@ -0,0 +1,7 @@
FROM python:3.8-slim-bullseye
WORKDIR /python-docker
COPY ./requirements.txt requirements.txt
RUN python3 -m pip install -r requirements.txt
COPY ./ .
EXPOSE 5000
CMD [ "python3", "-m" , "flask", "run", "--host=0.0.0.0"]

8
app/app.py Normal file
View File

@ -0,0 +1,8 @@
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_cloud():
return 'Hello Cloud!'
app.run(host='0.0.0.0')

6
app/deploy.sh Normal file
View File

@ -0,0 +1,6 @@
#!/bin/bash
sudo apt-get update
sudo apt-get install -yq docker.io
sudo docker build --network=host -t flaskapp .
sudo docker run -d -p 5000:5000 flaskapp:latest

1
app/requirements.txt Normal file
View File

@ -0,0 +1 @@
flask

0
auth/cle.json Normal file
View File

BIN
docs/service-account.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

113
main.tf Normal file
View File

@ -0,0 +1,113 @@
## TERRAFORM
terraform {
required_version = ">= 0.12"
}
## PROVIDER
provider "google" {
project = var.gcp_project_id
credentials = file(var.gcp_auth_file)
region = var.gcp_region
}
## NETWORK
resource "google_compute_network" "vpc_network" {
name = "my-custom-network"
auto_create_subnetworks = false
mtu = 1460
}
resource "google_compute_subnetwork" "default" {
name = "my-custom-subnet"
ip_cidr_range = "10.0.1.0/24"
region = var.gcp_region
network = google_compute_network.vpc_network.id
}
## FIREWALL
### SSH
resource "google_compute_firewall" "ssh" {
name = "allow-ssh"
allow {
ports = ["22"]
protocol = "tcp"
}
direction = "INGRESS"
network = google_compute_network.vpc_network.id
priority = 1000
source_ranges = ["0.0.0.0/0"]
target_tags = ["ssh"]
}
### APP
resource "google_compute_firewall" "flask" {
name = "flask-app-firewall"
network = google_compute_network.vpc_network.id
allow {
protocol = "tcp"
ports = ["5000"]
}
source_ranges = ["0.0.0.0/0"]
}
## VM
resource "google_compute_instance" "default" {
name = "flask-vm"
machine_type = "e2-micro"
zone = var.gcp_zone
tags = ["ssh"]
boot_disk {
initialize_params {
image = "debian-cloud/debian-11"
}
}
metadata = {
ssh-keys = "${var.gcp_ssh_user}:${file(var.gcp_ssh_pub_key_file)}"
}
network_interface {
subnetwork = google_compute_subnetwork.default.id
access_config {
#### TO HAVE A PUBLIC IP ADRESS
}
}
### COPY DES FICHIERS
provisioner "file" {
source = "app/"
destination = "./"
connection {
host = google_compute_instance.default.network_interface.0.access_config.0.nat_ip
type = "ssh"
user = var.gcp_ssh_user
timeout = "500s"
private_key = file(var.gcp_ssh_priv_key_file)
}
}
### START DEPLOY.SH
provisioner "remote-exec" {
inline = [
"chmod +x ~/deploy.sh",
"cd ~",
"./deploy.sh"
]
connection {
host = google_compute_instance.default.network_interface.0.access_config.0.nat_ip
type = "ssh"
user = var.gcp_ssh_user
timeout = "500s"
private_key = file(var.gcp_ssh_priv_key_file)
}
}
}
## GET VM PUBLIC IP
output "Web-server-URL" {
value = join("", ["http://", google_compute_instance.default.network_interface.0.access_config.0.nat_ip, ":5000"])
}

8
terraform.tfvars Normal file
View File

@ -0,0 +1,8 @@
# GCP Settings
gcp_project_id = "terraform-demo-381114" # A MODIFIER
gcp_region = "europe-west9"
gcp_zone = "europe-west9-a"
gcp_auth_file = "./auth/terraform-demo-381114-158cfce10778.json" # A MODIFIER
gcp_ssh_user = "devops" # A MODIFIER OU PAS
gcp_ssh_pub_key_file = "~/.ssh/terraform.pub"
gcp_ssh_priv_key_file = "~/.ssh/terraform"

38
variables.tf Normal file
View File

@ -0,0 +1,38 @@
# GCP authentication file
variable "gcp_auth_file" {
type = string
description = "GCP authentication file"
}
# define GCP region
variable "gcp_region" {
type = string
description = "GCP region"
}
# define GCP project name
variable "gcp_project_id" {
type = string
description = "GCP project id"
}
# define GCP zone
variable "gcp_zone" {
type = string
description = "GCP zone"
}
variable "gcp_ssh_user" {
type = string
description = "SSH user"
}
variable "gcp_ssh_pub_key_file" {
type = string
description = "SSH public key file path"
}
variable "gcp_ssh_priv_key_file" {
type = string
description = "SSH private key file path"
}