Compare commits
14
Commits
dev
...
feat/deploy
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6301ffedd7 | ||
|
|
da5d2d838a | ||
|
|
8386e05f31 | ||
|
|
2a7e1c25fc | ||
|
|
5d955ca991 | ||
|
|
cefb07067d | ||
|
|
3cc6c67e0d | ||
|
|
93afc6031c | ||
|
|
99db807e3c | ||
|
|
47c4fd445b | ||
|
|
667592033b | ||
|
|
6785c70f6f | ||
|
|
692ec436a5 | ||
|
|
a3d32a6fb1 |
@@ -1,3 +1,8 @@
|
|||||||
|
# syntax=docker/dockerfile:1
|
||||||
|
FROM docker
|
||||||
|
COPY --from=docker/buildx-bin /buildx /usr/libexec/docker/cli-plugins/docker-buildx
|
||||||
|
RUN docker buildx version
|
||||||
|
|
||||||
FROM python:3.14-slim AS builder
|
FROM python:3.14-slim AS builder
|
||||||
|
|
||||||
COPY --from=ghcr.io/astral-sh/uv:0.11.26 /uv /uvx /bin/
|
COPY --from=ghcr.io/astral-sh/uv:0.11.26 /uv /uvx /bin/
|
||||||
@@ -8,10 +13,8 @@ ENV UV_COMPILE_BYTECODE=1 \
|
|||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
RUN --mount=type=cache,target=/root/.cache/uv \
|
COPY uv.lock pyproject.toml /app/
|
||||||
--mount=type=bind,source=uv.lock,target=uv.lock \
|
RUN uv sync --locked --no-install-project --no-dev
|
||||||
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
|
|
||||||
uv sync --locked --no-install-project --no-dev --no-build
|
|
||||||
|
|
||||||
# Le projet lui-meme n'est pas installe (pas de second `uv sync`) : il tourne depuis /app, le
|
# Le projet lui-meme n'est pas installe (pas de second `uv sync`) : il tourne depuis /app, le
|
||||||
# repertoire de travail, et rien ne lit ses metadonnees. L'installer imposerait de le construire
|
# repertoire de travail, et rien ne lit ses metadonnees. L'installer imposerait de le construire
|
||||||
@@ -19,6 +22,7 @@ RUN --mount=type=cache,target=/root/.cache/uv \
|
|||||||
# l'installation des dependances n'execute aucun script de build (regle Sonar docker:S8541).
|
# l'installation des dependances n'execute aucun script de build (regle Sonar docker:S8541).
|
||||||
COPY . /app
|
COPY . /app
|
||||||
|
|
||||||
|
RUN uv sync --locked --no-dev
|
||||||
|
|
||||||
FROM python:3.14-slim AS runtime
|
FROM python:3.14-slim AS runtime
|
||||||
|
|
||||||
|
|||||||
@@ -26,20 +26,28 @@ RUN npm run build
|
|||||||
FROM nginx:1.31-alpine AS runner
|
FROM nginx:1.31-alpine AS runner
|
||||||
|
|
||||||
# Copie de la configuration de nginx
|
# Copie de la configuration de nginx
|
||||||
COPY --chown=root:root --chmod=755 nginx.conf /etc/nginx/nginx.conf
|
COPY --chown=root:root nginx.conf /etc/nginx/nginx.conf
|
||||||
|
RUN chmod 755 /etc/nginx/nginx.conf
|
||||||
|
|
||||||
# Copy the static build output from the build stage to Nginx's default HTML serving directory
|
# Copy the static build output from the build stage to Nginx's default HTML serving directory
|
||||||
COPY --chown=root:root --chmod=755 --from=builder /app/dist/*/browser /usr/share/nginx/html
|
COPY --chown=root:root --from=builder /app/dist/frontend/browser /usr/share/nginx/html
|
||||||
|
RUN chmod 755 /usr/share/nginx/html
|
||||||
|
|
||||||
|
|
||||||
# Create necessary directories with proper permissions for nginx
|
# Create necessary directories with proper permissions for nginx
|
||||||
RUN mkdir -p /var/log/nginx /var/cache/nginx && \
|
RUN mkdir -p /var/log/nginx /var/cache/nginx && \
|
||||||
chown -R nginx:nginx /var/log/nginx /var/cache/nginx /usr/share/nginx/html
|
chown -R nginx:nginx /var/log/nginx /var/cache/nginx /usr/share/nginx/html &&\
|
||||||
|
chmod 755 /var/log/nginx /var/log
|
||||||
|
|
||||||
|
# Permissions appropriées
|
||||||
|
RUN find /usr/share/nginx/html -type f -exec chmod 644 {} \; && \
|
||||||
|
find /usr/share/nginx/html -type d -exec chmod 755 {} \; && \
|
||||||
|
chown -R nginx:nginx /var/log/nginx /var/cache/nginx
|
||||||
|
|
||||||
# Use a non-root user for security best practices
|
# Use a non-root user for security best practices
|
||||||
USER nginx
|
USER nginx
|
||||||
|
|
||||||
# Frontend : port 3000
|
# Frontend : port 3000
|
||||||
# Backend : port 8000
|
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
|
|
||||||
# Start Nginx directly with custom config
|
# Start Nginx directly with custom config
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
worker_processes auto;
|
worker_processes auto;
|
||||||
error_log /var/log/nginx/error.log warn;
|
error_log /dev/null warn; # ← Envoyer les logs vers /dev/null
|
||||||
pid /tmp/nginx.pid;
|
pid /tmp/nginx.pid;
|
||||||
|
|
||||||
events {
|
events {
|
||||||
@@ -9,15 +9,14 @@ events {
|
|||||||
http {
|
http {
|
||||||
include /etc/nginx/mime.types;
|
include /etc/nginx/mime.types;
|
||||||
default_type application/octet-stream;
|
default_type application/octet-stream;
|
||||||
|
access_log /dev/null; # ← Idem pour access logs
|
||||||
|
|
||||||
sendfile on;
|
sendfile on;
|
||||||
keepalive_timeout 65;
|
keepalive_timeout 65;
|
||||||
|
|
||||||
|
|
||||||
server {
|
server {
|
||||||
listen 3000;
|
listen 3000;
|
||||||
server_name _;
|
server_name _;
|
||||||
|
|
||||||
root /usr/share/nginx/html;
|
root /usr/share/nginx/html;
|
||||||
index index.html;
|
index index.html;
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"ng": "ng",
|
"ng": "ng",
|
||||||
"start": "ng serve",
|
"start": "ng serve",
|
||||||
"build": "ng build",
|
"build": "node node_modules/@angular/cli/bin/ng.js build",
|
||||||
"watch": "ng build --watch --configuration development",
|
"watch": "ng build --watch --configuration development",
|
||||||
"test": "ng test",
|
"test": "ng test",
|
||||||
"test:ci": "ng test --watch=false"
|
"test:ci": "ng test --watch=false"
|
||||||
|
|||||||
+42
-2
@@ -1,11 +1,31 @@
|
|||||||
# This file is maintained automatically by "terraform init".
|
# This file is maintained automatically by "terraform init".
|
||||||
# Manual edits may be lost in future updates.
|
# Manual edits may be lost in future updates.
|
||||||
|
|
||||||
|
provider "registry.terraform.io/hashicorp/archive" {
|
||||||
|
version = "2.8.1"
|
||||||
|
constraints = "~> 2.4"
|
||||||
|
hashes = [
|
||||||
|
"h1:eehhIUcuegkswQDKArYBAhVV9wQmRVMhyYGaD7kHIj0=",
|
||||||
|
"zh:03de290604114a89fcd45c2e5bc7787d5a1ebfc5f964fb5989306bea7a4c79ec",
|
||||||
|
"zh:0a7d69dc9fbbc48960bc2f04588c8fb1bd92c78a8f306566b7fb17fc4a4f2058",
|
||||||
|
"zh:4df1f3981379c35f1757da957470f7f7724496b57219da3485177cf1647bdf59",
|
||||||
|
"zh:50f0e72ba53bfe6e11b03b7fc899e1f72536354381d302a743a274ae2a3f45f4",
|
||||||
|
"zh:5c4e15a04c98e2a8cafb1cd9632b48ad318051e8462d105b1153006277985c35",
|
||||||
|
"zh:66069e604bcf5c4af0278e15997d9e6bd755c54fb3801d78885838b889729c5f",
|
||||||
|
"zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3",
|
||||||
|
"zh:979765db3f42601870ab377104ba70befb029547b278337ec4ada980e3582de6",
|
||||||
|
"zh:b165254da774f49945a73fbccc3ef1b63d70ea00a98fa9e14716665ba80ecaad",
|
||||||
|
"zh:c0bb2697b525da9fec4511f569ed2bd2b42f25d5c1f9fa00f8f3645b50cfc2e9",
|
||||||
|
"zh:c48f6695d12df0d0fa5231f7c1b8d518a4feae91a733fdd35a5804af3a303831",
|
||||||
|
"zh:d589954c93f075180c9f4e2ce91780d5edcb56dfd0d3cda8ba08e13c10b52249",
|
||||||
|
"zh:f5792ed06da65d0daf7ca3711f5399ff78c7cb4400afe53fbce9a926fbde4477",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
provider "registry.terraform.io/hashicorp/null" {
|
provider "registry.terraform.io/hashicorp/null" {
|
||||||
version = "3.3.2"
|
version = "3.3.2"
|
||||||
constraints = "~> 3.2"
|
|
||||||
hashes = [
|
hashes = [
|
||||||
"h1:IQ1qrkht1sC1nibUR+AJ3ulryyhVDHfCHZhoJi0sg2Y=",
|
"h1:7rn0+p+fbrHfJxNVgTnlKp6C3yu0jENMXffz9Xb9XjQ=",
|
||||||
"zh:10ec43b8b7b18d5639238c7fb9e111f6a4b038523dd66c7a426bf27b25fa4c08",
|
"zh:10ec43b8b7b18d5639238c7fb9e111f6a4b038523dd66c7a426bf27b25fa4c08",
|
||||||
"zh:60beb9cc2ad5b871c710860cee75b42850cc6acd43db0d77cb5e00fda7288b55",
|
"zh:60beb9cc2ad5b871c710860cee75b42850cc6acd43db0d77cb5e00fda7288b55",
|
||||||
"zh:62538582d0a4a2f10ad8a8d9a6c3cd3f05af6c6d91c6641ffc78d4f0e8e69b27",
|
"zh:62538582d0a4a2f10ad8a8d9a6c3cd3f05af6c6d91c6641ffc78d4f0e8e69b27",
|
||||||
@@ -21,3 +41,23 @@ provider "registry.terraform.io/hashicorp/null" {
|
|||||||
"zh:faa01928c25d2a6ecd9c7eb8b88134cb08de55a6b11ca6c703ac0092845344ba",
|
"zh:faa01928c25d2a6ecd9c7eb8b88134cb08de55a6b11ca6c703ac0092845344ba",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
provider "registry.terraform.io/kreuzwerker/docker" {
|
||||||
|
version = "4.5.0"
|
||||||
|
constraints = "~> 4.5.0"
|
||||||
|
hashes = [
|
||||||
|
"h1:eXPMxNcZjz5gC7Nc1oEPJldpI6B5btbvldjLOgJQNbI=",
|
||||||
|
"zh:0ee4e9121632158a9ae1049bdd53c71fd9e06357de915dd193df2c1c55ae8814",
|
||||||
|
"zh:12c6991012b5a548a406e1960c323484f95a9538c2522af15ec82f47fdb832d1",
|
||||||
|
"zh:19c86ae59ed1e062e8402a49ea842f957fcda2f9689e06ecbd9480cc9bd1e41a",
|
||||||
|
"zh:3ac8bc9805acd20c40c0ed474c9f4605aa73b61cf52809e1131e335fcbfe8e49",
|
||||||
|
"zh:5a0e70d143759712fdda109f024a41d59d4758b5615378aa21ee6b959f65a416",
|
||||||
|
"zh:5d3599285f71cc53c88a5802fa6e2f8ba87b9deea03abe5fe8bb2639e9d95654",
|
||||||
|
"zh:a42f573a2526cddc9b8a93637a2c5478bc6e903ff29556ab8b2f1467681d5bde",
|
||||||
|
"zh:c8de50d902cc8457e565a5d959f1e3e49064d31c2f14f7adf5f3ec632cfe3695",
|
||||||
|
"zh:d40543d51eb4e902125d2c5a8a0f425a60edcec6c1dc07c4a89d92335ec05541",
|
||||||
|
"zh:dd3105018ffddc8114083dcf84798c32fdecca7ef708eceaee49eb4b306fc061",
|
||||||
|
"zh:e51e0199700698b962085683af4551d1f982dce37f3b6950da062c65e0145505",
|
||||||
|
"zh:ffe415d3d3deffffdbd3a7173e3a9f90b74601cb6d8acafec1ab701a5b91dbff",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
locals {
|
||||||
|
backend_dir = "../../../../apps/backend"
|
||||||
|
backend_image_name = "enervision-back"
|
||||||
|
backend_image_tag = "latest"
|
||||||
|
backend_container_name = "enervision-backend"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "docker_image" "backend" {
|
||||||
|
name = "${local.backend_image_name}:${local.backend_image_tag}"
|
||||||
|
|
||||||
|
build {
|
||||||
|
context = local.backend_dir
|
||||||
|
dockerfile = "Dockerfile"
|
||||||
|
}
|
||||||
|
|
||||||
|
triggers = {
|
||||||
|
build_hash = sha256(join("", [
|
||||||
|
for file in fileset(local.backend_dir, "**") :
|
||||||
|
filesha256("${local.backend_dir}/${file}")
|
||||||
|
]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "docker_container" "backend" {
|
||||||
|
image = docker_image.backend.image_id
|
||||||
|
name = local.backend_container_name
|
||||||
|
|
||||||
|
ports {
|
||||||
|
internal = 8000
|
||||||
|
external = var.backend_port
|
||||||
|
}
|
||||||
|
|
||||||
|
volumes {
|
||||||
|
host_path = "/var/log/enervision"
|
||||||
|
container_path = "/var/log/enervision"
|
||||||
|
}
|
||||||
|
|
||||||
|
depends_on = [docker_image.backend]
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "null_resource" "deploy_backend_to_server" {
|
||||||
|
depends_on = [docker_image.backend]
|
||||||
|
|
||||||
|
triggers = {
|
||||||
|
image_id = docker_image.backend.image_id
|
||||||
|
}
|
||||||
|
|
||||||
|
connection {
|
||||||
|
type = "ssh"
|
||||||
|
host = var.ssh_host
|
||||||
|
port = var.ssh_port
|
||||||
|
user = var.ssh_user
|
||||||
|
password = var.ssh_password
|
||||||
|
private_key = try(file(pathexpand(var.ssh_private_key_path)), null)
|
||||||
|
timeout = "5m"
|
||||||
|
}
|
||||||
|
|
||||||
|
provisioner "file" {
|
||||||
|
source = "${local.backend_dir}/Dockerfile"
|
||||||
|
destination = "/tmp/Dockerfile"
|
||||||
|
}
|
||||||
|
provisioner "file" {
|
||||||
|
source = "${local.backend_dir}/"
|
||||||
|
destination = "/tmp/backend/"
|
||||||
|
}
|
||||||
|
|
||||||
|
provisioner "remote-exec" {
|
||||||
|
inline = [
|
||||||
|
"cd /tmp/backend",
|
||||||
|
"sudo docker stop ${local.backend_container_name} 2>/dev/null || true",
|
||||||
|
"sudo docker rm ${local.backend_container_name} 2>/dev/null || true",
|
||||||
|
"sudo docker build -t ${local.backend_image_name}:${local.backend_image_tag} .",
|
||||||
|
"sudo docker run -d --name ${local.backend_container_name} -p ${var.backend_port}:8000 --restart always -v /var/log/enervision:/var/log/enervision ${local.backend_image_name}:${local.backend_image_tag}"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,145 @@
|
|||||||
|
locals {
|
||||||
|
frontend_environments = {
|
||||||
|
dev = {
|
||||||
|
source_dir = "${path.root}/../../../../apps/frontend/dist/frontend/browser"
|
||||||
|
domain = "dev.enervision"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
frontend_dir = "../../../../apps/frontend"
|
||||||
|
image_name = "enervision-front"
|
||||||
|
image_tag = "latest"
|
||||||
|
container_name = "enervision-frontend"
|
||||||
|
|
||||||
|
selected_frontend = local.frontend_environments[var.deployment_environment]
|
||||||
|
}
|
||||||
|
|
||||||
|
provider "docker" {
|
||||||
|
host = var.docker_host
|
||||||
|
}
|
||||||
|
|
||||||
|
# Build le front
|
||||||
|
resource "null_resource" "build_frontend" {
|
||||||
|
triggers = {
|
||||||
|
frontend_files = sha256(join("", [
|
||||||
|
for file in fileset(local.frontend_dir, "src/**,package.json") :
|
||||||
|
filesha256("${local.frontend_dir}/${file}")
|
||||||
|
]))
|
||||||
|
}
|
||||||
|
|
||||||
|
provisioner "local-exec" {
|
||||||
|
command = "cd ${local.frontend_dir} && npm ci && chmod -R +x node_modules/@angular/cli/bin && chmod -R +x node_modules/.bin && npm exec ng build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Build l'image docker du front
|
||||||
|
resource "docker_image" "frontend" {
|
||||||
|
name = "${local.image_name}:${local.image_tag}"
|
||||||
|
|
||||||
|
build {
|
||||||
|
context = local.frontend_dir
|
||||||
|
dockerfile = "Dockerfile"
|
||||||
|
}
|
||||||
|
|
||||||
|
triggers = {
|
||||||
|
build_hash = sha256(join("", [
|
||||||
|
for file in fileset(local.frontend_dir, "**") :
|
||||||
|
filesha256("${local.frontend_dir}/${file}")
|
||||||
|
]))
|
||||||
|
}
|
||||||
|
|
||||||
|
depends_on = [null_resource.build_frontend]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Création du container Docker
|
||||||
|
resource "docker_container" "frontend" {
|
||||||
|
image = docker_image.frontend.image_id
|
||||||
|
name = local.container_name
|
||||||
|
|
||||||
|
ports {
|
||||||
|
internal = 3000
|
||||||
|
external = var.frontend_port
|
||||||
|
}
|
||||||
|
|
||||||
|
# Volume pour les logs
|
||||||
|
volumes {
|
||||||
|
host_path = "/var/log/enervision"
|
||||||
|
container_path = "/var/log/nginx"
|
||||||
|
}
|
||||||
|
|
||||||
|
depends_on = [docker_image.frontend]
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "null_resource" "create_network" {
|
||||||
|
provisioner "remote-exec" {
|
||||||
|
connection {
|
||||||
|
type = "ssh"
|
||||||
|
host = var.ssh_host
|
||||||
|
port = var.ssh_port
|
||||||
|
user = var.ssh_user
|
||||||
|
password = var.ssh_password
|
||||||
|
private_key = try(file(pathexpand(var.ssh_private_key_path)), null)
|
||||||
|
timeout = "5m"
|
||||||
|
}
|
||||||
|
|
||||||
|
inline = [
|
||||||
|
"sudo docker network create enervision_default 2>/dev/null || true"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Déploiement du container sur le serveur via SSH
|
||||||
|
resource "null_resource" "deploy_to_server" {
|
||||||
|
depends_on = [docker_image.frontend]
|
||||||
|
|
||||||
|
triggers = {
|
||||||
|
image_id = docker_image.frontend.image_id
|
||||||
|
}
|
||||||
|
|
||||||
|
connection {
|
||||||
|
type = "ssh"
|
||||||
|
host = var.ssh_host
|
||||||
|
port = var.ssh_port
|
||||||
|
user = var.ssh_user
|
||||||
|
password = var.ssh_password
|
||||||
|
private_key = try(file(pathexpand(var.ssh_private_key_path)), null)
|
||||||
|
timeout = "5m"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Copie le Dockerfile et nginx.conf
|
||||||
|
provisioner "file" {
|
||||||
|
source = "${local.frontend_dir}/Dockerfile"
|
||||||
|
destination = "/tmp/Dockerfile"
|
||||||
|
}
|
||||||
|
|
||||||
|
provisioner "file" {
|
||||||
|
source = "${local.frontend_dir}/nginx.conf"
|
||||||
|
destination = "/tmp/nginx.conf"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Copie les sources pour le build
|
||||||
|
provisioner "file" {
|
||||||
|
source = "${local.frontend_dir}/"
|
||||||
|
destination = "/tmp/frontend/"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Build et lance le container sur le serveur
|
||||||
|
provisioner "remote-exec" {
|
||||||
|
inline = [
|
||||||
|
"cd /tmp/frontend",
|
||||||
|
"sudo docker stop ${local.container_name} 2>/dev/null || true",
|
||||||
|
"sudo docker rm ${local.container_name} 2>/dev/null || true",
|
||||||
|
"sudo docker build -t ${local.image_name}:${local.image_tag} .",
|
||||||
|
"sudo docker run -d \\",
|
||||||
|
" --name ${local.container_name} \\",
|
||||||
|
" --network enervision_default \\",
|
||||||
|
" --network-alias frontend \\",
|
||||||
|
" -p ${var.frontend_port}:3000 \\",
|
||||||
|
" --restart always \\",
|
||||||
|
" -v /var/log/enervision:/var/log/nginx \\",
|
||||||
|
" ${local.image_name}:${local.image_tag}"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -5,7 +5,24 @@ module "k3s" {
|
|||||||
ssh_port = var.ssh_port
|
ssh_port = var.ssh_port
|
||||||
ssh_user = var.ssh_user
|
ssh_user = var.ssh_user
|
||||||
ssh_private_key_path = var.ssh_private_key_path
|
ssh_private_key_path = var.ssh_private_key_path
|
||||||
|
ssh_password = var.ssh_password
|
||||||
k3s_version = var.k3s_version
|
k3s_version = var.k3s_version
|
||||||
k3s_disable_components = var.k3s_disable_components
|
k3s_disable_components = var.k3s_disable_components
|
||||||
kubeconfig_output_path = var.kubeconfig_output_path
|
kubeconfig_output_path = var.kubeconfig_output_path
|
||||||
}
|
}
|
||||||
|
|
||||||
|
provider "vault" {
|
||||||
|
# Adresse du serveur Vault (dev)
|
||||||
|
address = "https://10.101.200.37:8200"
|
||||||
|
|
||||||
|
# Auth par userpass
|
||||||
|
auth_login {
|
||||||
|
path = "auth/userpass/login/${var.vault_username}"
|
||||||
|
parameters = {
|
||||||
|
login = var.vault_username
|
||||||
|
password = var.vault_password
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# Skip verify pour dev uniquement (pas en prod!)
|
||||||
|
# skip_client_verification = true
|
||||||
|
}
|
||||||
@@ -21,6 +21,35 @@ variable "ssh_private_key_path" {
|
|||||||
sensitive = true
|
sensitive = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
variable "ssh_password" {
|
||||||
|
type = string
|
||||||
|
sensitive = true
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "remote_path" {
|
||||||
|
type = string
|
||||||
|
description = "Chemin distant sur le serveur pour le deploiement."
|
||||||
|
default = "/var/www/enervision"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "docker_host" {
|
||||||
|
type = string
|
||||||
|
default = "npipe:////.//pipe//docker_engine"
|
||||||
|
description = "Host Docker (local ou distant)"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "frontend_port" {
|
||||||
|
type = number
|
||||||
|
default = 3000
|
||||||
|
description = "Port externe du frontend"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "backend_port" {
|
||||||
|
type = number
|
||||||
|
default = 8000
|
||||||
|
description = "Port externe du backend"
|
||||||
|
}
|
||||||
|
|
||||||
variable "k3s_version" {
|
variable "k3s_version" {
|
||||||
type = string
|
type = string
|
||||||
description = "Version k3s a epingler pour un deploiement reproductible (ex: v1.31.5+k3s1). Voir https://github.com/k3s-io/k3s/releases."
|
description = "Version k3s a epingler pour un deploiement reproductible (ex: v1.31.5+k3s1). Voir https://github.com/k3s-io/k3s/releases."
|
||||||
@@ -37,3 +66,25 @@ variable "kubeconfig_output_path" {
|
|||||||
description = "Chemin local ou ecrire le kubeconfig recupere apres installation."
|
description = "Chemin local ou ecrire le kubeconfig recupere apres installation."
|
||||||
default = "./kubeconfig"
|
default = "./kubeconfig"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
variable "deployment_environment" {
|
||||||
|
type = string
|
||||||
|
default = "dev"
|
||||||
|
|
||||||
|
validation {
|
||||||
|
condition = contains(["dev", "rec", "prod"], var.deployment_environment)
|
||||||
|
error_message = "L'environnement doit être dev, rec ou prod."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vault_username" {
|
||||||
|
description = "Username Vault"
|
||||||
|
type = string
|
||||||
|
sensitive = false
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vault_password" {
|
||||||
|
description = "Password Vault"
|
||||||
|
type = string
|
||||||
|
sensitive = true
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,125 @@
|
|||||||
|
locals {
|
||||||
|
frontend_environments = {
|
||||||
|
prod = {
|
||||||
|
source_dir = "${path.root}/../../../apps/frontend/dist/frontend/browser"
|
||||||
|
domain = "enervision"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
frontend_dir = "../../../../apps/frontend"
|
||||||
|
image_name = "enervision-front"
|
||||||
|
image_tag = "latest"
|
||||||
|
container_name = "enervision-frontend"
|
||||||
|
|
||||||
|
selected_frontend = local.frontend_environments[var.deployment_environment]
|
||||||
|
}
|
||||||
|
|
||||||
|
provider "docker" {
|
||||||
|
host = var.docker_host
|
||||||
|
}
|
||||||
|
|
||||||
|
# Build le front
|
||||||
|
resource "null_resource" "build_frontend" {
|
||||||
|
triggers = {
|
||||||
|
frontend_files = sha256(join("", [
|
||||||
|
for file in fileset(local.frontend_dir, "src/**,package.json") :
|
||||||
|
filesha256("${local.frontend_dir}/${file}")
|
||||||
|
]))
|
||||||
|
}
|
||||||
|
|
||||||
|
provisioner "local-exec" {
|
||||||
|
command = "cd ${local.frontend_dir} && npm ci && chmod -R +x node_modules/@angular/cli/bin && chmod -R +x node_modules/.bin && npm exec ng build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Build l'image docker du front
|
||||||
|
resource "docker_image" "frontend" {
|
||||||
|
name = "${local.image_name}:${local.image_tag}"
|
||||||
|
|
||||||
|
build {
|
||||||
|
context = local.frontend_dir
|
||||||
|
dockerfile = "Dockerfile"
|
||||||
|
}
|
||||||
|
|
||||||
|
triggers = {
|
||||||
|
build_hash = sha256(join("", [
|
||||||
|
for file in fileset(local.frontend_dir, "**") :
|
||||||
|
filesha256("${local.frontend_dir}/${file}")
|
||||||
|
]))
|
||||||
|
}
|
||||||
|
|
||||||
|
depends_on = [null_resource.build_frontend]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Création du container Docker
|
||||||
|
resource "docker_container" "frontend" {
|
||||||
|
image = docker_image.frontend.image_id
|
||||||
|
name = local.container_name
|
||||||
|
|
||||||
|
ports {
|
||||||
|
internal = 3000
|
||||||
|
external = var.frontend_port
|
||||||
|
}
|
||||||
|
|
||||||
|
# Volume pour les logs
|
||||||
|
volumes {
|
||||||
|
host_path = "/var/log/enervision"
|
||||||
|
container_path = "/var/log/nginx"
|
||||||
|
}
|
||||||
|
|
||||||
|
depends_on = [docker_image.frontend]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Déploiement du container sur le serveur via SSH
|
||||||
|
resource "null_resource" "deploy_to_server" {
|
||||||
|
depends_on = [docker_image.frontend]
|
||||||
|
|
||||||
|
triggers = {
|
||||||
|
image_id = docker_image.frontend.image_id
|
||||||
|
}
|
||||||
|
|
||||||
|
connection {
|
||||||
|
type = "ssh"
|
||||||
|
host = var.ssh_host
|
||||||
|
port = var.ssh_port
|
||||||
|
user = var.ssh_user
|
||||||
|
password = var.ssh_password
|
||||||
|
private_key = try(file(pathexpand(var.ssh_private_key_path)), null)
|
||||||
|
timeout = "5m"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Copie le Dockerfile et nginx.conf
|
||||||
|
provisioner "file" {
|
||||||
|
source = "${local.frontend_dir}/Dockerfile"
|
||||||
|
destination = "/tmp/Dockerfile"
|
||||||
|
}
|
||||||
|
|
||||||
|
provisioner "file" {
|
||||||
|
source = "${local.frontend_dir}/nginx.conf"
|
||||||
|
destination = "/tmp/nginx.conf"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Copie les sources pour le build
|
||||||
|
provisioner "file" {
|
||||||
|
source = "${local.frontend_dir}/"
|
||||||
|
destination = "/tmp/frontend/"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Build et lance le container sur le serveur
|
||||||
|
provisioner "remote-exec" {
|
||||||
|
inline = [
|
||||||
|
"cd /tmp/frontend",
|
||||||
|
"sudo docker stop ${local.container_name} 2>/dev/null || true",
|
||||||
|
"sudo docker rm ${local.container_name} 2>/dev/null || true",
|
||||||
|
"sudo docker build -t ${local.image_name}:${local.image_tag} .",
|
||||||
|
"sudo docker run -d \\",
|
||||||
|
" --name ${local.container_name} \\",
|
||||||
|
" --network enervision_default \\",
|
||||||
|
" --network-alias frontend \\",
|
||||||
|
" -p ${var.frontend_port}:3000 \\",
|
||||||
|
" --restart always \\",
|
||||||
|
" -v /var/log/enervision:/var/log/nginx \\",
|
||||||
|
" ${local.image_name}:${local.image_tag}"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
module "k3s" {
|
||||||
|
source = "../../modules/k3s"
|
||||||
|
|
||||||
|
ssh_host = var.ssh_host
|
||||||
|
ssh_port = var.ssh_port
|
||||||
|
ssh_user = var.ssh_user
|
||||||
|
ssh_private_key_path = var.ssh_private_key_path
|
||||||
|
k3s_version = var.k3s_version
|
||||||
|
k3s_disable_components = var.k3s_disable_components
|
||||||
|
kubeconfig_output_path = var.kubeconfig_output_path
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
output "kubeconfig_path" {
|
||||||
|
description = "Chemin local du kubeconfig recupere apres installation."
|
||||||
|
value = module.k3s.kubeconfig_path
|
||||||
|
}
|
||||||
|
|
||||||
|
output "node_host" {
|
||||||
|
description = "Adresse du serveur sur lequel k3s est installe."
|
||||||
|
value = module.k3s.node_host
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
variable "ssh_host" {
|
||||||
|
type = string
|
||||||
|
description = "Adresse IP ou nom d'hote du serveur on-premise de l'ecole."
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "ssh_port" {
|
||||||
|
type = number
|
||||||
|
description = "Port SSH du serveur."
|
||||||
|
default = 22
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "ssh_user" {
|
||||||
|
type = string
|
||||||
|
description = "Utilisateur SSH utilise pour l'installation."
|
||||||
|
default = "root"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "ssh_private_key_path" {
|
||||||
|
type = string
|
||||||
|
description = "Chemin local vers la cle privee SSH."
|
||||||
|
sensitive = true
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "k3s_version" {
|
||||||
|
type = string
|
||||||
|
description = "Version k3s a epingler pour un deploiement reproductible (ex: v1.31.5+k3s1). Voir https://github.com/k3s-io/k3s/releases."
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "k3s_disable_components" {
|
||||||
|
type = list(string)
|
||||||
|
description = "Composants embarques k3s a desactiver."
|
||||||
|
default = ["traefik"]
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "kubeconfig_output_path" {
|
||||||
|
type = string
|
||||||
|
description = "Chemin local ou ecrire le kubeconfig recupere apres installation."
|
||||||
|
default = "./kubeconfig"
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
terraform {
|
||||||
|
required_version = ">= 1.7"
|
||||||
|
|
||||||
|
required_providers {
|
||||||
|
null = {
|
||||||
|
source = "hashicorp/null"
|
||||||
|
version = "~> 3.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
backend "local" {
|
||||||
|
path = "terraform.tfstate"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
locals {
|
||||||
|
frontend_environments = {
|
||||||
|
rec = {
|
||||||
|
source_dir = "${path.root}/../../../apps/frontend/dist/frontend-rec/browser"
|
||||||
|
domain = "rec.enervision"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
selected_frontend = local.frontend_environments[var.deployment_environment]
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "null_resource" "frontend" {
|
||||||
|
depends_on = [module.k3s]
|
||||||
|
|
||||||
|
triggers = {
|
||||||
|
environment = var.deployment_environment
|
||||||
|
|
||||||
|
build_hash = sha256(join("", [
|
||||||
|
for file in fileset("${path.root}/../../../apps/frontend/dist/frontend/browser", "**") :
|
||||||
|
filesha256("${path.root}/../../../apps/frontend/dist/frontend/browser/${file}")
|
||||||
|
]))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Variables pour la connexion SSH
|
||||||
|
connection {
|
||||||
|
type = "ssh"
|
||||||
|
host = var.ssh_host
|
||||||
|
port = var.ssh_port
|
||||||
|
user = var.ssh_user
|
||||||
|
private_key = file(pathexpand(var.ssh_private_key_path))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lancement de script en SSH avec remote-exec
|
||||||
|
// Installation de Nginx et initialisation du répertoire du frontend
|
||||||
|
provisioner "remote-exec" {
|
||||||
|
inline = [
|
||||||
|
"sudo apt-get update",
|
||||||
|
"sudo apt-get install -y nginx",
|
||||||
|
"sudo mkdir -p /var/www/enervision",
|
||||||
|
"sudo rm -rf /var/www/enervision/*"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copie des fichiers vers le serveur
|
||||||
|
provisioner "file" {
|
||||||
|
source = "${path.root}/../../../apps/frontend/dist/frontend/browser/"
|
||||||
|
destination = "/tmp/enervision-frontend"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Déplacement des fichiers
|
||||||
|
provisioner "remote-exec" {
|
||||||
|
inline = [
|
||||||
|
"sudo cp -r /tmp/enervision-frontend/* /var/www/enervision/",
|
||||||
|
"sudo chown -R www-data:www-data /var/www/enervision"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
module "k3s" {
|
||||||
|
source = "../../modules/k3s"
|
||||||
|
|
||||||
|
ssh_host = var.ssh_host
|
||||||
|
ssh_port = var.ssh_port
|
||||||
|
ssh_user = var.ssh_user
|
||||||
|
ssh_private_key_path = var.ssh_private_key_path
|
||||||
|
k3s_version = var.k3s_version
|
||||||
|
k3s_disable_components = var.k3s_disable_components
|
||||||
|
kubeconfig_output_path = var.kubeconfig_output_path
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
output "kubeconfig_path" {
|
||||||
|
description = "Chemin local du kubeconfig recupere apres installation."
|
||||||
|
value = module.k3s.kubeconfig_path
|
||||||
|
}
|
||||||
|
|
||||||
|
output "node_host" {
|
||||||
|
description = "Adresse du serveur sur lequel k3s est installe."
|
||||||
|
value = module.k3s.node_host
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
variable "ssh_host" {
|
||||||
|
type = string
|
||||||
|
description = "Adresse IP ou nom d'hote du serveur on-premise de l'ecole."
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "ssh_port" {
|
||||||
|
type = number
|
||||||
|
description = "Port SSH du serveur."
|
||||||
|
default = 22
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "ssh_user" {
|
||||||
|
type = string
|
||||||
|
description = "Utilisateur SSH utilise pour l'installation."
|
||||||
|
default = "root"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "ssh_private_key_path" {
|
||||||
|
type = string
|
||||||
|
description = "Chemin local vers la cle privee SSH."
|
||||||
|
sensitive = true
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "k3s_version" {
|
||||||
|
type = string
|
||||||
|
description = "Version k3s a epingler pour un deploiement reproductible (ex: v1.31.5+k3s1). Voir https://github.com/k3s-io/k3s/releases."
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "k3s_disable_components" {
|
||||||
|
type = list(string)
|
||||||
|
description = "Composants embarques k3s a desactiver."
|
||||||
|
default = ["traefik"]
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "kubeconfig_output_path" {
|
||||||
|
type = string
|
||||||
|
description = "Chemin local ou ecrire le kubeconfig recupere apres installation."
|
||||||
|
default = "./kubeconfig"
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
terraform {
|
||||||
|
required_version = ">= 1.7"
|
||||||
|
|
||||||
|
required_providers {
|
||||||
|
null = {
|
||||||
|
source = "hashicorp/null"
|
||||||
|
version = "~> 3.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
backend "local" {
|
||||||
|
path = "terraform.tfstate"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,13 +2,15 @@ terraform {
|
|||||||
required_version = ">= 1.7"
|
required_version = ">= 1.7"
|
||||||
|
|
||||||
required_providers {
|
required_providers {
|
||||||
null = {
|
archive = {
|
||||||
source = "hashicorp/null"
|
source = "hashicorp/archive"
|
||||||
version = "~> 3.2"
|
version = "~> 2.4"
|
||||||
|
}
|
||||||
|
|
||||||
|
docker = {
|
||||||
|
source = "kreuzwerker/docker"
|
||||||
|
version = "~> 4.5.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
backend "local" {
|
|
||||||
path = "terraform.tfstate"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,13 @@ locals {
|
|||||||
# l'adresse, le port, l'utilisateur et le chemin de la cle : jamais la cle ni un mot de passe.
|
# l'adresse, le port, l'utilisateur et le chemin de la cle : jamais la cle ni un mot de passe.
|
||||||
resource "null_resource" "k3s_install" {
|
resource "null_resource" "k3s_install" {
|
||||||
triggers = {
|
triggers = {
|
||||||
|
ssh_host = var.ssh_host
|
||||||
|
ssh_port = tostring(var.ssh_port)
|
||||||
|
ssh_user = var.ssh_user
|
||||||
|
ssh_password = var.ssh_password
|
||||||
|
k3s_version = var.k3s_version
|
||||||
|
disable_components = join(",", var.k3s_disable_components)
|
||||||
|
sudo_prefix = local.sudo_prefix
|
||||||
ssh_host = var.ssh_host
|
ssh_host = var.ssh_host
|
||||||
ssh_port = tostring(var.ssh_port)
|
ssh_port = tostring(var.ssh_port)
|
||||||
ssh_user = var.ssh_user
|
ssh_user = var.ssh_user
|
||||||
@@ -22,9 +29,9 @@ resource "null_resource" "k3s_install" {
|
|||||||
connection {
|
connection {
|
||||||
type = "ssh"
|
type = "ssh"
|
||||||
host = self.triggers.ssh_host
|
host = self.triggers.ssh_host
|
||||||
port = tonumber(self.triggers.ssh_port)
|
port = self.triggers.ssh_port
|
||||||
user = self.triggers.ssh_user
|
user = self.triggers.ssh_user
|
||||||
private_key = file(pathexpand(self.triggers.ssh_key_path))
|
password = self.triggers.ssh_password
|
||||||
}
|
}
|
||||||
|
|
||||||
provisioner "remote-exec" {
|
provisioner "remote-exec" {
|
||||||
@@ -53,10 +60,13 @@ resource "null_resource" "fetch_kubeconfig" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
provisioner "local-exec" {
|
provisioner "local-exec" {
|
||||||
interpreter = ["bash", "-c"]
|
interpreter = ["PowerShell", "-NoProfile", "-Command"]
|
||||||
|
|
||||||
command = <<-EOT
|
command = <<-EOT
|
||||||
ssh -i "${var.ssh_private_key_path}" -p ${var.ssh_port} -o StrictHostKeyChecking=accept-new ${var.ssh_user}@${var.ssh_host} '${local.kubeconfig_cmd}' \
|
$content = ssh -i "${pathexpand(var.ssh_private_key_path)}" -p ${var.ssh_port} -o StrictHostKeyChecking=accept-new ${var.ssh_user}@${var.ssh_host} "cat /etc/rancher/k3s/k3s.yaml"
|
||||||
| sed 's/127.0.0.1/${var.ssh_host}/' > "${var.kubeconfig_output_path}"
|
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
||||||
|
$content -replace "127.0.0.1", "${var.ssh_host}" |
|
||||||
|
Set-Content -Path "${var.kubeconfig_output_path}" -Encoding UTF8
|
||||||
EOT
|
EOT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,11 @@ variable "ssh_private_key_path" {
|
|||||||
sensitive = true
|
sensitive = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
variable "ssh_password" {
|
||||||
|
type = string
|
||||||
|
sensitive = true
|
||||||
|
}
|
||||||
|
|
||||||
variable "k3s_version" {
|
variable "k3s_version" {
|
||||||
type = string
|
type = string
|
||||||
description = "Version k3s a epingler pour un deploiement reproductible (ex: v1.31.5+k3s1). Voir https://github.com/k3s-io/k3s/releases."
|
description = "Version k3s a epingler pour un deploiement reproductible (ex: v1.31.5+k3s1). Voir https://github.com/k3s-io/k3s/releases."
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ terraform {
|
|||||||
required_version = ">= 1.7"
|
required_version = ">= 1.7"
|
||||||
|
|
||||||
required_providers {
|
required_providers {
|
||||||
null = {
|
provider = {
|
||||||
source = "hashicorp/null"
|
source = "hashicorp/archive"
|
||||||
version = "~> 3.2"
|
version = "~> 2.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user