From e91f3ec3ac714d2af2062d738de9ba115f100487 Mon Sep 17 00:00:00 2001 From: Ramiro Castillo Date: Thu, 23 Feb 2023 00:18:40 -0300 Subject: [PATCH 01/23] Added Docker files --- Dockerfile | 23 +++++++++++++++++++++++ docker-compose.yaml | 0 requirements.txt | 3 +++ 3 files changed, 26 insertions(+) create mode 100644 Dockerfile create mode 100644 docker-compose.yaml create mode 100644 requirements.txt diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..ff819c4 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,23 @@ +# Use an official Python runtime as a parent image +FROM python:3.7-slim-buster + +# Set the working directory to /app +WORKDIR /app + +# Copy the requirements file into the container +COPY requirements.txt . + +# Install any needed packages specified in requirements.txt +RUN pip install --trusted-host pypi.python.org -r requirements.txt + +# Copy the rest of the application code into the container +COPY /app . + +# Set the environment variable for Flask +ENV FLASK_APP=main.py + +# Expose port 5000 for the Flask app to listen on +EXPOSE 5000 + +# Run the command to start the Flask app +CMD ["flask", "run", "--host=0.0.0.0"] diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..e69de29 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..a005cb5 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +psycopg2-binary +flask +flask_sqlalchemy \ No newline at end of file From f2a836dee909a57b6f1c1cda2d18644ecd3b0cf3 Mon Sep 17 00:00:00 2001 From: Ramiro Castillo Date: Fri, 24 Feb 2023 19:42:48 -0300 Subject: [PATCH 02/23] Added postgresql folder --- Dockerfile | 6 +++--- app/db.py | 28 ++++++++++++++++------------ app/main.py | 18 ++++++++++++++---- docker-compose.yaml | 32 ++++++++++++++++++++++++++++++++ postgresql/init.sql | 9 +++++++++ 5 files changed, 74 insertions(+), 19 deletions(-) create mode 100644 postgresql/init.sql diff --git a/Dockerfile b/Dockerfile index ff819c4..427538c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Use an official Python runtime as a parent image -FROM python:3.7-slim-buster +FROM python:3.7-alpine # Set the working directory to /app WORKDIR /app @@ -8,7 +8,7 @@ WORKDIR /app COPY requirements.txt . # Install any needed packages specified in requirements.txt -RUN pip install --trusted-host pypi.python.org -r requirements.txt +RUN pip install -r requirements.txt # Copy the rest of the application code into the container COPY /app . @@ -20,4 +20,4 @@ ENV FLASK_APP=main.py EXPOSE 5000 # Run the command to start the Flask app -CMD ["flask", "run", "--host=0.0.0.0"] +CMD ["flask","run", "--host=0.0.0.0"] diff --git a/app/db.py b/app/db.py index 4d363f5..7a3cd9d 100644 --- a/app/db.py +++ b/app/db.py @@ -34,16 +34,16 @@ def createUpdateUser(self, username, dateOfBirth): if user_exists: cur.execute("UPDATE users SET dateOfBirth=%s WHERE username=%s", (dateOfBirth, username.lower())) self.conn.commit() - return {"status": 204, "message": f"User {username.lower()} updated successfully."} + return {"status": 204, "message": f"User {username.lower()} updated successfully."}, 204 else: cur.execute("INSERT INTO users (username, dateOfBirth) VALUES (%s, %s)", (username.lower(), dateOfBirth)) self.conn.commit() - return {"status": 204, "message": f"User '{username.lower()}' created successfully."} + return {"status": 204, "message": f"User '{username.lower()}' created successfully."}, 204 except Error as e: print(f"Error creating user: {e}") self.conn.rollback() - return {"status": 400, "message": str(e)} + return {"status": 400, "message": str(e)}, 400 def isBirthday(self, username): date_format = '%Y-%m-%d' @@ -52,18 +52,22 @@ def isBirthday(self, username): with self.conn.cursor() as cur: cur.execute("SELECT dateOfBirth FROM users WHERE username=%s", (username.lower(),)) birthday = cur.fetchone() - birthday = datetime.strptime(birthday[0], date_format) - birthday = birthday.replace(year=today.year) - delta = abs(birthday - today) - if today > birthday: - return 365 - delta.days - if today == birthday: - return 0 + if birthday == None: + return None else: - return delta.days + birthday = datetime.strptime(str(birthday[0]), date_format) + birthday = birthday.replace(year=today.year) + delta = abs(birthday - today) + if today > birthday: + return 365 - delta.days + if today == birthday: + return 0 + else: + return delta.days except Error as e: print(f"Error fetching birthday: {e}") - + # except NoneType as e: + # print(f"Error, no user: {e}") def disconnect(self): self.conn.close() print("Disconnected from database") diff --git a/app/main.py b/app/main.py index c1f2967..aa2ed05 100644 --- a/app/main.py +++ b/app/main.py @@ -16,7 +16,6 @@ db = SQLAlchemy(app) db_conn = PostgreSQL(db_name, db_user, db_pass, db_host, db_port) -db_conn.connect() def verifyDate(date=str): pattern = "(?:19\d{2}|20[01][0-9]|2023)[-/.](?:0[1-9]|1[012])[-/.](?:0[1-9]|[12][0-9]|3[01])\b" @@ -34,11 +33,14 @@ def hello_world(username): if 'dateOfBirth' in json_data: dob = json_data['dateOfBirth'] if verifyDate(dob): + db_conn.connect() try: db_conn.createUpdateUser(username, dob) - return "OK", 204 + return {}, 204 except: - return 400 + return {}, 400 + finally: + db_conn.disconnect() else: return jsonify({"message":"dateOfBirth format isn't YYYY-MM-DD", "status": 400}), 400 else: @@ -46,19 +48,27 @@ def hello_world(username): else: return jsonify({"message":f"Request not in json format {type(request)}", "status": 400}), 400 else: + db_conn.connect() try: if db_conn.isBirthday(username) == 0: return { "message":f"Hello, {username.capitalize()}! Happy birthday!" }, 200 - else: + if db_conn.isBirthday(username) != 0 and db_conn.isBirthday(username) is not None: return { "message":f"Hello, {username.capitalize()}! Your birthday is in {db_conn.isBirthday(username)} day(s)!" }, 200 + elif db_conn.isBirthday(username) == None: + return { + "message":f"Error: User {username.capitalize()} doesn't exist." + }, 400 except IndexError as e: return { "message":f"Error occurred {e}" }, 400 + finally: + db_conn.disconnect() + if __name__ == "__main__": app.run(debug='False') diff --git a/docker-compose.yaml b/docker-compose.yaml index e69de29..c44ce76 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -0,0 +1,32 @@ +version: '3' +services: + # app: + # build: + # context: . + # dockerfile: Dockerfile + # ports: + # - "5000:5000" + # environment: + # DB_USER: admin + # DB_PASS: admin + # DB_HOST: db + # DB_NAME: suppliers + # depends_on: + # postgres: + # condition: service_started + + postgres: + image: postgres + ports: + - "5432:5432" + environment: + POSTGRES_USER: admin + POSTGRES_PASSWORD: admin + POSTGRES_DB: localhost + volumes: + - ./postgresql/init.sql:/docker-entrypoint-initdb.d/init.sql + healthcheck: + test: ["CMD-SHELL", "pg_isready -U admin -d suppliers"] + interval: 10s + timeout: 5s + retries: 5 \ No newline at end of file diff --git a/postgresql/init.sql b/postgresql/init.sql new file mode 100644 index 0000000..7aaba4c --- /dev/null +++ b/postgresql/init.sql @@ -0,0 +1,9 @@ +CREATE DATABASE suppliers; + +\c suppliers + +CREATE TABLE users ( + id SERIAL PRIMARY KEY, + username VARCHAR(100) NOT NULL, + dateOfBirth DATE NOT NULL +); From 81e4f94689e739761bce8c3188273621361f83a4 Mon Sep 17 00:00:00 2001 From: Ramiro Castillo Date: Fri, 24 Feb 2023 23:25:01 -0300 Subject: [PATCH 03/23] Added tf and helm files for postgresql deployment on gke --- postgresql/deployment/dev.tfvars | 5 ++++ postgresql/deployment/main.tf | 30 +++++++++++++++++++ postgresql/deployment/prod.tfvars | 5 ++++ postgresql/deployment/variables.tf | 38 ++++++++++++++++++++++++ postgresql/modules/main.tf | 46 ++++++++++++++++++++++++++++++ postgresql/modules/variables.tf | 24 ++++++++++++++++ 6 files changed, 148 insertions(+) create mode 100644 postgresql/deployment/dev.tfvars create mode 100644 postgresql/deployment/main.tf create mode 100644 postgresql/deployment/prod.tfvars create mode 100644 postgresql/deployment/variables.tf create mode 100644 postgresql/modules/main.tf create mode 100644 postgresql/modules/variables.tf diff --git a/postgresql/deployment/dev.tfvars b/postgresql/deployment/dev.tfvars new file mode 100644 index 0000000..e57564b --- /dev/null +++ b/postgresql/deployment/dev.tfvars @@ -0,0 +1,5 @@ +env = "dev" + +cluster_name = "flash-app-v1-dev" + +location = "europe-west1" diff --git a/postgresql/deployment/main.tf b/postgresql/deployment/main.tf new file mode 100644 index 0000000..2ec75e3 --- /dev/null +++ b/postgresql/deployment/main.tf @@ -0,0 +1,30 @@ +# Deploy pgsql cluster on GKE + +# https://registry.terraform.io/providers/hashicorp/helm/latest/docs +provider "helm" { + kubernetes { + config_path = var.kubeconfig_path + } + alias = "gke" +} + +# https://www.terraform.io/docs/language/settings/index.html +terraform { + required_version = ">= 1.0.0" + required_providers { + helm = { + source = "hashicorp/helm" + version = "~> 2.3.0" + } + } +} + +module "postgresql" { + source = "../modules" + + enable_ha = var.env == "prod" ? true : false + postgresqlPassword = var.pgPass + postgresqlUsername = var.pgUser + postgresqlDatabase = var.pgDb + +} \ No newline at end of file diff --git a/postgresql/deployment/prod.tfvars b/postgresql/deployment/prod.tfvars new file mode 100644 index 0000000..68216df --- /dev/null +++ b/postgresql/deployment/prod.tfvars @@ -0,0 +1,5 @@ +env = "prod" + +cluster_name = "flash-app-v1-prod" + +location = "europe-west1" \ No newline at end of file diff --git a/postgresql/deployment/variables.tf b/postgresql/deployment/variables.tf new file mode 100644 index 0000000..318ffb4 --- /dev/null +++ b/postgresql/deployment/variables.tf @@ -0,0 +1,38 @@ +variable "pgPass" { + description = "PostgreSQL Password" + type = string +} + +variable "pgUser" { + description = "PostgreSQL Username" + type = string +} + +variable "pgDb" { + description = "PostgreSQL Database" + type = string +} +variable "kubeconfig_path" { + description = "GKE kubeconfig path (usually ~/.kube/config)" + type = string +} + +variable "cluster_name" { + type = string + description = "GKE cluster name" +} + +variable "location" { + type = string + description = "GKE Location" +} + +variable "env" { + description = "Environment" + type = string + + validation { + condition = contains(["prod", "dev"], var.env) + error_message = "${var.env} not in accepted values: \"prod\", \"env\"" + } +} \ No newline at end of file diff --git a/postgresql/modules/main.tf b/postgresql/modules/main.tf new file mode 100644 index 0000000..f4dfe87 --- /dev/null +++ b/postgresql/modules/main.tf @@ -0,0 +1,46 @@ +// PGSQL DEV +resource "helm_release" "postgresql_dev" { + count = var.env == "prod" ? 0 : 1 + name = "bitnami" + repository = "https://charts.bitnami.com/bitnami" + chart = "postgresql" + + set_sensitive { + name = "global.postgresql.postgresqlPassword" + value = var.pgPass + } + + set_sensitive { + name = "global.postgresql.postgresqlUsername" + value = var.pgUser + } + + set_sensitive { + name = "global.postgresql.postgresqlDatabase" + value = var.pgDb + } + +} + +// PGSQL PROD +resource "helm_release" "postgresql_prod" { + count = var.env == "prod" ? 1 : 0 + name = "bitnami" + repository = "https://charts.bitnami.com/bitnami" + chart = "postgresql-ha" + + set_sensitive { + name = "global.postgresql.password" + value = var.pgPass + } + + set_sensitive { + name = "global.postgresql.username" + value = var.pgUser + } + + set_sensitive { + name = "global.postgresql.database" + value = var.pgDb + } +} \ No newline at end of file diff --git a/postgresql/modules/variables.tf b/postgresql/modules/variables.tf new file mode 100644 index 0000000..cbe08f7 --- /dev/null +++ b/postgresql/modules/variables.tf @@ -0,0 +1,24 @@ +variable "env" { + description = "Environment" + type = string + + validation { + condition = contains(["prod", "dev"], var.env) + error_message = "${var.env} not in accepted values: \"prod\", \"env\"" + } +} + +variable "pgPass" { + description = "PostgreSQL Password" + type = string +} + +variable "pgUser" { + description = "PostgreSQL Username" + type = string +} + +variable "pgDb" { + description = "PostgreSQL Database" + type = string +} \ No newline at end of file From 1ed3d29ba052152ac6f3b378fbe3c7813837515d Mon Sep 17 00:00:00 2001 From: Ramiro Castillo Date: Sat, 25 Feb 2023 01:16:46 -0300 Subject: [PATCH 04/23] Added gke infra tf and postgresql helm files --- postgresql/deployment/dev.tfvars | 8 ++++++++ postgresql/deployment/main.tf | 32 +++++--------------------------- 2 files changed, 13 insertions(+), 27 deletions(-) diff --git a/postgresql/deployment/dev.tfvars b/postgresql/deployment/dev.tfvars index e57564b..3420d28 100644 --- a/postgresql/deployment/dev.tfvars +++ b/postgresql/deployment/dev.tfvars @@ -3,3 +3,11 @@ env = "dev" cluster_name = "flash-app-v1-dev" location = "europe-west1" + +kubeconfig_path = "~/.kube/config" + +pgDb = "pgdb" + +pgPass = "admin" + +pgUser = "admin" diff --git a/postgresql/deployment/main.tf b/postgresql/deployment/main.tf index 2ec75e3..79a8471 100644 --- a/postgresql/deployment/main.tf +++ b/postgresql/deployment/main.tf @@ -1,30 +1,8 @@ # Deploy pgsql cluster on GKE - -# https://registry.terraform.io/providers/hashicorp/helm/latest/docs -provider "helm" { - kubernetes { - config_path = var.kubeconfig_path - } - alias = "gke" -} - -# https://www.terraform.io/docs/language/settings/index.html -terraform { - required_version = ">= 1.0.0" - required_providers { - helm = { - source = "hashicorp/helm" - version = "~> 2.3.0" - } - } -} - module "postgresql" { - source = "../modules" - - enable_ha = var.env == "prod" ? true : false - postgresqlPassword = var.pgPass - postgresqlUsername = var.pgUser - postgresqlDatabase = var.pgDb - + source = "../modules" + env = var.env + pgPass = var.pgPass + pgUser = var.pgUser + pgDb = var.pgDb } \ No newline at end of file From 313c9dace325b1b86248bc687e37a157095ef44e Mon Sep 17 00:00:00 2001 From: Ramiro Castillo Date: Tue, 28 Feb 2023 18:58:48 -0300 Subject: [PATCH 05/23] Reworked Flask api structure --- Dockerfile | 2 +- app/config.py | 39 ++++++++++++++++-------- app/database.ini | 5 ---- app/db.py | 73 -------------------------------------------- app/functions.py | 12 -------- app/main.py | 78 +++++++----------------------------------------- requirements.txt | 3 +- 7 files changed, 40 insertions(+), 172 deletions(-) delete mode 100644 app/database.ini delete mode 100644 app/db.py delete mode 100644 app/functions.py diff --git a/Dockerfile b/Dockerfile index 427538c..c83ccf5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,4 +20,4 @@ ENV FLASK_APP=main.py EXPOSE 5000 # Run the command to start the Flask app -CMD ["flask","run", "--host=0.0.0.0"] +CMD ["flask", "run", "--host=0.0.0.0"] diff --git a/app/config.py b/app/config.py index 9fe85c2..3b2fea1 100644 --- a/app/config.py +++ b/app/config.py @@ -1,16 +1,29 @@ -from configparser import ConfigParser +import os +basedir = os.path.abspath(os.path.dirname(__file__)) -def config(filename='database.ini', section='postgresql'): - parser = ConfigParser() - parser.read(filename) +db_user = os.environ['DB_USER'] +db_pass = os.environ['DB_PASS'] +db_host = os.environ['DB_HOST'] +db_name = os.environ['DB_NAME'] - db = {} - if parser.has_section(section): - params = parser.items(section) - for param in params: - db[param[0]] = param[1] +class Config(object): + DEBUG = False + DEVELOPMENT = False + TESTING = False + CSRF_ENABLED = False + SECRET_KEY = "" + SQLALCHEMY_DATABASE_URI = f'postgresql://{db_user}:{db_pass}@{db_host}/{db_name}' - else: - raise Exception(f'Section {section} not found in the {filename}') - - return db \ No newline at end of file +class ProductionConfig(Config): + DEBUG = False + +class StagingConfig(Config): + DEBUG = True + DEVELOPMENT = True + +class DevelopmentConfig(Config): + DEVELOPMENT = True + DEBUG = True + +class TestingConfig(Config): + TESTING = True \ No newline at end of file diff --git a/app/database.ini b/app/database.ini deleted file mode 100644 index 5a07986..0000000 --- a/app/database.ini +++ /dev/null @@ -1,5 +0,0 @@ -[postgresql] -host=localhost -database=suppliers -user=admin -password=admin \ No newline at end of file diff --git a/app/db.py b/app/db.py deleted file mode 100644 index 7a3cd9d..0000000 --- a/app/db.py +++ /dev/null @@ -1,73 +0,0 @@ -import psycopg2 -from psycopg2 import Error -from datetime import datetime - -class PostgreSQL: - def __init__(self, dbname, user, password, host, port): - self.dbname = dbname - self.user = user - self.password = password - self.host = host - self.port = port - self.conn = None - - def connect(self): - try: - self.conn = psycopg2.connect( - dbname=self.dbname, - user=self.user, - password=self.password, - host=self.host, - port=self.port - ) - print("Connected to database.") - except Error as e: - print(f"Error connecting to db: {e}") - self.conn = None - - def createUpdateUser(self, username, dateOfBirth): - try: - with self.conn.cursor() as cur: - cur.execute("SELECT 1 FROM users WHERE username=%s", (username.lower(),)) - user_exists = cur.fetchone() - - if user_exists: - cur.execute("UPDATE users SET dateOfBirth=%s WHERE username=%s", (dateOfBirth, username.lower())) - self.conn.commit() - return {"status": 204, "message": f"User {username.lower()} updated successfully."}, 204 - else: - cur.execute("INSERT INTO users (username, dateOfBirth) VALUES (%s, %s)", (username.lower(), dateOfBirth)) - self.conn.commit() - return {"status": 204, "message": f"User '{username.lower()}' created successfully."}, 204 - - except Error as e: - print(f"Error creating user: {e}") - self.conn.rollback() - return {"status": 400, "message": str(e)}, 400 - - def isBirthday(self, username): - date_format = '%Y-%m-%d' - today = datetime.today() - try: - with self.conn.cursor() as cur: - cur.execute("SELECT dateOfBirth FROM users WHERE username=%s", (username.lower(),)) - birthday = cur.fetchone() - if birthday == None: - return None - else: - birthday = datetime.strptime(str(birthday[0]), date_format) - birthday = birthday.replace(year=today.year) - delta = abs(birthday - today) - if today > birthday: - return 365 - delta.days - if today == birthday: - return 0 - else: - return delta.days - except Error as e: - print(f"Error fetching birthday: {e}") - # except NoneType as e: - # print(f"Error, no user: {e}") - def disconnect(self): - self.conn.close() - print("Disconnected from database") diff --git a/app/functions.py b/app/functions.py deleted file mode 100644 index bd2b28b..0000000 --- a/app/functions.py +++ /dev/null @@ -1,12 +0,0 @@ -import re - -def dateVerification(date=str): - pattern = "^\d{4}\-(0[1-9]|1[012])\-(0[1-9]|[12][0-9]|3[01])$" - try: - re.match(pattern, date) - return True - except: - return False - - -dateVerification(1) \ No newline at end of file diff --git a/app/main.py b/app/main.py index aa2ed05..f7c7315 100644 --- a/app/main.py +++ b/app/main.py @@ -1,74 +1,18 @@ -from flask import Flask, request, jsonify +from flask import Flask from flask_sqlalchemy import SQLAlchemy -from db import PostgreSQL -import re, os +from flask_cors import CORS +from api.user import user_route +import os +from config import ProductionConfig - -# db_user = os.environ["DB_USER"] -# db_pass = os.environ["DB_PASS"] -# db_host = os.environ["DB_HOST"] -# db_name = os.environ["DB_NAME"] - -db_user, db_pass, db_host, db_name, db_port= "admin", "admin", "localhost", "suppliers", "5432" +config = ProductionConfig() app = Flask(__name__) -app.config['SQLALCHEMY_DATABASE_URI'] = f'postgresql://{db_user}:{db_pass}@{db_host}/{db_name}' -db = SQLAlchemy(app) +app.register_blueprint(user_route) -db_conn = PostgreSQL(db_name, db_user, db_pass, db_host, db_port) - -def verifyDate(date=str): - pattern = "(?:19\d{2}|20[01][0-9]|2023)[-/.](?:0[1-9]|1[012])[-/.](?:0[1-9]|[12][0-9]|3[01])\b" - try: - re.match(pattern, date) - return True - except: - return False - -@app.route('/hello/', methods=['GET','PUT']) -def hello_world(username): - if request.method == 'PUT': - if request.is_json: - json_data = request.get_json() - if 'dateOfBirth' in json_data: - dob = json_data['dateOfBirth'] - if verifyDate(dob): - db_conn.connect() - try: - db_conn.createUpdateUser(username, dob) - return {}, 204 - except: - return {}, 400 - finally: - db_conn.disconnect() - else: - return jsonify({"message":"dateOfBirth format isn't YYYY-MM-DD", "status": 400}), 400 - else: - return jsonify({"message":"Missing required attribute \"dateOfBirth\"", "status": 400}), 400 - else: - return jsonify({"message":f"Request not in json format {type(request)}", "status": 400}), 400 - else: - db_conn.connect() - try: - if db_conn.isBirthday(username) == 0: - return { - "message":f"Hello, {username.capitalize()}! Happy birthday!" - }, 200 - if db_conn.isBirthday(username) != 0 and db_conn.isBirthday(username) is not None: - return { - "message":f"Hello, {username.capitalize()}! Your birthday is in {db_conn.isBirthday(username)} day(s)!" - }, 200 - elif db_conn.isBirthday(username) == None: - return { - "message":f"Error: User {username.capitalize()} doesn't exist." - }, 400 - except IndexError as e: - return { - "message":f"Error occurred {e}" - }, 400 - finally: - db_conn.disconnect() - +CORS(app) +app.config.from_object(config) +db = SQLAlchemy(app) if __name__ == "__main__": - app.run(debug='False') + app.run(debug='False', host='0.0.0.0') diff --git a/requirements.txt b/requirements.txt index a005cb5..9f1497a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ psycopg2-binary flask -flask_sqlalchemy \ No newline at end of file +flask_sqlalchemy +monoengine \ No newline at end of file From 995659b73931dd9b8610d887671ac4df6a2c13e8 Mon Sep 17 00:00:00 2001 From: Ramiro Castillo Date: Tue, 28 Feb 2023 21:31:24 -0300 Subject: [PATCH 06/23] Fixed names of user_service functions --- docker-compose.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docker-compose.yaml b/docker-compose.yaml index c44ce76..6a7d562 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -25,8 +25,8 @@ services: POSTGRES_DB: localhost volumes: - ./postgresql/init.sql:/docker-entrypoint-initdb.d/init.sql - healthcheck: - test: ["CMD-SHELL", "pg_isready -U admin -d suppliers"] - interval: 10s - timeout: 5s - retries: 5 \ No newline at end of file + # healthcheck: + # test: ["CMD-SHELL", "pg_isready -U admin -d suppliers"] + # interval: 10s + # timeout: 5s + # retries: 5 \ No newline at end of file From 2ef2b67da19cea92c8ed2da13c4458a9450e2016 Mon Sep 17 00:00:00 2001 From: Ramiro Castillo Date: Tue, 28 Feb 2023 21:40:23 -0300 Subject: [PATCH 07/23] Added postgresql deployment files and api structure --- app/api/user.py | 12 +++++ app/models/user.py | 0 app/services/user_service.py | 53 ++++++++++++++++++++++ app/utils/DbConnection.py | 73 ++++++++++++++++++++++++++++++ app/utils/VerifyDate.py | 10 ++++ postgresql/deployment/providers.tf | 7 +++ postgresql/deployment/version.tf | 14 ++++++ 7 files changed, 169 insertions(+) create mode 100644 app/api/user.py create mode 100644 app/models/user.py create mode 100644 app/services/user_service.py create mode 100644 app/utils/DbConnection.py create mode 100644 app/utils/VerifyDate.py create mode 100644 postgresql/deployment/providers.tf create mode 100644 postgresql/deployment/version.tf diff --git a/app/api/user.py b/app/api/user.py new file mode 100644 index 0000000..ad4ce9c --- /dev/null +++ b/app/api/user.py @@ -0,0 +1,12 @@ +from flask import Blueprint, request +from services.user_service import get_user_service, put_user_service + +user_route = Blueprint('user_route', __name__) + +@user_route.route('/hello/', methods=['GET']) +def hello_world_get(username): + return get_user_service(username) + +@user_route.route('/hello/', methods=['PUT']) +def hello_world_put(username): + return put_user_service(username, request) \ No newline at end of file diff --git a/app/models/user.py b/app/models/user.py new file mode 100644 index 0000000..e69de29 diff --git a/app/services/user_service.py b/app/services/user_service.py new file mode 100644 index 0000000..acfde4d --- /dev/null +++ b/app/services/user_service.py @@ -0,0 +1,53 @@ +from flask import make_response +from utils.VerifyDate import VerifyDate +from utils.DbConnection import PostgreSQL +import os + +db_user = os.environ["DB_USER"] +db_pass = os.environ["DB_PASS"] +db_host = os.environ["DB_HOST"] +db_name = os.environ["DB_NAME"] +db_port = os.environ["DB_PORT"] + +db_conn = PostgreSQL( + dbname = db_name, + password = db_pass, + host = db_host, + user = db_user, + port = db_port + ) + +def put_user_service(username, request): + if request.is_json: + json_data = request.get_json() + if 'dateOfBirth' in json_data: + dob = json_data['dateOfBirth'] + if VerifyDate.verifyDate(dob): + db_conn.connect() + try: + db_conn.createUpdateUser(username, dob) + return make_response({}, 204) + except: + return make_response({}, 400) + finally: + db_conn.disconnect() + else: + return make_response({"message" : "dateOfBirth format isn't YYYY-MM-DD", "status": 400}, 400) + else: + return make_response({"message":"Missing required attribute \"dateOfBirth\"", "status": 400}, 400) + else: + return make_response({"message":f"Request not in json format {type(request)}", "status": 400}, 400) + +def get_user_service(username): + db_conn.connect() + try: + if db_conn.isBirthday(username) == 0: + return make_response({"message":f"Hello, {username.capitalize()}! Happy birthday!"}, 200) + if db_conn.isBirthday(username) != 0 and db_conn.isBirthday(username) is not None: + return make_response({"message":f"Hello, {username.capitalize()}! Your birthday is in {db_conn.isBirthday(username)} day(s)!"}, 200) + elif db_conn.isBirthday(username) == None: + return make_response({"message":f"Error: User {username.capitalize()} doesn't exist."}, 400) + except Exception as e: + return make_response({"message":f"Error occurred {e}"}, 400) + finally: + db_conn.disconnect() \ No newline at end of file diff --git a/app/utils/DbConnection.py b/app/utils/DbConnection.py new file mode 100644 index 0000000..7a3cd9d --- /dev/null +++ b/app/utils/DbConnection.py @@ -0,0 +1,73 @@ +import psycopg2 +from psycopg2 import Error +from datetime import datetime + +class PostgreSQL: + def __init__(self, dbname, user, password, host, port): + self.dbname = dbname + self.user = user + self.password = password + self.host = host + self.port = port + self.conn = None + + def connect(self): + try: + self.conn = psycopg2.connect( + dbname=self.dbname, + user=self.user, + password=self.password, + host=self.host, + port=self.port + ) + print("Connected to database.") + except Error as e: + print(f"Error connecting to db: {e}") + self.conn = None + + def createUpdateUser(self, username, dateOfBirth): + try: + with self.conn.cursor() as cur: + cur.execute("SELECT 1 FROM users WHERE username=%s", (username.lower(),)) + user_exists = cur.fetchone() + + if user_exists: + cur.execute("UPDATE users SET dateOfBirth=%s WHERE username=%s", (dateOfBirth, username.lower())) + self.conn.commit() + return {"status": 204, "message": f"User {username.lower()} updated successfully."}, 204 + else: + cur.execute("INSERT INTO users (username, dateOfBirth) VALUES (%s, %s)", (username.lower(), dateOfBirth)) + self.conn.commit() + return {"status": 204, "message": f"User '{username.lower()}' created successfully."}, 204 + + except Error as e: + print(f"Error creating user: {e}") + self.conn.rollback() + return {"status": 400, "message": str(e)}, 400 + + def isBirthday(self, username): + date_format = '%Y-%m-%d' + today = datetime.today() + try: + with self.conn.cursor() as cur: + cur.execute("SELECT dateOfBirth FROM users WHERE username=%s", (username.lower(),)) + birthday = cur.fetchone() + if birthday == None: + return None + else: + birthday = datetime.strptime(str(birthday[0]), date_format) + birthday = birthday.replace(year=today.year) + delta = abs(birthday - today) + if today > birthday: + return 365 - delta.days + if today == birthday: + return 0 + else: + return delta.days + except Error as e: + print(f"Error fetching birthday: {e}") + # except NoneType as e: + # print(f"Error, no user: {e}") + def disconnect(self): + self.conn.close() + print("Disconnected from database") diff --git a/app/utils/VerifyDate.py b/app/utils/VerifyDate.py new file mode 100644 index 0000000..9bcce78 --- /dev/null +++ b/app/utils/VerifyDate.py @@ -0,0 +1,10 @@ +import re + +class VerifyDate: + def verifyDate(date): + pattern = "(?:19\d{2}|20[01][0-9]|2023)[-/.](?:0[1-9]|1[012])[-/.](?:0[1-9]|[12][0-9]|3[01])\b" + try: + re.match(pattern, date) + return True + except: + return False \ No newline at end of file diff --git a/postgresql/deployment/providers.tf b/postgresql/deployment/providers.tf new file mode 100644 index 0000000..c5290f4 --- /dev/null +++ b/postgresql/deployment/providers.tf @@ -0,0 +1,7 @@ +# https://registry.terraform.io/providers/hashicorp/helm/latest/docs +provider "helm" { + kubernetes { + config_path = var.kubeconfig_path + } + alias = "gke" +} \ No newline at end of file diff --git a/postgresql/deployment/version.tf b/postgresql/deployment/version.tf new file mode 100644 index 0000000..c0a937b --- /dev/null +++ b/postgresql/deployment/version.tf @@ -0,0 +1,14 @@ +# https://www.terraform.io/docs/language/settings/index.html +terraform { + required_version = ">= 1.0.0" + required_providers { + helm = { + source = "hashicorp/helm" + version = "~> 2.3.0" + } + } + backend "gcs" { + bucket = "tf-flash-app-v1" + prefix = "postgresql_state" + } +} \ No newline at end of file From a378bb1c92cce1e55a89816a7059bf7b9b5c558c Mon Sep 17 00:00:00 2001 From: Ramiro Castillo Date: Tue, 28 Feb 2023 23:25:30 -0300 Subject: [PATCH 08/23] Fixed connection problem between both containers --- app/config.py | 9 ++++--- app/services/user_service.py | 10 ++++---- app/utils/DbConnection.py | 10 ++++---- docker-compose.yaml | 48 +++++++++++++++++++----------------- postgresql/init.sql | 8 +++--- requirements.txt | 3 ++- 6 files changed, 47 insertions(+), 41 deletions(-) diff --git a/app/config.py b/app/config.py index 3b2fea1..3f51dc0 100644 --- a/app/config.py +++ b/app/config.py @@ -1,10 +1,11 @@ import os basedir = os.path.abspath(os.path.dirname(__file__)) -db_user = os.environ['DB_USER'] -db_pass = os.environ['DB_PASS'] -db_host = os.environ['DB_HOST'] -db_name = os.environ['DB_NAME'] +db_user = os.environ['POSTGRES_USER'] +db_pass = os.environ['POSTGRES_PASSWORD'] +db_host = os.environ['POSTGRES_HOST'] +db_name = os.environ['POSTGRES_DB'] +db_port = os.environ['POSTGRES_PORT'] class Config(object): DEBUG = False diff --git a/app/services/user_service.py b/app/services/user_service.py index acfde4d..dc89fc4 100644 --- a/app/services/user_service.py +++ b/app/services/user_service.py @@ -3,11 +3,11 @@ from utils.DbConnection import PostgreSQL import os -db_user = os.environ["DB_USER"] -db_pass = os.environ["DB_PASS"] -db_host = os.environ["DB_HOST"] -db_name = os.environ["DB_NAME"] -db_port = os.environ["DB_PORT"] +db_user = os.environ["POSTGRES_USER"] +db_pass = os.environ["POSTGRES_PASSWORD"] +db_host = os.environ["POSTGRES_HOST"] +db_name = os.environ["POSTGRES_DB"] +db_port = os.environ["POSTGRES_PORT"] db_conn = PostgreSQL( dbname = db_name, diff --git a/app/utils/DbConnection.py b/app/utils/DbConnection.py index 7a3cd9d..3de405e 100644 --- a/app/utils/DbConnection.py +++ b/app/utils/DbConnection.py @@ -28,15 +28,15 @@ def connect(self): def createUpdateUser(self, username, dateOfBirth): try: with self.conn.cursor() as cur: - cur.execute("SELECT 1 FROM users WHERE username=%s", (username.lower(),)) + cur.execute(f"SELECT 1 FROM usuarios WHERE username='{username.lower()}'") user_exists = cur.fetchone() if user_exists: - cur.execute("UPDATE users SET dateOfBirth=%s WHERE username=%s", (dateOfBirth, username.lower())) + cur.execute(f"UPDATE usuarios SET dateOfBirth='{dateOfBirth}' WHERE username='{username.lower()}'") self.conn.commit() - return {"status": 204, "message": f"User {username.lower()} updated successfully."}, 204 + return {"status": 204, "message": f"User '{username.lower()}' updated successfully."}, 204 else: - cur.execute("INSERT INTO users (username, dateOfBirth) VALUES (%s, %s)", (username.lower(), dateOfBirth)) + cur.execute(f"INSERT INTO usuarios (username, dateOfBirth) VALUES ('{username.lower()}', '{dateOfBirth}')") self.conn.commit() return {"status": 204, "message": f"User '{username.lower()}' created successfully."}, 204 @@ -50,7 +50,7 @@ def isBirthday(self, username): today = datetime.today() try: with self.conn.cursor() as cur: - cur.execute("SELECT dateOfBirth FROM users WHERE username=%s", (username.lower(),)) + cur.execute(f"SELECT dateOfBirth FROM usuarios WHERE username='{username.lower()}'") birthday = cur.fetchone() if birthday == None: return None diff --git a/docker-compose.yaml b/docker-compose.yaml index 6a7d562..074984f 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,32 +1,36 @@ version: '3' services: - # app: - # build: - # context: . - # dockerfile: Dockerfile - # ports: - # - "5000:5000" - # environment: - # DB_USER: admin - # DB_PASS: admin - # DB_HOST: db - # DB_NAME: suppliers - # depends_on: - # postgres: - # condition: service_started + app: + build: + context: . + dockerfile: Dockerfile + networks: + - backend + ports: + - "5000:5000" + depends_on: + - postgres postgres: image: postgres - ports: - - "5432:5432" + networks: + - backend environment: POSTGRES_USER: admin POSTGRES_PASSWORD: admin - POSTGRES_DB: localhost + POSTGRES_DB: suppliers + POSTGRES_HOST: postgres + POSTGRES_PORT: 5432 + ports: + - "5432:5432" volumes: - ./postgresql/init.sql:/docker-entrypoint-initdb.d/init.sql - # healthcheck: - # test: ["CMD-SHELL", "pg_isready -U admin -d suppliers"] - # interval: 10s - # timeout: 5s - # retries: 5 \ No newline at end of file + healthcheck: + test: ["CMD-SHELL", "pg_isready -U admin -d suppliers -h localhost -p 5432"] + interval: 10s + timeout: 5s + retries: 5 + +networks: + backend: + \ No newline at end of file diff --git a/postgresql/init.sql b/postgresql/init.sql index 7aaba4c..9a0871b 100644 --- a/postgresql/init.sql +++ b/postgresql/init.sql @@ -1,9 +1,9 @@ -CREATE DATABASE suppliers; +CREATE DATABASE databesos; -\c suppliers +\c databesos -CREATE TABLE users ( +CREATE TABLE usuarios ( id SERIAL PRIMARY KEY, username VARCHAR(100) NOT NULL, dateOfBirth DATE NOT NULL -); +); \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 9f1497a..dc4c0b8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,5 @@ psycopg2-binary flask flask_sqlalchemy -monoengine \ No newline at end of file +flask_cors +python-dotenv \ No newline at end of file From aca00298843c8e5d4b7e525ffb271a7d581c7a37 Mon Sep 17 00:00:00 2001 From: Ramiro Castillo Date: Tue, 28 Feb 2023 23:27:21 -0300 Subject: [PATCH 09/23] Added GKE infra deployment --- gcp/gke/dev.tfvars | 32 +++++++++++++ gcp/gke/main.tf | 89 ++++++++++++++++++++++++++++++++++++ gcp/gke/prod.tfvars | 0 gcp/gke/providers.tf | 4 ++ gcp/gke/variables.tf | 105 +++++++++++++++++++++++++++++++++++++++++++ gcp/gke/version.tf | 13 ++++++ 6 files changed, 243 insertions(+) create mode 100644 gcp/gke/dev.tfvars create mode 100644 gcp/gke/main.tf create mode 100644 gcp/gke/prod.tfvars create mode 100644 gcp/gke/providers.tf create mode 100644 gcp/gke/variables.tf create mode 100644 gcp/gke/version.tf diff --git a/gcp/gke/dev.tfvars b/gcp/gke/dev.tfvars new file mode 100644 index 0000000..d10465e --- /dev/null +++ b/gcp/gke/dev.tfvars @@ -0,0 +1,32 @@ +project_id = "developing-stuff" + +region = "europe-west1" + +gke_num_nodes = { + max = 2 + min = 1 +} + +gke_preemptible = true + +gke_machine_type = "n1-standard-1" + +gke_subnet_ip_cidr_range = "10.51.0.0/20" + +gke_cluster_autoscaling = { + enabled = true + cpu_minimum = 1 + cpu_maximum = 4 + memory_minimum = 4 + memory_maximum = 16 +} + +gke_disabled_hpa = true + +env_name = "dev" + +cluster_name = "flash-app-v1" + +ip_range_pods_name = "ip-range-pods-name" + +ip_range_services_name = "ip-range-services-name" \ No newline at end of file diff --git a/gcp/gke/main.tf b/gcp/gke/main.tf new file mode 100644 index 0000000..3a3c7e0 --- /dev/null +++ b/gcp/gke/main.tf @@ -0,0 +1,89 @@ +# Create a new private K8s cluster +# Source: https://github.com/terraform-google-modules/terraform-google-kubernetes-engine/tree/master/modules/private-cluster +module "gke" { + source = "terraform-google-modules/kubernetes-engine/google//modules/private-cluster" + version = "= 23.1.0" + name = "${var.cluster_name}-${var.env_name}" + project_id = var.project_id + region = var.region + network = module.gke_vpc.network_name + # subnetwork = module.gke_vpc.subnets["subnet_name"] + subnetwork = "${var.subnetwork}-${var.env_name}" + ip_range_pods = var.ip_range_pods_name + ip_range_services = var.ip_range_services_name + horizontal_pod_autoscaling = var.gke_disabled_hpa + enable_vertical_pod_autoscaling = var.gke_disabled_vpa + cluster_autoscaling = { + enabled = var.gke_cluster_autoscaling.enabled + min_cpu_cores = var.gke_cluster_autoscaling.cpu_minimum + max_cpu_cores = var.gke_cluster_autoscaling.cpu_maximum + min_memory_gb = var.gke_cluster_autoscaling.memory_minimum + max_memory_gb = var.gke_cluster_autoscaling.memory_maximum + gpu_resources = [] + } + + node_pools = [ + { + name = "${var.cluster_name}-${var.env_name}-node-pool" + machine_type = var.gke_machine_type + node_locations = "${var.region}-c" + min_count = var.gke_num_nodes.min + max_count = var.gke_num_nodes.max + preemptible = var.gke_preemptible + initial_node_count = 1 + remove_default_node_pool = true + } + ] + + depends_on = [ + module.gke_vpc + ] +} + +# Create a VPC +# Source: https://github.com/terraform-google-modules/terraform-google-network +module "gke_vpc" { + source = "terraform-google-modules/network/google" + version = "~> 4.0" + project_id = var.project_id + network_name = "${var.network}-${var.env_name}" + # routing_mode = "GLOBAL" + subnets = [ + { + subnet_name = "${var.subnetwork}-${var.env_name}" + subnet_ip = var.gke_subnet_ip_cidr_range + subnet_region = var.region + } + ] + secondary_ranges = { + "${var.subnetwork}-${var.env_name}" = [ + { + ip_cidr_range = "10.20.0.0/16" + range_name = var.ip_range_pods_name + }, + { + ip_cidr_range = "10.30.0.0/16" + range_name = var.ip_range_services_name + } + ] + } +} + +# GKE Auth for retrieving token +# Source: https://github.com/terraform-google-modules/terraform-google-kubernetes-engine/tree/master/modules/auth +module "gke_auth" { + source = "terraform-google-modules/kubernetes-engine/google//modules/auth" + project_id = var.project_id + cluster_name = module.gke.name + location = module.gke.location + # use_private_endpoint = true + depends_on = [ + module.gke + ] +} + +# Save kubeconfig file +resource "local_file" "kubeconfig" { + content = module.gke_auth.kubeconfig_raw + filename = "./kubeconfig-${var.env_name}" +} \ No newline at end of file diff --git a/gcp/gke/prod.tfvars b/gcp/gke/prod.tfvars new file mode 100644 index 0000000..e69de29 diff --git a/gcp/gke/providers.tf b/gcp/gke/providers.tf new file mode 100644 index 0000000..6afd575 --- /dev/null +++ b/gcp/gke/providers.tf @@ -0,0 +1,4 @@ +provider "google" { + project = var.project_id + region = var.region +} \ No newline at end of file diff --git a/gcp/gke/variables.tf b/gcp/gke/variables.tf new file mode 100644 index 0000000..872f9be --- /dev/null +++ b/gcp/gke/variables.tf @@ -0,0 +1,105 @@ +variable "project_id" { + default = "" + description = "GCP project id" + type = string +} + +variable "region" { + default = "" + description = "GCP region" + type = string +} + +variable "gke_num_nodes" { + default = { + min = 1 + max = 2 + } + description = "Number of GKE nodes" + type = object({ + min = number + max = number + }) +} + +variable "gke_preemptible" { + default = true + description = "Boolean variable for setting preemtible machines or not on GKE cluster" + type = bool +} + +variable "gke_machine_type" { + default = "" + description = "GKE machine type" + type = string +} + +variable "gke_disabled_hpa" { + default = true + description = "Boolean. Is HPA disabled?" + type = bool +} + +variable "gke_disabled_vpa" { + default = true + description = "Boolean. Is VPA disabled?" + type = bool +} + +variable "gke_cluster_autoscaling" { + default = { + enabled = true + cpu_minimum = 2 + cpu_maximum = 4 + memory_minimum = 4 + memory_maximum = 16 + } + description = "Object with information for enabling GKE cluster autoscaling" + type = object({ + enabled = bool + cpu_minimum = number + cpu_maximum = number + memory_minimum = number + memory_maximum = number + }) +} + +variable "gke_subnet_ip_cidr_range" { + default = "" + description = "ip cidr range for gcp subnet" + type = string +} + +variable "cluster_name" { + description = "The name for the GKE cluster" + type = string +} + +variable "env_name" { + description = "The environment for the GKE cluster" + default = "dev" + type = string +} + +variable "network" { + description = "The VPC network created to host the cluster in" + default = "gke-network" +} + +variable "subnetwork" { + description = "The subnetwork created to host the cluster in" + default = "gke-subnet" + type = string +} + +variable "ip_range_pods_name" { + description = "Name of the IP range pods name" + default = "ip_range_pods_name" + type = string +} + +variable "ip_range_services_name" { + description = "Name of the IP services pods name" + default = "ip_range_services_name" + type = string +} \ No newline at end of file diff --git a/gcp/gke/version.tf b/gcp/gke/version.tf new file mode 100644 index 0000000..d216dd5 --- /dev/null +++ b/gcp/gke/version.tf @@ -0,0 +1,13 @@ +terraform { + # required_version = ">= 1.3.1" + required_providers { + google = { + source = "hashicorp/google" + version = "4.54.0" + } + } + backend "gcs" { + bucket = "tf-flash-app-v1" + prefix = "state" + } +} \ No newline at end of file From 3fe6735631a3b590a5061c007b85511b80610123 Mon Sep 17 00:00:00 2001 From: Ramiro Castillo Date: Wed, 1 Mar 2023 01:01:01 -0300 Subject: [PATCH 10/23] Added GKE files for app --- Dockerfile | 23 ----------------------- docker-compose.yaml | 36 ------------------------------------ requirements.txt | 5 ----- 3 files changed, 64 deletions(-) delete mode 100644 Dockerfile delete mode 100644 docker-compose.yaml delete mode 100644 requirements.txt diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index c83ccf5..0000000 --- a/Dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -# Use an official Python runtime as a parent image -FROM python:3.7-alpine - -# Set the working directory to /app -WORKDIR /app - -# Copy the requirements file into the container -COPY requirements.txt . - -# Install any needed packages specified in requirements.txt -RUN pip install -r requirements.txt - -# Copy the rest of the application code into the container -COPY /app . - -# Set the environment variable for Flask -ENV FLASK_APP=main.py - -# Expose port 5000 for the Flask app to listen on -EXPOSE 5000 - -# Run the command to start the Flask app -CMD ["flask", "run", "--host=0.0.0.0"] diff --git a/docker-compose.yaml b/docker-compose.yaml deleted file mode 100644 index 074984f..0000000 --- a/docker-compose.yaml +++ /dev/null @@ -1,36 +0,0 @@ -version: '3' -services: - app: - build: - context: . - dockerfile: Dockerfile - networks: - - backend - ports: - - "5000:5000" - depends_on: - - postgres - - postgres: - image: postgres - networks: - - backend - environment: - POSTGRES_USER: admin - POSTGRES_PASSWORD: admin - POSTGRES_DB: suppliers - POSTGRES_HOST: postgres - POSTGRES_PORT: 5432 - ports: - - "5432:5432" - volumes: - - ./postgresql/init.sql:/docker-entrypoint-initdb.d/init.sql - healthcheck: - test: ["CMD-SHELL", "pg_isready -U admin -d suppliers -h localhost -p 5432"] - interval: 10s - timeout: 5s - retries: 5 - -networks: - backend: - \ No newline at end of file diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index dc4c0b8..0000000 --- a/requirements.txt +++ /dev/null @@ -1,5 +0,0 @@ -psycopg2-binary -flask -flask_sqlalchemy -flask_cors -python-dotenv \ No newline at end of file From 302b9145161254ff1e6c289e9e6c6db8a28eea2d Mon Sep 17 00:00:00 2001 From: Ramiro Castillo Date: Wed, 1 Mar 2023 01:02:13 -0300 Subject: [PATCH 11/23] Added GKE files for app --- app/Dockerfile | 23 +++++++++++++++++++++ app/build_image.sh | 7 +++++++ app/deployment/create_secret.sh | 4 ++++ app/deployment/deployment.yaml | 27 +++++++++++++++++++++++++ app/deployment/hpa.yaml | 21 +++++++++++++++++++ app/deployment/service.yaml | 15 ++++++++++++++ app/docker-compose.yaml | 36 +++++++++++++++++++++++++++++++++ app/requirements.txt | 5 +++++ 8 files changed, 138 insertions(+) create mode 100644 app/Dockerfile create mode 100644 app/build_image.sh create mode 100644 app/deployment/create_secret.sh create mode 100644 app/deployment/deployment.yaml create mode 100644 app/deployment/hpa.yaml create mode 100644 app/deployment/service.yaml create mode 100644 app/docker-compose.yaml create mode 100644 app/requirements.txt diff --git a/app/Dockerfile b/app/Dockerfile new file mode 100644 index 0000000..5a95c1e --- /dev/null +++ b/app/Dockerfile @@ -0,0 +1,23 @@ +# Use an official Python runtime as a parent image +FROM python:3.7-alpine + +# Set the working directory to /app +WORKDIR /app + +# Copy the requirements file into the container +COPY requirements.txt . + +# Install any needed packages specified in requirements.txt +RUN pip install -r requirements.txt + +# Copy the rest of the application code into the container +COPY . . + +# Set the environment variable for Flask +ENV FLASK_APP=main.py + +# Expose port 5000 for the Flask app to listen on +EXPOSE 5000 + +# Run the command to start the Flask app +CMD ["flask", "run", "--host=0.0.0.0"] diff --git a/app/build_image.sh b/app/build_image.sh new file mode 100644 index 0000000..4e938b0 --- /dev/null +++ b/app/build_image.sh @@ -0,0 +1,7 @@ +export FLASK_IMAGE_NAME=flask-api +export GCP_PROJECT_NAME=developing-stuff +export FLASK_IMAGE_TAG=v0.0.1 + +docker build --platform=linux/amd64 -t $FLASK_IMAGE_NAME . +docker tag $FLASK_IMAGE_NAME gcr.io/$GCP_PROJECT_NAME/$FLASK_IMAGE_NAME:$FLASK_IMAGE_TAG +docker push gcr.io/$PROJECT_ID/$FLASK_IMAGE_NAME:$FLASK_IMAGE_TAG \ No newline at end of file diff --git a/app/deployment/create_secret.sh b/app/deployment/create_secret.sh new file mode 100644 index 0000000..cdab57e --- /dev/null +++ b/app/deployment/create_secret.sh @@ -0,0 +1,4 @@ +kubectl create secret docker-registry gcr-json-key \ + --docker-server=gcr.io \ + --docker-username=_json_key \ + --docker-password="$(cat developing-stuff-94480a8432b6.json)" \ No newline at end of file diff --git a/app/deployment/deployment.yaml b/app/deployment/deployment.yaml new file mode 100644 index 0000000..5d66510 --- /dev/null +++ b/app/deployment/deployment.yaml @@ -0,0 +1,27 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: flask-api + namespace: default + labels: + app: flask-api +spec: + replicas: 3 + selector: + matchLabels: + app: flask-api + template: + metadata: + labels: + app: flask-api + spec: + imagePullSecrets: + - name: gcr-json-key + containers: + - name: flask-api + image: gcr.io/developing-stuff/flask-api:v0.0.2 + imagePullPolicy: IfNotPresent + resources: + limits: + cpu: "0.1" + memory: "64Mi" \ No newline at end of file diff --git a/app/deployment/hpa.yaml b/app/deployment/hpa.yaml new file mode 100644 index 0000000..25c8ec8 --- /dev/null +++ b/app/deployment/hpa.yaml @@ -0,0 +1,21 @@ +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: flask-api-hpa + namespace: default + labels: + app: flask-api +spec: + scaleTargetRef: + kind: Deployment + name: flask-api + apiVersion: apps/v1 + minReplicas: 1 + maxReplicas: 5 + metrics: + - type: Resource + resource: + name: cpu + target: + type: AverageValue + averageValue: 40m \ No newline at end of file diff --git a/app/deployment/service.yaml b/app/deployment/service.yaml new file mode 100644 index 0000000..1d32a98 --- /dev/null +++ b/app/deployment/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: flask-api-service + namespace: default + labels: + app: flask-api +spec: + ports: + - protocol: TCP + port: 25443 + selector: + app: flask-api + type: LoadBalancer + loadBalancerIP: "" \ No newline at end of file diff --git a/app/docker-compose.yaml b/app/docker-compose.yaml new file mode 100644 index 0000000..c901a9e --- /dev/null +++ b/app/docker-compose.yaml @@ -0,0 +1,36 @@ +version: '3' +services: + app: + build: + context: . + dockerfile: Dockerfile + # networks: + # - backend + ports: + - "5000:5000" + # depends_on: + # - postgres + +# postgres: +# image: postgres +# networks: +# - backend +# environment: +# POSTGRES_USER: admin +# POSTGRES_PASSWORD: admin +# POSTGRES_DB: suppliers +# POSTGRES_HOST: postgres +# POSTGRES_PORT: 5432 +# ports: +# - "5432:5432" +# volumes: +# - ./postgresql/init.sql:/docker-entrypoint-initdb.d/init.sql +# healthcheck: +# test: ["CMD-SHELL", "pg_isready -U admin -d suppliers -h localhost -p 5432"] +# interval: 10s +# timeout: 5s +# retries: 5 + +# networks: +# backend: + \ No newline at end of file diff --git a/app/requirements.txt b/app/requirements.txt new file mode 100644 index 0000000..dc4c0b8 --- /dev/null +++ b/app/requirements.txt @@ -0,0 +1,5 @@ +psycopg2-binary +flask +flask_sqlalchemy +flask_cors +python-dotenv \ No newline at end of file From 36f27c1a6ad64ad9432db926e93e14128d736b80 Mon Sep 17 00:00:00 2001 From: Ramiro Castillo Date: Sun, 5 Mar 2023 17:45:51 -0300 Subject: [PATCH 12/23] changed postegresql deployment --- postgresql/deployment/dev.tfvars | 2 +- postgresql/deployment/main.tf | 10 +++++----- postgresql/deployment/variables.tf | 2 +- postgresql/modules/main.tf | 32 +++++++++++++++++++----------- 4 files changed, 27 insertions(+), 19 deletions(-) diff --git a/postgresql/deployment/dev.tfvars b/postgresql/deployment/dev.tfvars index 3420d28..798bad7 100644 --- a/postgresql/deployment/dev.tfvars +++ b/postgresql/deployment/dev.tfvars @@ -10,4 +10,4 @@ pgDb = "pgdb" pgPass = "admin" -pgUser = "admin" +pgUser = "admin" \ No newline at end of file diff --git a/postgresql/deployment/main.tf b/postgresql/deployment/main.tf index 79a8471..13f2bf6 100644 --- a/postgresql/deployment/main.tf +++ b/postgresql/deployment/main.tf @@ -1,8 +1,8 @@ # Deploy pgsql cluster on GKE module "postgresql" { - source = "../modules" - env = var.env - pgPass = var.pgPass - pgUser = var.pgUser - pgDb = var.pgDb + source = "../modules" + env = var.env + pgPass = var.pgPass + pgUser = var.pgUser + pgDb = var.pgDb } \ No newline at end of file diff --git a/postgresql/deployment/variables.tf b/postgresql/deployment/variables.tf index 318ffb4..bde600b 100644 --- a/postgresql/deployment/variables.tf +++ b/postgresql/deployment/variables.tf @@ -35,4 +35,4 @@ variable "env" { condition = contains(["prod", "dev"], var.env) error_message = "${var.env} not in accepted values: \"prod\", \"env\"" } -} \ No newline at end of file +} diff --git a/postgresql/modules/main.tf b/postgresql/modules/main.tf index f4dfe87..f1c1631 100644 --- a/postgresql/modules/main.tf +++ b/postgresql/modules/main.tf @@ -1,25 +1,31 @@ -// PGSQL DEV +# PGSQL DEV +# Chart documentation: https://artifacthub.io/packages/helm/bitnami/postgresql resource "helm_release" "postgresql_dev" { count = var.env == "prod" ? 0 : 1 name = "bitnami" repository = "https://charts.bitnami.com/bitnami" chart = "postgresql" + values = [ + "${file("${path.module}/values.yaml")}" + ] + set_sensitive { - name = "global.postgresql.postgresqlPassword" + name = "global.postgresql.auth.postgresPassword" value = var.pgPass } - set_sensitive { - name = "global.postgresql.postgresqlUsername" + name = "global.postgresql.auth.username" value = var.pgUser } - set_sensitive { - name = "global.postgresql.postgresqlDatabase" + name = "global.postgresql.auth.password" + value = var.pgPass + } + set_sensitive { + name = "global.postgresql.auth.database" value = var.pgDb } - } // PGSQL PROD @@ -30,17 +36,19 @@ resource "helm_release" "postgresql_prod" { chart = "postgresql-ha" set_sensitive { - name = "global.postgresql.password" + name = "global.postgresql.auth.postgresPassword" value = var.pgPass } - set_sensitive { - name = "global.postgresql.username" + name = "global.postgresql.auth.username" value = var.pgUser } - set_sensitive { - name = "global.postgresql.database" + name = "global.postgresql.auth.password" + value = var.pgPass + } + set_sensitive { + name = "global.postgresql.auth.database" value = var.pgDb } } \ No newline at end of file From 778406e43624bf81b87b9bedcad7d6f780e43b0c Mon Sep 17 00:00:00 2001 From: Ramiro Castillo Date: Sun, 5 Mar 2023 18:18:21 -0300 Subject: [PATCH 13/23] added http port to service manifest --- app/deployment/deployment.yaml | 2 +- app/deployment/service.yaml | 11 +++++++---- gcp/gke/dev.tfvars | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/app/deployment/deployment.yaml b/app/deployment/deployment.yaml index 5d66510..fbbaa26 100644 --- a/app/deployment/deployment.yaml +++ b/app/deployment/deployment.yaml @@ -20,7 +20,7 @@ spec: containers: - name: flask-api image: gcr.io/developing-stuff/flask-api:v0.0.2 - imagePullPolicy: IfNotPresent + imagePullPolicy: Always resources: limits: cpu: "0.1" diff --git a/app/deployment/service.yaml b/app/deployment/service.yaml index 1d32a98..2edc582 100644 --- a/app/deployment/service.yaml +++ b/app/deployment/service.yaml @@ -6,10 +6,13 @@ metadata: labels: app: flask-api spec: - ports: - - protocol: TCP - port: 25443 selector: app: flask-api type: LoadBalancer - loadBalancerIP: "" \ No newline at end of file + ports: + - name: tcp + protocol: TCP + port: 25443 + - name: http + port: 80 + targetPort: 5000 \ No newline at end of file diff --git a/gcp/gke/dev.tfvars b/gcp/gke/dev.tfvars index d10465e..14b2c70 100644 --- a/gcp/gke/dev.tfvars +++ b/gcp/gke/dev.tfvars @@ -3,7 +3,7 @@ project_id = "developing-stuff" region = "europe-west1" gke_num_nodes = { - max = 2 + max = 10 min = 1 } From 85b04c7c633bdca1f6afe34886c432ecf706165c Mon Sep 17 00:00:00 2001 From: Ramiro Castillo Date: Sun, 5 Mar 2023 19:02:09 -0300 Subject: [PATCH 14/23] added postgres env variables to deployment manifest --- app/deployment/deployment.yaml | 11 +++++++++++ postgresql/deployment/main.tf | 10 +++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/app/deployment/deployment.yaml b/app/deployment/deployment.yaml index fbbaa26..e7d8e4c 100644 --- a/app/deployment/deployment.yaml +++ b/app/deployment/deployment.yaml @@ -21,6 +21,17 @@ spec: - name: flask-api image: gcr.io/developing-stuff/flask-api:v0.0.2 imagePullPolicy: Always + env: + - name: POSTGRES_USER + value: "admin" + - name: POSTGRES_PASSWORD + value: "admin" + - name: POSTGRES_HOST + value: "10.30.244.110" + - name: POSTGRES_DB + value: "databesos" + - name: POSTGRES_PORT + value: "5432" resources: limits: cpu: "0.1" diff --git a/postgresql/deployment/main.tf b/postgresql/deployment/main.tf index 13f2bf6..6afb6fd 100644 --- a/postgresql/deployment/main.tf +++ b/postgresql/deployment/main.tf @@ -1,8 +1,8 @@ # Deploy pgsql cluster on GKE module "postgresql" { - source = "../modules" - env = var.env - pgPass = var.pgPass - pgUser = var.pgUser - pgDb = var.pgDb + source = "../modules" + env = var.env + pgPass = var.pgPass + pgUser = var.pgUser + pgDb = var.pgDb } \ No newline at end of file From 3c4597cd2df5dfd155d4e36dd0b3a76bf541db82 Mon Sep 17 00:00:00 2001 From: Ramiro Castillo Date: Sun, 5 Mar 2023 19:02:52 -0300 Subject: [PATCH 15/23] cleaned docker-compose yaml file --- app/docker-compose.yaml | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/app/docker-compose.yaml b/app/docker-compose.yaml index c901a9e..b5cdf81 100644 --- a/app/docker-compose.yaml +++ b/app/docker-compose.yaml @@ -4,33 +4,6 @@ services: build: context: . dockerfile: Dockerfile - # networks: - # - backend ports: - "5000:5000" - # depends_on: - # - postgres - -# postgres: -# image: postgres -# networks: -# - backend -# environment: -# POSTGRES_USER: admin -# POSTGRES_PASSWORD: admin -# POSTGRES_DB: suppliers -# POSTGRES_HOST: postgres -# POSTGRES_PORT: 5432 -# ports: -# - "5432:5432" -# volumes: -# - ./postgresql/init.sql:/docker-entrypoint-initdb.d/init.sql -# healthcheck: -# test: ["CMD-SHELL", "pg_isready -U admin -d suppliers -h localhost -p 5432"] -# interval: 10s -# timeout: 5s -# retries: 5 - -# networks: -# backend: \ No newline at end of file From ff0470dfafafcffaad496db7f82c1107c7edf64d Mon Sep 17 00:00:00 2001 From: Ramiro Castillo Date: Sun, 5 Mar 2023 20:01:00 -0300 Subject: [PATCH 16/23] Added helm and terraform files --- app/build_image.sh | 7 ---- app/deployment/helm/Chart.yaml | 5 +++ app/deployment/helm/templates/deployment.yaml | 38 +++++++++++++++++ app/deployment/helm/templates/hpa.yaml | 21 ++++++++++ app/deployment/helm/templates/service.yaml | 19 +++++++++ app/deployment/helm/values.yaml | 42 +++++++++++++++++++ app/deployment/helm/values/dev.yaml | 42 +++++++++++++++++++ app/deployment/helm/values/prod.yaml | 42 +++++++++++++++++++ app/deployment/main.tf | 5 +++ app/deployment/providers.tf | 7 ++++ app/deployment/variables.tf | 0 app/deployment/version.tf | 14 +++++++ 12 files changed, 235 insertions(+), 7 deletions(-) delete mode 100644 app/build_image.sh create mode 100644 app/deployment/helm/Chart.yaml create mode 100644 app/deployment/helm/templates/deployment.yaml create mode 100644 app/deployment/helm/templates/hpa.yaml create mode 100644 app/deployment/helm/templates/service.yaml create mode 100644 app/deployment/helm/values.yaml create mode 100644 app/deployment/helm/values/dev.yaml create mode 100644 app/deployment/helm/values/prod.yaml create mode 100644 app/deployment/main.tf create mode 100644 app/deployment/providers.tf create mode 100644 app/deployment/variables.tf create mode 100644 app/deployment/version.tf diff --git a/app/build_image.sh b/app/build_image.sh deleted file mode 100644 index 4e938b0..0000000 --- a/app/build_image.sh +++ /dev/null @@ -1,7 +0,0 @@ -export FLASK_IMAGE_NAME=flask-api -export GCP_PROJECT_NAME=developing-stuff -export FLASK_IMAGE_TAG=v0.0.1 - -docker build --platform=linux/amd64 -t $FLASK_IMAGE_NAME . -docker tag $FLASK_IMAGE_NAME gcr.io/$GCP_PROJECT_NAME/$FLASK_IMAGE_NAME:$FLASK_IMAGE_TAG -docker push gcr.io/$PROJECT_ID/$FLASK_IMAGE_NAME:$FLASK_IMAGE_TAG \ No newline at end of file diff --git a/app/deployment/helm/Chart.yaml b/app/deployment/helm/Chart.yaml new file mode 100644 index 0000000..c0cc75c --- /dev/null +++ b/app/deployment/helm/Chart.yaml @@ -0,0 +1,5 @@ +apiVersion: v2 +name: flask-api-chart +description: A Helm chart for deploying Flash application to GKE +version: 1.0.0 +appVersion: 0.0.1 \ No newline at end of file diff --git a/app/deployment/helm/templates/deployment.yaml b/app/deployment/helm/templates/deployment.yaml new file mode 100644 index 0000000..0b0edaa --- /dev/null +++ b/app/deployment/helm/templates/deployment.yaml @@ -0,0 +1,38 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Values.app.name }} + namespace: {{ .Values.app.namespace }} + labels: + app: {{ .Values.app.name }} +spec: + replicas: {{ .Values.app.replicas }} + selector: + matchLabels: + app: {{ .Values.app.name }} + template: + metadata: + labels: + app: {{ .Values.app.name }} + spec: + imagePullSecrets: + - name: {{ .Values.imagePullSecrets.name }} + containers: + - name: {{ .Values.app.name }} + image: {{ .Values.image.repository }}:{{ .Values.image.tag }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + - name: POSTGRES_USER + value: "{{ .Values.database.user }}" + - name: POSTGRES_PASSWORD + value: "{{ .Values.database.password }}" + - name: POSTGRES_HOST + value: "{{ .Values.database.host }}" + - name: POSTGRES_DB + value: "{{ .Values.database.dbname }}" + - name: POSTGRES_PORT + value: "{{ .Values.database.port }}" + resources: + limits: + cpu: "{{ .Values.app.resources.cpu }}" + memory: "{{ .Values.app.resources.memory }}" diff --git a/app/deployment/helm/templates/hpa.yaml b/app/deployment/helm/templates/hpa.yaml new file mode 100644 index 0000000..f1b2162 --- /dev/null +++ b/app/deployment/helm/templates/hpa.yaml @@ -0,0 +1,21 @@ +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: {{ .Values.hpa.name }} + namespace: {{ .Values.hpa.namespace }} + labels: + app: {{ .Values.app.name }} +spec: + scaleTargetRef: + kind: {{ .Values.hpa.targetKind }} + name: {{ .Values.hpa.targetName }} + apiVersion: {{ .Values.hpa.targetAPIVersion }} + minReplicas: {{ .Values.hpa.minReplicas }} + maxReplicas: {{ .Values.hpa.maxReplicas }} + metrics: + - type: Resource + resource: + name: {{ .Values.hpa.metricName }} + target: + type: {{ .Values.hpa.metricType }} + averageValue: {{ .Values.hpa.metricAverageValue }} diff --git a/app/deployment/helm/templates/service.yaml b/app/deployment/helm/templates/service.yaml new file mode 100644 index 0000000..d491ee8 --- /dev/null +++ b/app/deployment/helm/templates/service.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ .Values.service.name }} + namespace: {{ .Values.service.namespace }} + labels: + app: {{ .Values.app.name }} +spec: + selector: + app: {{ .Values.app.name }} + type: {{ .Values.service.type }} + ports: + - name: tcp + protocol: TCP + port: {{ .Values.service.tcpPort }} + targetPort: {{ .Values.service.targetPort }} + - name: http + port: {{ .Values.service.httpPort }} + targetPort: {{ .Values.service.targetPort }} diff --git a/app/deployment/helm/values.yaml b/app/deployment/helm/values.yaml new file mode 100644 index 0000000..81d072c --- /dev/null +++ b/app/deployment/helm/values.yaml @@ -0,0 +1,42 @@ +app: + name: flask-api + namespace: default + replicas: 3 + resources: + cpu: "0.1" + memory: "64Mi" + +image: + repository: gcr.io/developing-stuff/flask-api + tag: v0.0.2 + pullPolicy: Always + +database: + user: admin + password: admin + host: 10.30.244.110 + port: "5432" + dbname: databesos + +imagePullSecrets: + name: gcr-json-key + +service: + name: flask-api-service + namespace: default + type: LoadBalancer + tcpPort: 25443 + httpPort: 80 + targetPort: 5000 + +hpa: + name: flask-api-hpa + namespace: default + targetKind: Deployment + targetName: flask-api + targetAPIVersion: apps/v1 + minReplicas: 1 + maxReplicas: 5 + metricName: cpu + metricType: AverageValue + metricAverageValue: 40m \ No newline at end of file diff --git a/app/deployment/helm/values/dev.yaml b/app/deployment/helm/values/dev.yaml new file mode 100644 index 0000000..81d072c --- /dev/null +++ b/app/deployment/helm/values/dev.yaml @@ -0,0 +1,42 @@ +app: + name: flask-api + namespace: default + replicas: 3 + resources: + cpu: "0.1" + memory: "64Mi" + +image: + repository: gcr.io/developing-stuff/flask-api + tag: v0.0.2 + pullPolicy: Always + +database: + user: admin + password: admin + host: 10.30.244.110 + port: "5432" + dbname: databesos + +imagePullSecrets: + name: gcr-json-key + +service: + name: flask-api-service + namespace: default + type: LoadBalancer + tcpPort: 25443 + httpPort: 80 + targetPort: 5000 + +hpa: + name: flask-api-hpa + namespace: default + targetKind: Deployment + targetName: flask-api + targetAPIVersion: apps/v1 + minReplicas: 1 + maxReplicas: 5 + metricName: cpu + metricType: AverageValue + metricAverageValue: 40m \ No newline at end of file diff --git a/app/deployment/helm/values/prod.yaml b/app/deployment/helm/values/prod.yaml new file mode 100644 index 0000000..81d072c --- /dev/null +++ b/app/deployment/helm/values/prod.yaml @@ -0,0 +1,42 @@ +app: + name: flask-api + namespace: default + replicas: 3 + resources: + cpu: "0.1" + memory: "64Mi" + +image: + repository: gcr.io/developing-stuff/flask-api + tag: v0.0.2 + pullPolicy: Always + +database: + user: admin + password: admin + host: 10.30.244.110 + port: "5432" + dbname: databesos + +imagePullSecrets: + name: gcr-json-key + +service: + name: flask-api-service + namespace: default + type: LoadBalancer + tcpPort: 25443 + httpPort: 80 + targetPort: 5000 + +hpa: + name: flask-api-hpa + namespace: default + targetKind: Deployment + targetName: flask-api + targetAPIVersion: apps/v1 + minReplicas: 1 + maxReplicas: 5 + metricName: cpu + metricType: AverageValue + metricAverageValue: 40m \ No newline at end of file diff --git a/app/deployment/main.tf b/app/deployment/main.tf new file mode 100644 index 0000000..c96a2ec --- /dev/null +++ b/app/deployment/main.tf @@ -0,0 +1,5 @@ +resource "helm_release" "flask-api" { + name = "flask-api-helm" + repository = "file://./helm" + chart = "./helm" +} \ No newline at end of file diff --git a/app/deployment/providers.tf b/app/deployment/providers.tf new file mode 100644 index 0000000..c5290f4 --- /dev/null +++ b/app/deployment/providers.tf @@ -0,0 +1,7 @@ +# https://registry.terraform.io/providers/hashicorp/helm/latest/docs +provider "helm" { + kubernetes { + config_path = var.kubeconfig_path + } + alias = "gke" +} \ No newline at end of file diff --git a/app/deployment/variables.tf b/app/deployment/variables.tf new file mode 100644 index 0000000..e69de29 diff --git a/app/deployment/version.tf b/app/deployment/version.tf new file mode 100644 index 0000000..cf6d61c --- /dev/null +++ b/app/deployment/version.tf @@ -0,0 +1,14 @@ +# https://www.terraform.io/docs/language/settings/index.html +terraform { + required_version = ">= 1.0.0" + required_providers { + helm = { + source = "hashicorp/helm" + version = "~> 2.3.0" + } + } + backend "gcs" { + bucket = "tf-flash-app-v1" + prefix = "app_state" + } +} \ No newline at end of file From b5df1b5df74e8ffdc0e2577ed50f949b739dd226 Mon Sep 17 00:00:00 2001 From: Ramiro Castillo Date: Mon, 6 Mar 2023 19:01:56 -0300 Subject: [PATCH 17/23] Changed cluster name --- app/deployment/deployment.yaml | 38 ------------------------------- app/deployment/hpa.yaml | 21 ----------------- app/deployment/service.yaml | 18 --------------- app/deployment/version.tf | 2 +- gcp/gke/version.tf | 2 +- postgresql/deployment/dev.tfvars | 2 +- postgresql/deployment/prod.tfvars | 2 +- postgresql/deployment/version.tf | 2 +- 8 files changed, 5 insertions(+), 82 deletions(-) delete mode 100644 app/deployment/deployment.yaml delete mode 100644 app/deployment/hpa.yaml delete mode 100644 app/deployment/service.yaml diff --git a/app/deployment/deployment.yaml b/app/deployment/deployment.yaml deleted file mode 100644 index e7d8e4c..0000000 --- a/app/deployment/deployment.yaml +++ /dev/null @@ -1,38 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: flask-api - namespace: default - labels: - app: flask-api -spec: - replicas: 3 - selector: - matchLabels: - app: flask-api - template: - metadata: - labels: - app: flask-api - spec: - imagePullSecrets: - - name: gcr-json-key - containers: - - name: flask-api - image: gcr.io/developing-stuff/flask-api:v0.0.2 - imagePullPolicy: Always - env: - - name: POSTGRES_USER - value: "admin" - - name: POSTGRES_PASSWORD - value: "admin" - - name: POSTGRES_HOST - value: "10.30.244.110" - - name: POSTGRES_DB - value: "databesos" - - name: POSTGRES_PORT - value: "5432" - resources: - limits: - cpu: "0.1" - memory: "64Mi" \ No newline at end of file diff --git a/app/deployment/hpa.yaml b/app/deployment/hpa.yaml deleted file mode 100644 index 25c8ec8..0000000 --- a/app/deployment/hpa.yaml +++ /dev/null @@ -1,21 +0,0 @@ -apiVersion: autoscaling/v2 -kind: HorizontalPodAutoscaler -metadata: - name: flask-api-hpa - namespace: default - labels: - app: flask-api -spec: - scaleTargetRef: - kind: Deployment - name: flask-api - apiVersion: apps/v1 - minReplicas: 1 - maxReplicas: 5 - metrics: - - type: Resource - resource: - name: cpu - target: - type: AverageValue - averageValue: 40m \ No newline at end of file diff --git a/app/deployment/service.yaml b/app/deployment/service.yaml deleted file mode 100644 index 2edc582..0000000 --- a/app/deployment/service.yaml +++ /dev/null @@ -1,18 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: flask-api-service - namespace: default - labels: - app: flask-api -spec: - selector: - app: flask-api - type: LoadBalancer - ports: - - name: tcp - protocol: TCP - port: 25443 - - name: http - port: 80 - targetPort: 5000 \ No newline at end of file diff --git a/app/deployment/version.tf b/app/deployment/version.tf index cf6d61c..6f615a4 100644 --- a/app/deployment/version.tf +++ b/app/deployment/version.tf @@ -8,7 +8,7 @@ terraform { } } backend "gcs" { - bucket = "tf-flash-app-v1" + bucket = "tf-flask-app-v1" prefix = "app_state" } } \ No newline at end of file diff --git a/gcp/gke/version.tf b/gcp/gke/version.tf index d216dd5..958f863 100644 --- a/gcp/gke/version.tf +++ b/gcp/gke/version.tf @@ -7,7 +7,7 @@ terraform { } } backend "gcs" { - bucket = "tf-flash-app-v1" + bucket = "tf-flask-app-v1" prefix = "state" } } \ No newline at end of file diff --git a/postgresql/deployment/dev.tfvars b/postgresql/deployment/dev.tfvars index 798bad7..a4aa92a 100644 --- a/postgresql/deployment/dev.tfvars +++ b/postgresql/deployment/dev.tfvars @@ -1,6 +1,6 @@ env = "dev" -cluster_name = "flash-app-v1-dev" +cluster_name = "flask-app-v1-dev" location = "europe-west1" diff --git a/postgresql/deployment/prod.tfvars b/postgresql/deployment/prod.tfvars index 68216df..3bf759c 100644 --- a/postgresql/deployment/prod.tfvars +++ b/postgresql/deployment/prod.tfvars @@ -1,5 +1,5 @@ env = "prod" -cluster_name = "flash-app-v1-prod" +cluster_name = "flask-app-v1-prod" location = "europe-west1" \ No newline at end of file diff --git a/postgresql/deployment/version.tf b/postgresql/deployment/version.tf index c0a937b..369a6d9 100644 --- a/postgresql/deployment/version.tf +++ b/postgresql/deployment/version.tf @@ -8,7 +8,7 @@ terraform { } } backend "gcs" { - bucket = "tf-flash-app-v1" + bucket = "tf-flask-app-v1" prefix = "postgresql_state" } } \ No newline at end of file From a23d14b65547ed0aef12d8f503ea9ef60a6f8b2e Mon Sep 17 00:00:00 2001 From: Ramiro Castillo Date: Mon, 6 Mar 2023 19:33:41 -0300 Subject: [PATCH 18/23] Reworked app directory organization --- app/deployment/main.tf | 15 +++++++++---- app/deployment/variables.tf | 29 ++++++++++++++++++++++++++ app/modules/flask-app/main.tf | 5 +++++ app/modules/flask-app/variables.tf | 9 ++++++++ app/modules/gke-secret/key.json | 12 +++++++++++ app/modules/gke-secret/main.tf | 17 +++++++++++++++ app/modules/gke-secret/variables.tf | 19 +++++++++++++++++ app/{ => src}/Dockerfile | 0 app/{ => src}/api/user.py | 0 app/{ => src}/config.py | 0 app/{ => src}/docker-compose.yaml | 0 app/{ => src}/main.py | 0 app/{ => src}/models/user.py | 0 app/{ => src}/requirements.txt | 0 app/{ => src}/services/user_service.py | 0 app/{ => src}/utils/DbConnection.py | 0 app/{ => src}/utils/VerifyDate.py | 0 gcp/gke/dev.tfvars | 2 +- 18 files changed, 103 insertions(+), 5 deletions(-) create mode 100644 app/modules/flask-app/main.tf create mode 100644 app/modules/flask-app/variables.tf create mode 100644 app/modules/gke-secret/key.json create mode 100644 app/modules/gke-secret/main.tf create mode 100644 app/modules/gke-secret/variables.tf rename app/{ => src}/Dockerfile (100%) rename app/{ => src}/api/user.py (100%) rename app/{ => src}/config.py (100%) rename app/{ => src}/docker-compose.yaml (100%) rename app/{ => src}/main.py (100%) rename app/{ => src}/models/user.py (100%) rename app/{ => src}/requirements.txt (100%) rename app/{ => src}/services/user_service.py (100%) rename app/{ => src}/utils/DbConnection.py (100%) rename app/{ => src}/utils/VerifyDate.py (100%) diff --git a/app/deployment/main.tf b/app/deployment/main.tf index c96a2ec..dd22f5b 100644 --- a/app/deployment/main.tf +++ b/app/deployment/main.tf @@ -1,5 +1,12 @@ -resource "helm_release" "flask-api" { - name = "flask-api-helm" - repository = "file://./helm" - chart = "./helm" +module "flask-app" { + source = "../modules/flask-app" + env = var.env +} + +module "gke_secret" { + source = "../modules/gke-secret" + k8s_secret_name = var.k8s_secret_name + k8s_secret_password = var.k8s_secret_password + k8s_secret_server = var.k8s_secret_server + k8s_secret_username = var.k8s_secret_username } \ No newline at end of file diff --git a/app/deployment/variables.tf b/app/deployment/variables.tf index e69de29..597f0a3 100644 --- a/app/deployment/variables.tf +++ b/app/deployment/variables.tf @@ -0,0 +1,29 @@ +variable "env" { + description = "Environment variable" + type = string + + validation { + condition = contains(["prod", "dev"], var.env) + error_message = "Error! \"${var.env}\" not in acceptable values: \"prod\", \"env\"" + } +} + +variable "k8s_secret_name" { + type = string + description = "Kubernetes secret name" +} + +variable "k8s_secret_server" { + type = string + description = "Kubernetes server name" +} + +variable "k8s_secret_username" { + type = string + description = "Kubernetes username" +} + +variable "k8s_secret_password" { + type = string + description = "Kubernetes password" +} \ No newline at end of file diff --git a/app/modules/flask-app/main.tf b/app/modules/flask-app/main.tf new file mode 100644 index 0000000..0208c0c --- /dev/null +++ b/app/modules/flask-app/main.tf @@ -0,0 +1,5 @@ +resource "helm_release" "flask-api" { + name = "flask-api-helm_${var.env}" + repository = "file://./helm" + chart = "./helm" +} \ No newline at end of file diff --git a/app/modules/flask-app/variables.tf b/app/modules/flask-app/variables.tf new file mode 100644 index 0000000..6d02ae6 --- /dev/null +++ b/app/modules/flask-app/variables.tf @@ -0,0 +1,9 @@ +variable "env" { + description = "Environment variable" + type = string + + validation { + condition = contains(["prod", "dev"], var.env) + error_message = "Error! \"${var.env}\" not in acceptable values: \"prod\", \"env\"" + } +} \ No newline at end of file diff --git a/app/modules/gke-secret/key.json b/app/modules/gke-secret/key.json new file mode 100644 index 0000000..40eb101 --- /dev/null +++ b/app/modules/gke-secret/key.json @@ -0,0 +1,12 @@ +{ + "type": "service_account", + "project_id": "developing-stuff", + "private_key_id": "94480a8432b6a1a5c82e269001ef84b51d6ea20d", + "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDiyIKFxIus+z0j\nSOjWFPTJoqV+ug+63TYJPreKNnP6O9rdk0MROcTnB2mb3Hsk6kcegzxDiZMbYqLf\nWT3zWjRHOzc2wukmeGGzLq1Y/da3S1DQo/oNhyF/HNRwPw1XLV3hkPrVko/E61We\nxxguIgDGry5LUWJjDiJygdOkc/vemm0ZhOQgqFXgesfG5E42mbcoMGEGYmw5L6Ox\nlA+IxKGrYD09q0YTVxQ/02GT3LfIly//DYvuaa5Q4rEDWKjMWEYtKLo15r8QQ946\nlc8LcWktkebHdaxmCqZG2OIlXcK8gt0UoQUuyzYcHDEYPT89g6z+JAd3ssFod+b5\nd6OfgndtAgMBAAECggEABm9RM6Yx59TEAzGUj3Hyx5sIR2av2repAZHdAMpAwQ8T\nJy6k8z5RrK9dlnxwE8o3Iq04nGOxFr5D42dcs+3/KptlrPWuAVdMP4hS0EswJlsB\nKZpkX40JCGy8R4zJUIwUR7nLQffWODXDiJsbCPeAB5Dq8Fxzz4LdTe4vH+PiCh0H\nXKpP/1hAyZ1KVQYCpLablJbJbE0Z/iKTIVDGZscQZ32FV3NXiW3yD6YUfl+L1h8W\ngrBQIxQjo0lKH2M5dAuiq4dEDX+AbCB5Xr/f1M1US4UXmfawHeq0eWzxHSkH9qpi\nUGl4ATYTbp73h8BMegNoupzHDXqpgbxtZpGrH7z3QQKBgQD/gwHmv2JxzYufrdkF\nBeTirh0QQo68JfnleJUGXQ5DZQYK6EZDJNY40D6JNLLUm5EK9hWAOR/oFVbdZFWj\nuY/FMKvhLdJSooDfDKgglSFUWIzSAER90lIrLLB9vqd2zKtiadugckAyt1IMT0QI\nJgwJ7TbxO8CyaWOFz+GopbZzXQKBgQDjN3Lo2xzE/9PEt/tNsU+a3bH21lHoJrhA\n3P1D9O+SsElxtAjQ83OxEiVL3sZOZ4/ro6vDazmgtYxNJWei5mItrPwHwKcvxOYh\nruNQ38M8TdZgQDM8YN4gvGOh4nQ4Ma1MEM/CacZgdVpbjlTjn39Ijrj6J34CClF8\nBwq0WydjUQKBgQDc4BYrr3PdZs71CSaadf7niZXsMW0L7lQ47uT8bELhNZpkoWfj\nsRtSX4o/t4OD0LswW4w4nKkdSh0eIxb5AnbrAmkCrkarUnjO2DUafXAjZqzM+Jg8\noCyRz/79pGtFgiYBW/sUls8ySFCv/XGVDbbIefxNytaIJBx5Vzv+OsoerQKBgQDJ\nFRZVqywfz8QLMUNus3+er5pCt9NO341qoehljsvChs7ImKrAuONnDocBSQs48f/1\nayikTi1245Rh5bt89+RlRdTZy45qARglMRAtT4oJwVz6W3a8dYG/eNm3t6Bg5t3W\nFn63MEMGtHSd2C2aMFpFzUE46WBjz9vjJpw7lvwZsQKBgF7O+c2FY7J8fuMLGZiJ\ny1rGiLKxKZ4+ShKs3RHVD28Yfkj44IzOyx9DbtU2rVEYh4R6rNETSS1sLoBHPrO2\nTk63HYTbdsY2i5W+Mcfo0S6+sKByzdwwDnOQnOThwZ9S1FTkPfTkeI3DpmY+8ba2\nJcZlySePxDklXWvAUyI2vzVr\n-----END PRIVATE KEY-----\n", + "client_email": "k8s-gcr-image-pull@developing-stuff.iam.gserviceaccount.com", + "client_id": "102585089829369003491", + "auth_uri": "https://accounts.google.com/o/oauth2/auth", + "token_uri": "https://oauth2.googleapis.com/token", + "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", + "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/k8s-gcr-image-pull%40developing-stuff.iam.gserviceaccount.com" +} diff --git a/app/modules/gke-secret/main.tf b/app/modules/gke-secret/main.tf new file mode 100644 index 0000000..69451b4 --- /dev/null +++ b/app/modules/gke-secret/main.tf @@ -0,0 +1,17 @@ +resource "kubernetes_secret" "gcr-json-key" { + metadata { + name = var.k8s_secret_name + } + + data = { + ".dockerconfigjson" = jsonencode({ + auths = { + "${var.k8s_secret_server}" = { + auth = base64encode("${var.k8s_secret_username}:${file("${path.module}/${var.k8s_secret_password}")}") + } + } + }) + } + + type = "kubernetes.io/dockerconfigjson" +} \ No newline at end of file diff --git a/app/modules/gke-secret/variables.tf b/app/modules/gke-secret/variables.tf new file mode 100644 index 0000000..d95e941 --- /dev/null +++ b/app/modules/gke-secret/variables.tf @@ -0,0 +1,19 @@ +variable "k8s_secret_name" { + type = string + description = "Kubernetes secret name" +} + +variable "k8s_secret_server" { + type = string + description = "Kubernetes server name" +} + +variable "k8s_secret_username" { + type = string + description = "Kubernetes username" +} + +variable "k8s_secret_password" { + type = string + description = "Kubernetes password" +} \ No newline at end of file diff --git a/app/Dockerfile b/app/src/Dockerfile similarity index 100% rename from app/Dockerfile rename to app/src/Dockerfile diff --git a/app/api/user.py b/app/src/api/user.py similarity index 100% rename from app/api/user.py rename to app/src/api/user.py diff --git a/app/config.py b/app/src/config.py similarity index 100% rename from app/config.py rename to app/src/config.py diff --git a/app/docker-compose.yaml b/app/src/docker-compose.yaml similarity index 100% rename from app/docker-compose.yaml rename to app/src/docker-compose.yaml diff --git a/app/main.py b/app/src/main.py similarity index 100% rename from app/main.py rename to app/src/main.py diff --git a/app/models/user.py b/app/src/models/user.py similarity index 100% rename from app/models/user.py rename to app/src/models/user.py diff --git a/app/requirements.txt b/app/src/requirements.txt similarity index 100% rename from app/requirements.txt rename to app/src/requirements.txt diff --git a/app/services/user_service.py b/app/src/services/user_service.py similarity index 100% rename from app/services/user_service.py rename to app/src/services/user_service.py diff --git a/app/utils/DbConnection.py b/app/src/utils/DbConnection.py similarity index 100% rename from app/utils/DbConnection.py rename to app/src/utils/DbConnection.py diff --git a/app/utils/VerifyDate.py b/app/src/utils/VerifyDate.py similarity index 100% rename from app/utils/VerifyDate.py rename to app/src/utils/VerifyDate.py diff --git a/gcp/gke/dev.tfvars b/gcp/gke/dev.tfvars index 14b2c70..204851a 100644 --- a/gcp/gke/dev.tfvars +++ b/gcp/gke/dev.tfvars @@ -25,7 +25,7 @@ gke_disabled_hpa = true env_name = "dev" -cluster_name = "flash-app-v1" +cluster_name = "flask-app-v1" ip_range_pods_name = "ip-range-pods-name" From 488791bb20fc62a68a308cb1cd2c9b0619e41448 Mon Sep 17 00:00:00 2001 From: Ramiro Castillo Date: Mon, 6 Mar 2023 19:37:41 -0300 Subject: [PATCH 19/23] Added dev and prod values for app deployment --- app/deployment/create_secret.sh | 4 ---- app/deployment/dev.tfvars | 5 +++++ app/deployment/prod.tfvars | 5 +++++ 3 files changed, 10 insertions(+), 4 deletions(-) delete mode 100644 app/deployment/create_secret.sh create mode 100644 app/deployment/dev.tfvars create mode 100644 app/deployment/prod.tfvars diff --git a/app/deployment/create_secret.sh b/app/deployment/create_secret.sh deleted file mode 100644 index cdab57e..0000000 --- a/app/deployment/create_secret.sh +++ /dev/null @@ -1,4 +0,0 @@ -kubectl create secret docker-registry gcr-json-key \ - --docker-server=gcr.io \ - --docker-username=_json_key \ - --docker-password="$(cat developing-stuff-94480a8432b6.json)" \ No newline at end of file diff --git a/app/deployment/dev.tfvars b/app/deployment/dev.tfvars new file mode 100644 index 0000000..a4b79b1 --- /dev/null +++ b/app/deployment/dev.tfvars @@ -0,0 +1,5 @@ +env = "dev" +k8s_secret_name = "gcr-json-key" +k8s_secret_password = "key.json" +k8s_secret_server = "gcr.io" +k8s_secret_username = "_json_key" \ No newline at end of file diff --git a/app/deployment/prod.tfvars b/app/deployment/prod.tfvars new file mode 100644 index 0000000..1a4d771 --- /dev/null +++ b/app/deployment/prod.tfvars @@ -0,0 +1,5 @@ +env = "prod" +k8s_secret_name = "gcr-json-key" +k8s_secret_password = "key.json" +k8s_secret_server = "gcr.io" +k8s_secret_username = "_json_key" \ No newline at end of file From 7f27dd5b7aab11d94892014dc62f6b5952d7d261 Mon Sep 17 00:00:00 2001 From: Ramiro Castillo Date: Mon, 6 Mar 2023 20:31:54 -0300 Subject: [PATCH 20/23] changed database ip on chart values --- app/deployment/helm/values/dev.yaml | 2 +- app/deployment/helm/values/prod.yaml | 2 +- app/modules/flask-app/main.tf | 6 +++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/app/deployment/helm/values/dev.yaml b/app/deployment/helm/values/dev.yaml index 81d072c..4d0e65e 100644 --- a/app/deployment/helm/values/dev.yaml +++ b/app/deployment/helm/values/dev.yaml @@ -14,7 +14,7 @@ image: database: user: admin password: admin - host: 10.30.244.110 + host: bitnami-postgresql.default.svc.cluster.local port: "5432" dbname: databesos diff --git a/app/deployment/helm/values/prod.yaml b/app/deployment/helm/values/prod.yaml index 81d072c..4d0e65e 100644 --- a/app/deployment/helm/values/prod.yaml +++ b/app/deployment/helm/values/prod.yaml @@ -14,7 +14,7 @@ image: database: user: admin password: admin - host: 10.30.244.110 + host: bitnami-postgresql.default.svc.cluster.local port: "5432" dbname: databesos diff --git a/app/modules/flask-app/main.tf b/app/modules/flask-app/main.tf index 0208c0c..d1a27cc 100644 --- a/app/modules/flask-app/main.tf +++ b/app/modules/flask-app/main.tf @@ -1,5 +1,9 @@ resource "helm_release" "flask-api" { - name = "flask-api-helm_${var.env}" + name = "flask-api-helm" repository = "file://./helm" chart = "./helm" + + values = [ + "${file("./helm/values/${var.env}.yaml")}" + ] } \ No newline at end of file From 624545fb3442b4ef96569362b37382b001179e31 Mon Sep 17 00:00:00 2001 From: Ramiro Castillo Date: Mon, 6 Mar 2023 20:39:36 -0300 Subject: [PATCH 21/23] deleted key.json --- app/modules/gke-secret/key.json | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 app/modules/gke-secret/key.json diff --git a/app/modules/gke-secret/key.json b/app/modules/gke-secret/key.json deleted file mode 100644 index 40eb101..0000000 --- a/app/modules/gke-secret/key.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "type": "service_account", - "project_id": "developing-stuff", - "private_key_id": "94480a8432b6a1a5c82e269001ef84b51d6ea20d", - "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDiyIKFxIus+z0j\nSOjWFPTJoqV+ug+63TYJPreKNnP6O9rdk0MROcTnB2mb3Hsk6kcegzxDiZMbYqLf\nWT3zWjRHOzc2wukmeGGzLq1Y/da3S1DQo/oNhyF/HNRwPw1XLV3hkPrVko/E61We\nxxguIgDGry5LUWJjDiJygdOkc/vemm0ZhOQgqFXgesfG5E42mbcoMGEGYmw5L6Ox\nlA+IxKGrYD09q0YTVxQ/02GT3LfIly//DYvuaa5Q4rEDWKjMWEYtKLo15r8QQ946\nlc8LcWktkebHdaxmCqZG2OIlXcK8gt0UoQUuyzYcHDEYPT89g6z+JAd3ssFod+b5\nd6OfgndtAgMBAAECggEABm9RM6Yx59TEAzGUj3Hyx5sIR2av2repAZHdAMpAwQ8T\nJy6k8z5RrK9dlnxwE8o3Iq04nGOxFr5D42dcs+3/KptlrPWuAVdMP4hS0EswJlsB\nKZpkX40JCGy8R4zJUIwUR7nLQffWODXDiJsbCPeAB5Dq8Fxzz4LdTe4vH+PiCh0H\nXKpP/1hAyZ1KVQYCpLablJbJbE0Z/iKTIVDGZscQZ32FV3NXiW3yD6YUfl+L1h8W\ngrBQIxQjo0lKH2M5dAuiq4dEDX+AbCB5Xr/f1M1US4UXmfawHeq0eWzxHSkH9qpi\nUGl4ATYTbp73h8BMegNoupzHDXqpgbxtZpGrH7z3QQKBgQD/gwHmv2JxzYufrdkF\nBeTirh0QQo68JfnleJUGXQ5DZQYK6EZDJNY40D6JNLLUm5EK9hWAOR/oFVbdZFWj\nuY/FMKvhLdJSooDfDKgglSFUWIzSAER90lIrLLB9vqd2zKtiadugckAyt1IMT0QI\nJgwJ7TbxO8CyaWOFz+GopbZzXQKBgQDjN3Lo2xzE/9PEt/tNsU+a3bH21lHoJrhA\n3P1D9O+SsElxtAjQ83OxEiVL3sZOZ4/ro6vDazmgtYxNJWei5mItrPwHwKcvxOYh\nruNQ38M8TdZgQDM8YN4gvGOh4nQ4Ma1MEM/CacZgdVpbjlTjn39Ijrj6J34CClF8\nBwq0WydjUQKBgQDc4BYrr3PdZs71CSaadf7niZXsMW0L7lQ47uT8bELhNZpkoWfj\nsRtSX4o/t4OD0LswW4w4nKkdSh0eIxb5AnbrAmkCrkarUnjO2DUafXAjZqzM+Jg8\noCyRz/79pGtFgiYBW/sUls8ySFCv/XGVDbbIefxNytaIJBx5Vzv+OsoerQKBgQDJ\nFRZVqywfz8QLMUNus3+er5pCt9NO341qoehljsvChs7ImKrAuONnDocBSQs48f/1\nayikTi1245Rh5bt89+RlRdTZy45qARglMRAtT4oJwVz6W3a8dYG/eNm3t6Bg5t3W\nFn63MEMGtHSd2C2aMFpFzUE46WBjz9vjJpw7lvwZsQKBgF7O+c2FY7J8fuMLGZiJ\ny1rGiLKxKZ4+ShKs3RHVD28Yfkj44IzOyx9DbtU2rVEYh4R6rNETSS1sLoBHPrO2\nTk63HYTbdsY2i5W+Mcfo0S6+sKByzdwwDnOQnOThwZ9S1FTkPfTkeI3DpmY+8ba2\nJcZlySePxDklXWvAUyI2vzVr\n-----END PRIVATE KEY-----\n", - "client_email": "k8s-gcr-image-pull@developing-stuff.iam.gserviceaccount.com", - "client_id": "102585089829369003491", - "auth_uri": "https://accounts.google.com/o/oauth2/auth", - "token_uri": "https://oauth2.googleapis.com/token", - "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", - "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/k8s-gcr-image-pull%40developing-stuff.iam.gserviceaccount.com" -} From 70a11c00bbb033f789577defd6d10ef851d94e14 Mon Sep 17 00:00:00 2001 From: Ramiro Castillo Date: Tue, 7 Mar 2023 17:48:25 -0300 Subject: [PATCH 22/23] fmt prod.tfvars for app deployment --- app/deployment/prod.tfvars | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/deployment/prod.tfvars b/app/deployment/prod.tfvars index 1a4d771..55ed77f 100644 --- a/app/deployment/prod.tfvars +++ b/app/deployment/prod.tfvars @@ -1,5 +1,5 @@ -env = "prod" -k8s_secret_name = "gcr-json-key" +env = "prod" +k8s_secret_name = "gcr-json-key" k8s_secret_password = "key.json" -k8s_secret_server = "gcr.io" +k8s_secret_server = "gcr.io" k8s_secret_username = "_json_key" \ No newline at end of file From e5153279e9f8fe670498bb959fa4f868bc93e53f Mon Sep 17 00:00:00 2001 From: Ramiro Castillo Date: Tue, 7 Mar 2023 17:52:25 -0300 Subject: [PATCH 23/23] Added atlantis files for namespace --- atlantis/dev.tfvars | 5 +++++ atlantis/main.tf | 22 ++++++++++++++++++++++ atlantis/providers.tf | 3 +++ atlantis/variables.tf | 30 ++++++++++++++++++++++++++++++ atlantis/version.tf | 14 ++++++++++++++ gcp/gke/prod.tfvars | 32 ++++++++++++++++++++++++++++++++ gcp/gke/variables.tf | 5 +++++ 7 files changed, 111 insertions(+) create mode 100644 atlantis/dev.tfvars create mode 100644 atlantis/main.tf create mode 100644 atlantis/providers.tf create mode 100644 atlantis/variables.tf create mode 100644 atlantis/version.tf diff --git a/atlantis/dev.tfvars b/atlantis/dev.tfvars new file mode 100644 index 0000000..f6ab921 --- /dev/null +++ b/atlantis/dev.tfvars @@ -0,0 +1,5 @@ +namespace_name = "atlantis" +env = "dev" +cluster_name = "flask-app-v1-dev" +project_id = "developing-stuff" +region = "europe-west1" \ No newline at end of file diff --git a/atlantis/main.tf b/atlantis/main.tf new file mode 100644 index 0000000..9876b0e --- /dev/null +++ b/atlantis/main.tf @@ -0,0 +1,22 @@ +locals { + namespace_name = "${var.namespace_name}-${var.env}" +} + +resource "kubernetes_namespace" "example" { + metadata { + name = local.namespace_name + annotations = { + name = local.namespace_name + } + } +} + +# resource "helm_release" "atlantis" { +# name = "atlantis-${var.env}" +# repository = "file://./helm" +# chart = "./helm" +# namespace = "atlantis-${var.env}" +# values = [ +# "${file("./helm/values/${var.env}.yaml")}" +# ] +# } \ No newline at end of file diff --git a/atlantis/providers.tf b/atlantis/providers.tf new file mode 100644 index 0000000..9c75a53 --- /dev/null +++ b/atlantis/providers.tf @@ -0,0 +1,3 @@ +provider "kubernetes" { + config_path = "~/.kube/config" +} \ No newline at end of file diff --git a/atlantis/variables.tf b/atlantis/variables.tf new file mode 100644 index 0000000..8687504 --- /dev/null +++ b/atlantis/variables.tf @@ -0,0 +1,30 @@ +variable "project_id" { + type = string + description = "Project ID" +} + +variable "region" { + type = string + description = "Region name" +} + +variable "cluster_name" { + type = string + description = "Cluster name" +} + +variable "namespace_name" { + type = string + description = "Namespace name to be created" +} + +variable "env" { + type = string + description = "Environment: \"prod\" or \"dev\"" + + validation { + condition = contains(["prod", "dev"], var.env) + error_message = "Error! \"${var.env}\" not in possible values: \"prod\" or \"dev\"" + } +} + diff --git a/atlantis/version.tf b/atlantis/version.tf new file mode 100644 index 0000000..01f4cf0 --- /dev/null +++ b/atlantis/version.tf @@ -0,0 +1,14 @@ +# https://www.terraform.io/docs/language/settings/index.html +terraform { + required_version = ">= 1.0.0" + required_providers { + helm = { + source = "hashicorp/helm" + version = "~> 2.3.0" + } + } + backend "gcs" { + bucket = "tf-flask-app-v1" + prefix = "atlantis_state" + } +} \ No newline at end of file diff --git a/gcp/gke/prod.tfvars b/gcp/gke/prod.tfvars index e69de29..b8682c1 100644 --- a/gcp/gke/prod.tfvars +++ b/gcp/gke/prod.tfvars @@ -0,0 +1,32 @@ +project_id = "developing-stuff" + +region = "europe-west1" + +gke_num_nodes = { + max = 10 + min = 1 +} + +gke_preemptible = true + +gke_machine_type = "n1-standard-1" + +gke_subnet_ip_cidr_range = "10.51.0.0/20" + +gke_cluster_autoscaling = { + enabled = true + cpu_minimum = 1 + cpu_maximum = 4 + memory_minimum = 4 + memory_maximum = 16 +} + +gke_disabled_hpa = false + +env_name = "prod" + +cluster_name = "flask-app-v1" + +ip_range_pods_name = "ip-range-pods-name" + +ip_range_services_name = "ip-range-services-name" \ No newline at end of file diff --git a/gcp/gke/variables.tf b/gcp/gke/variables.tf index 872f9be..2b75464 100644 --- a/gcp/gke/variables.tf +++ b/gcp/gke/variables.tf @@ -102,4 +102,9 @@ variable "ip_range_services_name" { description = "Name of the IP services pods name" default = "ip_range_services_name" type = string +} + +variable "namespaces" { + type = map(object) + description = "List of namespaces" } \ No newline at end of file