From 75e669b8b4a48673b97b272c0c0dd97bdc5ef403 Mon Sep 17 00:00:00 2001 From: fserres Date: Mon, 9 Dec 2024 14:58:48 -0500 Subject: [PATCH] Add deployment with opentofu --- .gitignore | 10 +- opentofu/README.md | 44 +++++ opentofu/auth_config.json.example | 35 ++++ opentofu/azure/app.tf | 67 ++++++++ opentofu/azure/database.tf | 43 +++++ opentofu/azure/main.tf | 14 ++ opentofu/azure/network.tf | 87 ++++++++++ opentofu/azure/resource_group.tf | 5 + opentofu/azure/storage.tf | 74 ++++++++ opentofu/azure/terraform.tfvars.example | 7 + opentofu/azure/variables.tf | 214 ++++++++++++++++++++++++ opentofu/docker-compose.yaml | 80 +++++++++ 12 files changed, 679 insertions(+), 1 deletion(-) create mode 100644 opentofu/README.md create mode 100644 opentofu/auth_config.json.example create mode 100644 opentofu/azure/app.tf create mode 100644 opentofu/azure/database.tf create mode 100644 opentofu/azure/main.tf create mode 100644 opentofu/azure/network.tf create mode 100644 opentofu/azure/resource_group.tf create mode 100644 opentofu/azure/storage.tf create mode 100644 opentofu/azure/terraform.tfvars.example create mode 100644 opentofu/azure/variables.tf create mode 100644 opentofu/docker-compose.yaml diff --git a/.gitignore b/.gitignore index 551aa14..f6ed4f9 100644 --- a/.gitignore +++ b/.gitignore @@ -130,4 +130,12 @@ dist .pnp.* db-backup/ -.venv \ No newline at end of file +.venv + +# Opentofu state +opentofu/*/.terraform +opentofu/*/.terraform.lock* +opentofu/*/terraform.tfstate* +opentofu/*/terraform.tfvars +# Opentofu auth config +opentofu/auth_config.json \ No newline at end of file diff --git a/opentofu/README.md b/opentofu/README.md new file mode 100644 index 0000000..b7de6e5 --- /dev/null +++ b/opentofu/README.md @@ -0,0 +1,44 @@ +# Déploiement avec Opentofu + +## Microsoft Azure + +### Installer opentofu + +https://opentofu.org/docs/intro/install/ + +### Installer Azure CLI + +https://learn.microsoft.com/en-us/cli/azure/install-azure-cli#install + +### Se connecter à Azure et récupérer l'id de l'abonnement Azure + +Pour se connecter à Azure, faites la commande suivante + +`az login` + +Avec cette commande, vous allez sélectionner un abonnement Azure. Copiez l'id de l'abonnement, vous en aurez besoin +dans l'étape suivant. + +### Modifier les configurations + +Créer un fichier **terraform.tfvars** sur la base du fichier **terraform.tfvars.example** dans le répertoire **azure**. +Vous pouvez changer toutes les variables utilisée lors du déploiement dans ce fichier. +Toutes les variables, leur description et leur valeur par défaut sont disponibles dans le fichier **variables.tf**. + +Créer un fichier **auth_config.json** sur la base du fichier **auth_config.json.example** dans le répertoire **opentofu**. + +L'url est défini comme suit: http://..cloudapp.azure.com. +Par défaut, l'url est http://evaluetonsavoir.canadacentral.cloudapp.azure.com/ + +### Lancer le déploiement + +Pour lancer le déploiement, faites les commandes suivantes + +`cd azure` +`az login` +`tofu init` +`tofu apply` + +Ensuite, opentofu va afficher toutes les actions qu'il va effectuer avec les valeurs configurées. +Entrez `yes` pour appliquer ces actions et lancer le déploiement. + diff --git a/opentofu/auth_config.json.example b/opentofu/auth_config.json.example new file mode 100644 index 0000000..6e15147 --- /dev/null +++ b/opentofu/auth_config.json.example @@ -0,0 +1,35 @@ +{ + auth: { + passportjs: [ + { + provider1: { + type: "oauth", + OAUTH_AUTHORIZATION_URL: "https://www.testurl.com/oauth2/authorize", + OAUTH_TOKEN_URL: "https://www.testurl.com/oauth2/token", + OAUTH_USERINFO_URL: "https://www.testurl.com/oauth2/userinfo/", + OAUTH_CLIENT_ID: "your_oauth_client_id", + OAUTH_CLIENT_SECRET: "your_oauth_client_secret", + OAUTH_ADD_SCOPE: "scopes", + OAUTH_ROLE_TEACHER_VALUE: "teacher-claim-value", + OAUTH_ROLE_STUDENT_VALUE: "student-claim-value", + }, + }, + { + provider2: { + type: "oidc", + OIDC_CLIENT_ID: "your_oidc_client_id", + OIDC_CLIENT_SECRET: "your_oidc_client_secret", + OIDC_CONFIG_URL: "https://your-issuer.com", + OIDC_ADD_SCOPE: "groups", + OIDC_ROLE_TEACHER_VALUE: "teacher-claim-value", + OIDC_ROLE_STUDENT_VALUE: "student-claim-value", + }, + }, + ], + "simpleauth": { + enabled: true, + name: "provider3", + SESSION_SECRET: "your_session_secret", + }, + }, +} \ No newline at end of file diff --git a/opentofu/azure/app.tf b/opentofu/azure/app.tf new file mode 100644 index 0000000..a1dada5 --- /dev/null +++ b/opentofu/azure/app.tf @@ -0,0 +1,67 @@ +# Create Virtual Machine +resource "azurerm_linux_virtual_machine" "vm" { + name = var.vm_name + resource_group_name = azurerm_resource_group.resource_group.name + location = azurerm_resource_group.resource_group.location + size = var.vm_size + admin_username = var.vm_user + admin_password = var.vm_password + disable_password_authentication = false + + network_interface_ids = [azurerm_network_interface.nic.id] + + os_disk { + name = var.vm_os_disk_name + caching = "ReadWrite" + storage_account_type = var.vm_os_disk_type + } + + source_image_reference { + publisher = var.vm_image_publisher + offer = var.vm_image_offer + sku = var.vm_image_plan + version = var.vm_image_version + } + + custom_data = base64encode(<<-EOT + #!/bin/bash + sudo apt-get update -y + sudo apt-get install -y docker.io + sudo apt-get install -y docker-compose + sudo systemctl start docker + sudo systemctl enable docker + + sudo usermod -aG docker ${var.vm_user} + sudo newgrp docker + + su - ${var.vm_user} -c ' + + curl -o auth_config.json \ + "https://${azurerm_storage_account.storage_account.name}.file.core.windows.net/${azurerm_storage_share.backend_storage_share.name}/auth_config.json${data.azurerm_storage_account_sas.storage_access.sas}" + + curl -L -o docker-compose.yaml ${var.docker_compose_url} + + export VITE_BACKEND_URL=http://${var.dns}.${lower(replace(azurerm_resource_group.resource_group.location, " ", ""))}.cloudapp.azure.com + export PORT=${var.backend_port} + export MONGO_URI="${azurerm_cosmosdb_account.cosmosdb_account.primary_mongodb_connection_string}" + export MONGO_DATABASE=${azurerm_cosmosdb_mongo_collection.cosmosdb_mongo_collection.database_name} + export EMAIL_SERVICE=${var.backend_email_service} + export SENDER_EMAIL=${var.backend_email_sender} + export EMAIL_PSW="${var.backend_email_password}" + export JWT_SECRET=${var.backend_jwt_secret} + export SESSION_Secret=${var.backend_session_secret} + export SITE_URL=http://${var.dns}.${lower(replace(azurerm_resource_group.resource_group.location, " ", ""))}.cloudapp.azure.com + export FRONTEND_PORT=${var.frontend_port} + export USE_PORTS=${var.backend_use_port} + export AUTHENTICATED_ROOMS=${var.backend_use_auth_student} + export QUIZROOM_IMAGE=${var.quizroom_image} + + docker-compose up -d + ' + EOT + ) + + depends_on = [ + azurerm_cosmosdb_mongo_collection.cosmosdb_mongo_collection, + data.azurerm_storage_account_sas.storage_access] +} diff --git a/opentofu/azure/database.tf b/opentofu/azure/database.tf new file mode 100644 index 0000000..efc9fbf --- /dev/null +++ b/opentofu/azure/database.tf @@ -0,0 +1,43 @@ +resource "azurerm_cosmosdb_account" "cosmosdb_account" { + name = var.cosmosdb_account_name + resource_group_name = azurerm_resource_group.resource_group.name + location = azurerm_resource_group.resource_group.location + offer_type = "Standard" + kind = "MongoDB" + mongo_server_version = "7.0" + + is_virtual_network_filter_enabled = true + + virtual_network_rule { + id = azurerm_subnet.subnet.id + } + + capabilities { + name = "EnableMongo" + } + + consistency_policy { + consistency_level = "Session" + } + + geo_location { + failover_priority = 0 + location = azurerm_resource_group.resource_group.location + } + + depends_on = [azurerm_resource_group.resource_group] +} + +resource "azurerm_cosmosdb_mongo_collection" "cosmosdb_mongo_collection" { + name = var.mongo_database_name + resource_group_name = azurerm_resource_group.resource_group.name + account_name = azurerm_cosmosdb_account.cosmosdb_account.name + database_name = var.mongo_database_name + + index { + keys = ["_id"] + unique = true + } + + depends_on = [azurerm_cosmosdb_account.cosmosdb_account] +} \ No newline at end of file diff --git a/opentofu/azure/main.tf b/opentofu/azure/main.tf new file mode 100644 index 0000000..1d1329d --- /dev/null +++ b/opentofu/azure/main.tf @@ -0,0 +1,14 @@ +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "~> 4.0" + } + } + required_version = ">= 1.0" +} + +provider "azurerm" { + features {} + subscription_id = var.subscription_id +} \ No newline at end of file diff --git a/opentofu/azure/network.tf b/opentofu/azure/network.tf new file mode 100644 index 0000000..d9db2c8 --- /dev/null +++ b/opentofu/azure/network.tf @@ -0,0 +1,87 @@ +# Create Virtual Network +resource "azurerm_virtual_network" "vnet" { + name = var.vnet_name + location = azurerm_resource_group.resource_group.location + resource_group_name = azurerm_resource_group.resource_group.name + address_space = ["10.0.0.0/16"] +} + +# Create Subnet +resource "azurerm_subnet" "subnet" { + name = var.subnet_name + resource_group_name = azurerm_resource_group.resource_group.name + virtual_network_name = azurerm_virtual_network.vnet.name + address_prefixes = ["10.0.1.0/24"] + + service_endpoints = ["Microsoft.AzureCosmosDB"] +} + +# Create Public IP Address +resource "azurerm_public_ip" "public_ip" { + name = var.public_ip_name + location = azurerm_resource_group.resource_group.location + resource_group_name = azurerm_resource_group.resource_group.name + allocation_method = "Static" + domain_name_label = var.dns +} + +resource "azurerm_network_security_group" "nsg" { + name = var.nsg_name + location = azurerm_resource_group.resource_group.location + resource_group_name = azurerm_resource_group.resource_group.name + + security_rule { + name = "SSH" + priority = 1000 + direction = "Inbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "22" + source_address_prefix = var.nsg_ssh_ip_range + destination_address_prefix = "*" + } + + security_rule { + name = "HTTP" + priority = 1001 + direction = "Inbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "80" + source_address_prefix = var.nsg_http_ip_range + destination_address_prefix = "*" + } + + security_rule { + name = "HTTPS" + priority = 1002 + direction = "Inbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "443" + source_address_prefix = var.nsg_https_ip_range + destination_address_prefix = "*" + } +} + +# Create Network Interface +resource "azurerm_network_interface" "nic" { + name = var.network_interface_name + location = azurerm_resource_group.resource_group.location + resource_group_name = azurerm_resource_group.resource_group.name + + ip_configuration { + name = "internal" + subnet_id = azurerm_subnet.subnet.id + private_ip_address_allocation = "Dynamic" + public_ip_address_id = azurerm_public_ip.public_ip.id + } +} + +resource "azurerm_network_interface_security_group_association" "example" { + network_interface_id = azurerm_network_interface.nic.id + network_security_group_id = azurerm_network_security_group.nsg.id +} diff --git a/opentofu/azure/resource_group.tf b/opentofu/azure/resource_group.tf new file mode 100644 index 0000000..ed83082 --- /dev/null +++ b/opentofu/azure/resource_group.tf @@ -0,0 +1,5 @@ +# Create Resource Group +resource "azurerm_resource_group" "resource_group" { + name = var.resource_group_name + location = var.location +} \ No newline at end of file diff --git a/opentofu/azure/storage.tf b/opentofu/azure/storage.tf new file mode 100644 index 0000000..1eb6db7 --- /dev/null +++ b/opentofu/azure/storage.tf @@ -0,0 +1,74 @@ +resource "azurerm_storage_account" "storage_account" { + name = var.config_volume_storage_account_name + resource_group_name = azurerm_resource_group.resource_group.name + location = azurerm_resource_group.resource_group.location + account_tier = "Standard" + account_replication_type = "LRS" + + depends_on = [azurerm_resource_group.resource_group] +} + +resource "azurerm_storage_share" "backend_storage_share" { + name = var.backend_storage_share_name + storage_account_name = azurerm_storage_account.storage_account.name + quota = 1 + + depends_on = [azurerm_storage_account.storage_account] +} + +resource "null_resource" "upload_file" { + provisioner "local-exec" { + command = <