From bc26ed8889e8518a6b447b6f529369796fcde9c0 Mon Sep 17 00:00:00 2001 From: greglebreton Date: Sun, 19 Mar 2023 23:34:01 +0100 Subject: [PATCH] ajout Dockerfile pour automatisation --- README.md | 54 +++++++++--------------- app/Dockerfile | 13 ++++++ app/app.py | 8 ++++ app/deploy.sh | 9 ++++ app/requirements.txt | 1 + main.tf | 97 ++++++++++++++++++++++++++++++++------------ terraform.tfvars | 7 +++- variables.tf | 15 +++++++ 8 files changed, 143 insertions(+), 61 deletions(-) create mode 100644 app/Dockerfile create mode 100644 app/app.py create mode 100644 app/deploy.sh create mode 100644 app/requirements.txt diff --git a/README.md b/README.md index d2d38ee..d7f8c43 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,17 @@ # 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 - @@ -11,7 +19,13 @@ sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(l sudo apt-get update && sudo apt-get install terraform ``` -## PREPARATION +- Créer une paire de clé ssh dédiée pour Terraform +```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 @@ -23,56 +37,28 @@ sudo apt-get update && sudo apt-get install terraform ![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 -- Modifier l'id du projet ainsi que le chemin du fichier json contenant la clef dans le fichier variables.tf +- 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 ## UTILISATION - Lançer Terraform: - ```bash terraform init ``` - Lançer Terraform: - ```bash terraform plan ``` - Lançer Terraform: - ```bash terraform apply # Saisir yes quand demandé ``` -> L'adresse public de la VM est fournie en output du terraform apply http://public-ip:5000 - -- Se connecter en SSH à la VM pour créer l'application Flask: - -```bash -nano app.py -from flask import Flask -app = Flask(__name__) - -@app.route('/') -def hello_cloud(): - return 'Hello Cloud!' - -app.run(host='0.0.0.0') -``` - -- Installer Flask: - -```bash -python3 -m pip install flask -``` - -- Lançer l'application: - -```bash -python3 app.py -``` - > Visiter l'adresse fournie en output du terraform apply \ No newline at end of file diff --git a/app/Dockerfile b/app/Dockerfile new file mode 100644 index 0000000..a28ec5b --- /dev/null +++ b/app/Dockerfile @@ -0,0 +1,13 @@ +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"] \ No newline at end of file diff --git a/app/app.py b/app/app.py new file mode 100644 index 0000000..bb8243d --- /dev/null +++ b/app/app.py @@ -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') diff --git a/app/deploy.sh b/app/deploy.sh new file mode 100644 index 0000000..53eee0e --- /dev/null +++ b/app/deploy.sh @@ -0,0 +1,9 @@ +#!/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 +#python3 -m pip install flask +#python3 app.py >> log.txt 2>&1 & +#nohup python3 -u ./app.py > output.log & \ No newline at end of file diff --git a/app/requirements.txt b/app/requirements.txt new file mode 100644 index 0000000..8ab6294 --- /dev/null +++ b/app/requirements.txt @@ -0,0 +1 @@ +flask \ No newline at end of file diff --git a/main.tf b/main.tf index fc86d82..5bed2af 100644 --- a/main.tf +++ b/main.tf @@ -24,31 +24,6 @@ resource "google_compute_subnetwork" "default" { network = google_compute_network.vpc_network.id } -# 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" - } - } - - ## INSTALL FLASK - metadata_startup_script = "sudo apt-get update; sudo apt-get install -yq build-essential python3-pip rsync; pip install flask" - - network_interface { - subnetwork = google_compute_subnetwork.default.id - - access_config { - # Include this section to give the VM an external IP address - } - } -} - ## FIREWALL ### SSH resource "google_compute_firewall" "ssh" { @@ -76,6 +51,78 @@ resource "google_compute_firewall" "flask" { 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 APP.PY + DEPLOY.SH - NOT WORKING + # provisioner "file" { + # source = "app/deploy.sh" + # destination = "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)}" + # } + # } + + 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)}" + } + } + + # provisioner "local-exec" { + # command = "ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -u {var.gcp_ssh_user} -i '${self.ipv4_address},' --private-key ${var.gcp_ssh_priv_key_file} playbook.yml" + # } + + ### 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"]) diff --git a/terraform.tfvars b/terraform.tfvars index 47f8fff..43dbfe5 100644 --- a/terraform.tfvars +++ b/terraform.tfvars @@ -1,5 +1,8 @@ # GCP Settings -gcp_project_id = "terraform-demo-381114" +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" \ No newline at end of file +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" \ No newline at end of file diff --git a/variables.tf b/variables.tf index caa48e1..fe7f9ac 100644 --- a/variables.tf +++ b/variables.tf @@ -20,4 +20,19 @@ variable "gcp_project_id" { 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" } \ No newline at end of file