From 54c817273976009bcdb1b54e2ae55203223ec150 Mon Sep 17 00:00:00 2001 From: kkatkot Date: Sun, 3 May 2026 00:07:49 +0300 Subject: [PATCH 01/10] Solution --- .gitignore | 2 ++ backend.tf | 26 +++++++++++++++ main.tf | 0 modules/compute/main.tf | 59 +++++++++++++++++++++++++++++++++ modules/compute/outputs.tf | 0 modules/compute/variables.tf | 14 ++++++++ modules/network/main.tf | 64 ++++++++++++++++++++++++++++++++++++ modules/network/outputs.tf | 0 modules/network/variables.tf | 29 ++++++++++++++++ modules/storage/main.tf | 24 ++++++++++++++ modules/storage/outputs.tf | 0 modules/storage/variables.tf | 9 +++++ outputs.tf | 0 terraform.tfvars | 0 variables.tf | 59 +++++++++++++++++++++++++++++++++ 15 files changed, 286 insertions(+) create mode 100644 .gitignore create mode 100644 backend.tf create mode 100644 main.tf create mode 100644 modules/compute/main.tf create mode 100644 modules/compute/outputs.tf create mode 100644 modules/compute/variables.tf create mode 100644 modules/network/main.tf create mode 100644 modules/network/outputs.tf create mode 100644 modules/network/variables.tf create mode 100644 modules/storage/main.tf create mode 100644 modules/storage/outputs.tf create mode 100644 modules/storage/variables.tf create mode 100644 outputs.tf create mode 100644 terraform.tfvars create mode 100644 variables.tf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5b5fa30 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.terraform/ +.terraform.lock.hcl \ No newline at end of file diff --git a/backend.tf b/backend.tf new file mode 100644 index 0000000..ea7e68c --- /dev/null +++ b/backend.tf @@ -0,0 +1,26 @@ +resource "azurerm_resource_group" "example" { + name = var.resource_group_name + location = var.location +} + +resource "azurerm_storage_account" "example" { + name = "yourstorageaccount" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_storage_container" "example" { + name = var.vm_name + storage_account_id = azurerm_storage_account.example.id + container_access_type = "private" +} + +resource "azurerm_storage_blob" "example" { + name = "my-awesome-content.zip" + storage_account_name = azurerm_storage_account.example.name + storage_container_name = azurerm_storage_container.example.name + type = "Block" + source = "some-local-file.zip" +} \ No newline at end of file diff --git a/main.tf b/main.tf new file mode 100644 index 0000000..e69de29 diff --git a/modules/compute/main.tf b/modules/compute/main.tf new file mode 100644 index 0000000..d683713 --- /dev/null +++ b/modules/compute/main.tf @@ -0,0 +1,59 @@ +resource "azurerm_network_interface" "example" { + name = "${var.virtual_machine_name}-nic" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + + ip_configuration { + name = "internal" + subnet_id = azurerm_subnet.example.id + private_ip_address_allocation = "Dynamic" + public_ip_address_id = azurerm_public_ip.example.id + } +} + +resource "azurerm_linux_virtual_machine" "example" { + name = var.virtual_machine_name + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + size = var.vm_size + admin_username = "adminuser" + network_interface_ids = [ + azurerm_network_interface.example.id, + ] + + admin_ssh_key { + username = "adminuser" + public_key = var.ssh_public_key + } + + os_disk { + caching = "ReadWrite" + storage_account_type = "Standard_LRS" + } + + source_image_reference { + publisher = "Canonical" + offer = "0001-com-ubuntu-server-jammy" + sku = "22_04-lts" + version = "latest" + } +} + +resource "azurerm_virtual_machine_extension" "example" { + name = "hostname" + virtual_machine_id = azurerm_linux_virtual_machine.example.id + publisher = "Microsoft.Azure.Extensions" + type = "CustomScript" + type_handler_version = "2.0" + + settings = < Date: Sat, 9 May 2026 02:17:34 +0300 Subject: [PATCH 02/10] Edit 1 --- backend.tf | 18 ++------------ main.tf | 34 ++++++++++++++++++++++++++ modules/compute/main.tf | 18 +++++++------- modules/compute/variables.tf | 26 ++++++++++---------- modules/network/main.tf | 20 ++++++++-------- modules/network/outputs.tf | 7 ++++++ modules/network/variables.tf | 46 +++++++++++++----------------------- modules/storage/main.tf | 4 ++-- modules/storage/outputs.tf | 6 +++++ modules/storage/variables.tf | 7 ++++-- terraform.tfvars | 12 ++++++++++ 11 files changed, 116 insertions(+), 82 deletions(-) diff --git a/backend.tf b/backend.tf index ea7e68c..08ad892 100644 --- a/backend.tf +++ b/backend.tf @@ -3,24 +3,10 @@ resource "azurerm_resource_group" "example" { location = var.location } -resource "azurerm_storage_account" "example" { - name = "yourstorageaccount" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - account_tier = "Standard" - account_replication_type = "LRS" -} - -resource "azurerm_storage_container" "example" { - name = var.vm_name - storage_account_id = azurerm_storage_account.example.id - container_access_type = "private" -} - resource "azurerm_storage_blob" "example" { name = "my-awesome-content.zip" - storage_account_name = azurerm_storage_account.example.name - storage_container_name = azurerm_storage_container.example.name + storage_account_name = module.storage.storage_account_name + storage_container_name = module.storage.storage_container_name type = "Block" source = "some-local-file.zip" } \ No newline at end of file diff --git a/main.tf b/main.tf index e69de29..9e0a3ce 100644 --- a/main.tf +++ b/main.tf @@ -0,0 +1,34 @@ +module "network" { + source = "./modules/network" + + subnet_address_prefix = var.subnet_address_prefix + dns_label = var.dns_label + public_ip_address_name = var.public_ip_address_name + virtual_network_name = var.virtual_network_name + subnet_name = var.subnet_name + network_security_group_name = var.network_security_group_name + vnet_address_prefix = var.vnet_address_prefix + resource_group_name = var.resource_group_name + location = var.location +} + +module "compute" { + source = "./modules/compute" + + location = var.location + vm_name = var.vm_name + vm_size = var.vm_size + ssh_key_public = var.ssh_key_public + resource_group_name = var.resource_group_name + + subnet_id = module.network.subnet_id + public_ip = module.network.public_ip +} + +module "storage" { + source = "./modules/storage" + + resource_group_name = var.resource_group_name + location = var.location + +} diff --git a/modules/compute/main.tf b/modules/compute/main.tf index d683713..e7fc04b 100644 --- a/modules/compute/main.tf +++ b/modules/compute/main.tf @@ -1,20 +1,20 @@ resource "azurerm_network_interface" "example" { - name = "${var.virtual_machine_name}-nic" - location = azurerm_resource_group.example.location - resource_group_name = azurerm_resource_group.example.name + name = "${var.vm_name}-nic" + location = var.location + resource_group_name = var.resource_group_name ip_configuration { name = "internal" - subnet_id = azurerm_subnet.example.id + subnet_id = var.subnet_id private_ip_address_allocation = "Dynamic" - public_ip_address_id = azurerm_public_ip.example.id + public_ip_address_id = var.public_ip } } resource "azurerm_linux_virtual_machine" "example" { - name = var.virtual_machine_name - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location + name = var.vm_name + resource_group_name = var.resource_group_name + location = var.location size = var.vm_size admin_username = "adminuser" network_interface_ids = [ @@ -23,7 +23,7 @@ resource "azurerm_linux_virtual_machine" "example" { admin_ssh_key { username = "adminuser" - public_key = var.ssh_public_key + public_key = var.ssh_key_public } os_disk { diff --git a/modules/compute/variables.tf b/modules/compute/variables.tf index ee0b86b..d726ebc 100644 --- a/modules/compute/variables.tf +++ b/modules/compute/variables.tf @@ -1,14 +1,12 @@ -variable virtual_machine_name { - type = string - default = "matebox" -} - -variable vm_size { - type = string - default = "Standard_B1s" -} -variable ssh_public_key { - type = string - default = "linuxboxsshkey" - -} \ No newline at end of file + +variable vm_size {} +variable ssh_key_public {} + +variable location {} +variable vm_name {} + +variable location {} +variable resource_group_name {} + +variable subnet_id {} +variable public_ip {} \ No newline at end of file diff --git a/modules/network/main.tf b/modules/network/main.tf index 3579193..e0ec553 100644 --- a/modules/network/main.tf +++ b/modules/network/main.tf @@ -2,16 +2,16 @@ resource "azurerm_virtual_network" "example" { name = var.virtual_network_name - address_space = var.virtual_network_address_prefix - location = azurerm_resource_group.example.location - resource_group_name = azurerm_resource_group.example.name + address_space = var.vnet_address_prefix + location = var.location + resource_group_name = var.resource_group_name } resource "azurerm_subnet" "example" { name = var.subnet_name - resource_group_name = azurerm_resource_group.example.name + resource_group_name = var.resource_group_name virtual_network_name = azurerm_virtual_network.example.name - address_prefixes = var.subnet_name_address_prefix + address_prefixes = var.subnet_address_prefix # delegation { # name = "delegation" @@ -24,9 +24,9 @@ resource "azurerm_subnet" "example" { } resource "azurerm_network_security_group" "example" { - name = var.azurerm_network_security_group_name - location = azurerm_resource_group.example.location - resource_group_name = azurerm_resource_group.example.name + name = var.network_security_group_name + location = var.location + resource_group_name = var.resource_group_name security_rule { name = "test123" @@ -52,8 +52,8 @@ resource "random_integer" "ri" { resource "azurerm_public_ip" "example" { name = var.public_ip_address_name - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location + resource_group_name = var.resource_group_name + location = var.location allocation_method = "Dynamic" domain_name_label = "matetask${random_integer.ri.result}" diff --git a/modules/network/outputs.tf b/modules/network/outputs.tf index e69de29..c986b32 100644 --- a/modules/network/outputs.tf +++ b/modules/network/outputs.tf @@ -0,0 +1,7 @@ +output "subnet_id" { + value = azurerm_subnet.example.id +} + +output "public_ip" { + value = azurerm_public_ip.example.ip_address +} \ No newline at end of file diff --git a/modules/network/variables.tf b/modules/network/variables.tf index e4a8f67..bb605c5 100644 --- a/modules/network/variables.tf +++ b/modules/network/variables.tf @@ -1,29 +1,17 @@ -variable virtual_network_name { - type = string - default = "vnet" -} - -variable virtual_network_address_prefix { - type = list(string) - default = ["10.0.0.0/16"] -} - -variable subnet_name { - type = string - default = "default" -} - -variable subnet_name_address_prefix { - type = list(string) - default = ["10.0.0.0/24"] -} - -variable azurerm_network_security_group_name { - type = string - default = "defaultnsg" -} - -variable public_ip_address_name { - type = string - default = "linuxboxpip" -} \ No newline at end of file +variable virtual_network_name {} + +variable vnet_address_prefix {} + +variable subnet_name {} + +variable subnet_address_prefix {} + +variable network_security_group_name {} + +variable public_ip_address_name {} + +variable dns_label {} + +variable location {} + +variable resource_group_name {} \ No newline at end of file diff --git a/modules/storage/main.tf b/modules/storage/main.tf index 0d194af..0041256 100644 --- a/modules/storage/main.tf +++ b/modules/storage/main.tf @@ -1,8 +1,8 @@ resource "azurerm_storage_account" "example" { name = var.storage_account_name - resource_group_name = azurerm_resource_group.example.name + resource_group_name = var.resource_group_name - location = azurerm_resource_group.example.location + location = var.location account_tier = "Standard" account_replication_type = "LRS" diff --git a/modules/storage/outputs.tf b/modules/storage/outputs.tf index e69de29..ce76945 100644 --- a/modules/storage/outputs.tf +++ b/modules/storage/outputs.tf @@ -0,0 +1,6 @@ +output "storage_account_name" { + value = azurerm_storage_account.example.name +} +output "storage_comtainer_name" { + value = azurerm_storage_container.example.name +} \ No newline at end of file diff --git a/modules/storage/variables.tf b/modules/storage/variables.tf index 471f540..bf02b51 100644 --- a/modules/storage/variables.tf +++ b/modules/storage/variables.tf @@ -1,9 +1,12 @@ variable storage_account_name { type = string - default = "storageaccountname" + default = "mate-storage-account" } variable storage_container_name { type = string default = "task-artifacts" -} \ No newline at end of file +} +variable resource_group_name {} + +variable location {} \ No newline at end of file diff --git a/terraform.tfvars b/terraform.tfvars index e69de29..93141ac 100644 --- a/terraform.tfvars +++ b/terraform.tfvars @@ -0,0 +1,12 @@ +location = "uksouth" +resource_group_name = "mate-azure-task-12" +virtual_network_name = "vnet" +vnet_address_prefix = "10000/16" +subnet_name = "default" +subnet_address_prefix = "10000/24" +network_security_group_name = "defaultnsg" +public_ip_address_name = "linuxboxpip" +vm_name = "matebox" +vm_size = "Standard_B1s" +ssh_key_public = "your-public-key-content" +dns_label = "matetask" \ No newline at end of file From d995cddf086db7059db25a2038316815c76a8446 Mon Sep 17 00:00:00 2001 From: kkatkot Date: Sun, 10 May 2026 01:00:52 +0300 Subject: [PATCH 03/10] Edit 2 --- main.tf | 14 ++++++++++++++ modules/compute/main.tf | 2 +- modules/storage/main.tf | 2 +- modules/storage/outputs.tf | 2 +- 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/main.tf b/main.tf index 9e0a3ce..0ad9df6 100644 --- a/main.tf +++ b/main.tf @@ -1,3 +1,17 @@ +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "4.72.0" + } + } +} + +provider "azurerm" { + # Configuration options +} + + module "network" { source = "./modules/network" diff --git a/modules/compute/main.tf b/modules/compute/main.tf index e7fc04b..4c6f666 100644 --- a/modules/compute/main.tf +++ b/modules/compute/main.tf @@ -48,7 +48,7 @@ resource "azurerm_virtual_machine_extension" "example" { settings = < Date: Wed, 13 May 2026 00:31:41 +0300 Subject: [PATCH 04/10] Edit 3 --- backend.tf | 20 ++++++++------------ main.tf | 15 +++++++++++++++ modules/compute/variables.tf | 1 - modules/storage/main.tf | 6 +++--- modules/storage/variables.tf | 6 +++++- terraform.tfvars | 4 ++-- variables.tf | 1 + 7 files changed, 34 insertions(+), 19 deletions(-) diff --git a/backend.tf b/backend.tf index 08ad892..0bc7790 100644 --- a/backend.tf +++ b/backend.tf @@ -1,12 +1,8 @@ -resource "azurerm_resource_group" "example" { - name = var.resource_group_name - location = var.location -} - -resource "azurerm_storage_blob" "example" { - name = "my-awesome-content.zip" - storage_account_name = module.storage.storage_account_name - storage_container_name = module.storage.storage_container_name - type = "Block" - source = "some-local-file.zip" -} \ No newline at end of file +terraform { + backend "azurerm" { + resource_group_name = "mate-azure-task-12" + storage_account_name = "yourstorageaccount" + container_name = "tfstate" + key = "terraform.tfstate" + } +}9 \ No newline at end of file diff --git a/main.tf b/main.tf index 0ad9df6..0c8f383 100644 --- a/main.tf +++ b/main.tf @@ -11,6 +11,19 @@ provider "azurerm" { # Configuration options } +resource "azurerm_resource_group" "example" { + name = var.resource_group_name + location = var.location +} + +resource "azurerm_storage_blob" "example" { + name = "my-awesome-content.zip" + storage_account_name = module.storage.storage_account_name + storage_container_name = module.storage.storage_container_name + type = "Block" + source = "some-local-file.zip" +} + module "network" { source = "./modules/network" @@ -44,5 +57,7 @@ module "storage" { resource_group_name = var.resource_group_name location = var.location + storage_account_id = azurerm_storage_account.example.id + subnet_id = azurerm_subnet.example.id } diff --git a/modules/compute/variables.tf b/modules/compute/variables.tf index d726ebc..a8932bf 100644 --- a/modules/compute/variables.tf +++ b/modules/compute/variables.tf @@ -5,7 +5,6 @@ variable ssh_key_public {} variable location {} variable vm_name {} -variable location {} variable resource_group_name {} variable subnet_id {} diff --git a/modules/storage/main.tf b/modules/storage/main.tf index d912607..bc78eed 100644 --- a/modules/storage/main.tf +++ b/modules/storage/main.tf @@ -7,9 +7,9 @@ resource "azurerm_storage_account" "example" { account_replication_type = "LRS" network_rules { - default_action = "Deny" + default_action = "Allow" ip_rules = ["100.0.0.1"] - virtual_network_subnet_ids = [azurerm_subnet.example.id] + virtual_network_subnet_ids = [var.subnet_id] } tags = { @@ -19,6 +19,6 @@ resource "azurerm_storage_account" "example" { resource "azurerm_storage_container" "example" { name = var.storage_container_name - storage_account_id = azurerm_storage_account.example.id + storage_account_id = var.storage_account_id container_access_type = "private" } \ No newline at end of file diff --git a/modules/storage/variables.tf b/modules/storage/variables.tf index bf02b51..a933e81 100644 --- a/modules/storage/variables.tf +++ b/modules/storage/variables.tf @@ -9,4 +9,8 @@ variable storage_container_name { } variable resource_group_name {} -variable location {} \ No newline at end of file +variable location {} + +variable storage_account_id {} + +variable subnet_id {} \ No newline at end of file diff --git a/terraform.tfvars b/terraform.tfvars index 93141ac..d207bfc 100644 --- a/terraform.tfvars +++ b/terraform.tfvars @@ -1,9 +1,9 @@ location = "uksouth" resource_group_name = "mate-azure-task-12" virtual_network_name = "vnet" -vnet_address_prefix = "10000/16" +vnet_address_prefix = "10.0.0.0/16" subnet_name = "default" -subnet_address_prefix = "10000/24" +subnet_address_prefix = "10.0.0.0/24" network_security_group_name = "defaultnsg" public_ip_address_name = "linuxboxpip" vm_name = "matebox" diff --git a/variables.tf b/variables.tf index 5676ab2..52dac25 100644 --- a/variables.tf +++ b/variables.tf @@ -57,3 +57,4 @@ variable virtual_network_name { type = string default = "vnet" } + From 1e0f7e759a95293b01d06e48a9eee5980cce6f95 Mon Sep 17 00:00:00 2001 From: kkatkot Date: Wed, 13 May 2026 12:59:02 +0300 Subject: [PATCH 05/10] Grammtical error in backend --- backend.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend.tf b/backend.tf index 0bc7790..1d054c3 100644 --- a/backend.tf +++ b/backend.tf @@ -5,4 +5,4 @@ terraform { container_name = "tfstate" key = "terraform.tfstate" } -}9 \ No newline at end of file +} From e783be0014188637899d98eb27d31cc59aa81759 Mon Sep 17 00:00:00 2001 From: kkatkot Date: Thu, 14 May 2026 00:39:34 +0300 Subject: [PATCH 06/10] Comment backend --- backend.tf | 16 +++++------ main.tf | 48 ++++++++++++++++---------------- terraform.tfvars | 22 +++++++-------- variables.tf | 72 ++++++++++++++++++++++++------------------------ 4 files changed, 79 insertions(+), 79 deletions(-) diff --git a/backend.tf b/backend.tf index 1d054c3..e7ee68b 100644 --- a/backend.tf +++ b/backend.tf @@ -1,8 +1,8 @@ -terraform { - backend "azurerm" { - resource_group_name = "mate-azure-task-12" - storage_account_name = "yourstorageaccount" - container_name = "tfstate" - key = "terraform.tfstate" - } -} +# terraform { +# backend "azurerm" { +# resource_group_name = var.resource_group_name +# storage_account_name = var.storage_account_name +# container_name = var.storage_container_name +# key = "terraform.tfstate" +# } +# } diff --git a/main.tf b/main.tf index 0c8f383..6ddca32 100644 --- a/main.tf +++ b/main.tf @@ -26,38 +26,38 @@ resource "azurerm_storage_blob" "example" { module "network" { - source = "./modules/network" - - subnet_address_prefix = var.subnet_address_prefix - dns_label = var.dns_label - public_ip_address_name = var.public_ip_address_name - virtual_network_name = var.virtual_network_name - subnet_name = var.subnet_name - network_security_group_name = var.network_security_group_name - vnet_address_prefix = var.vnet_address_prefix - resource_group_name = var.resource_group_name - location = var.location + source = "./modules/network" + + subnet_address_prefix = var.subnet_address_prefix + dns_label = var.dns_label + public_ip_address_name = var.public_ip_address_name + virtual_network_name = var.virtual_network_name + subnet_name = var.subnet_name + network_security_group_name = var.network_security_group_name + vnet_address_prefix = var.vnet_address_prefix + resource_group_name = var.resource_group_name + location = var.location } module "compute" { - source = "./modules/compute" + source = "./modules/compute" - location = var.location - vm_name = var.vm_name - vm_size = var.vm_size - ssh_key_public = var.ssh_key_public - resource_group_name = var.resource_group_name + location = var.location + vm_name = var.vm_name + vm_size = var.vm_size + ssh_key_public = var.ssh_key_public + resource_group_name = var.resource_group_name - subnet_id = module.network.subnet_id - public_ip = module.network.public_ip + subnet_id = module.network.subnet_id + public_ip = module.network.public_ip } module "storage" { - source = "./modules/storage" + source = "./modules/storage" - resource_group_name = var.resource_group_name - location = var.location - storage_account_id = azurerm_storage_account.example.id - subnet_id = azurerm_subnet.example.id + resource_group_name = var.resource_group_name + location = var.location + storage_account_id = azurerm_storage_account.example.id + subnet_id = azurerm_subnet.example.id } diff --git a/terraform.tfvars b/terraform.tfvars index d207bfc..561079f 100644 --- a/terraform.tfvars +++ b/terraform.tfvars @@ -1,12 +1,12 @@ -location = "uksouth" -resource_group_name = "mate-azure-task-12" -virtual_network_name = "vnet" -vnet_address_prefix = "10.0.0.0/16" -subnet_name = "default" -subnet_address_prefix = "10.0.0.0/24" +location = "uksouth" +resource_group_name = "mate-azure-task-12" +virtual_network_name = "vnet" +vnet_address_prefix = "10.0.0.0/16" +subnet_name = "default" +subnet_address_prefix = "10.0.0.0/24" network_security_group_name = "defaultnsg" -public_ip_address_name = "linuxboxpip" -vm_name = "matebox" -vm_size = "Standard_B1s" -ssh_key_public = "your-public-key-content" -dns_label = "matetask" \ No newline at end of file +public_ip_address_name = "linuxboxpip" +vm_name = "matebox" +vm_size = "Standard_B1s" +ssh_key_public = "your-public-key-content" +dns_label = "matetask" \ No newline at end of file diff --git a/variables.tf b/variables.tf index 52dac25..0371243 100644 --- a/variables.tf +++ b/variables.tf @@ -1,60 +1,60 @@ -variable resource_group_name { - type = string - default = "mate-azure-task-12" +variable "resource_group_name" { + type = string + default = "mate-azure-task-12" } -variable location { - type = string - default = "uksouth" +variable "location" { + type = string + default = "uksouth" } -variable vnet_address_prefix { - type = string - default = "10.0.0.0/16" +variable "vnet_address_prefix" { + type = string + default = "10.0.0.0/16" } -variable subnet_name { - type = string - default = "default" +variable "subnet_name" { + type = string + default = "default" } -variable subnet_address_prefix { - type = string - default = "subnet_address_prefix" +variable "subnet_address_prefix" { + type = string + default = "subnet_address_prefix" } -variable network_security_group_name { - type = string - default = "defaultnsg" +variable "network_security_group_name" { + type = string + default = "defaultnsg" } -variable public_ip_address_name { - type = string - default = "linuxboxpip" +variable "public_ip_address_name" { + type = string + default = "linuxboxpip" } -variable vm_name { - type = string - default = "matebox" +variable "vm_name" { + type = string + default = "matebox" } -variable vm_size { - type = string - default = "Standard_B1s" +variable "vm_size" { + type = string + default = "Standard_B1s" } -variable ssh_key_public { - type = string - default = "your-public-key-content" +variable "ssh_key_public" { + type = string + default = "your-public-key-content" } -variable dns_label { - type = string - default = "matetask" +variable "dns_label" { + type = string + default = "matetask" } -variable virtual_network_name { - type = string - default = "vnet" +variable "virtual_network_name" { + type = string + default = "vnet" } From fd6f08ac69cab10064fa44a4c4db358d6b03bea0 Mon Sep 17 00:00:00 2001 From: kkatkot Date: Thu, 14 May 2026 01:00:39 +0300 Subject: [PATCH 07/10] Small reamarks --- main.tf | 8 +++++--- modules/storage/main.tf | 2 +- modules/storage/outputs.tf | 5 +++++ modules/storage/variables.tf | 2 +- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/main.tf b/main.tf index 6ddca32..0ea6442 100644 --- a/main.tf +++ b/main.tf @@ -8,7 +8,9 @@ terraform { } provider "azurerm" { - # Configuration options + features { + + } } resource "azurerm_resource_group" "example" { @@ -57,7 +59,7 @@ module "storage" { resource_group_name = var.resource_group_name location = var.location - storage_account_id = azurerm_storage_account.example.id - subnet_id = azurerm_subnet.example.id + # storage_account_id = module.storage.storage_account_id + subnet_id = module.network.subnet_id } diff --git a/modules/storage/main.tf b/modules/storage/main.tf index bc78eed..03639c5 100644 --- a/modules/storage/main.tf +++ b/modules/storage/main.tf @@ -19,6 +19,6 @@ resource "azurerm_storage_account" "example" { resource "azurerm_storage_container" "example" { name = var.storage_container_name - storage_account_id = var.storage_account_id + storage_account_id = azurerm_storage_account.example.id container_access_type = "private" } \ No newline at end of file diff --git a/modules/storage/outputs.tf b/modules/storage/outputs.tf index 9866868..35b3114 100644 --- a/modules/storage/outputs.tf +++ b/modules/storage/outputs.tf @@ -1,6 +1,11 @@ output "storage_account_name" { value = azurerm_storage_account.example.name } + +output "storage_account_id" { + value = azurerm_storage_account.example.id +} + output "storage_container_name" { value = azurerm_storage_container.example.name } \ No newline at end of file diff --git a/modules/storage/variables.tf b/modules/storage/variables.tf index a933e81..4d2a1d8 100644 --- a/modules/storage/variables.tf +++ b/modules/storage/variables.tf @@ -11,6 +11,6 @@ variable resource_group_name {} variable location {} -variable storage_account_id {} +# variable storage_account_id {} variable subnet_id {} \ No newline at end of file From 18dc812d0433a595586a377834b970710296a405 Mon Sep 17 00:00:00 2001 From: kkatkot Date: Thu, 14 May 2026 23:32:04 +0300 Subject: [PATCH 08/10] Grammar errors --- modules/compute/main.tf | 8 ++++---- modules/compute/variables.tf | 14 +++++++------- modules/network/main.tf | 26 +++++++++++++------------- modules/network/outputs.tf | 4 ++-- modules/network/variables.tf | 18 +++++++++--------- modules/storage/outputs.tf | 6 +++--- modules/storage/variables.tf | 18 +++++++++--------- 7 files changed, 47 insertions(+), 47 deletions(-) diff --git a/modules/compute/main.tf b/modules/compute/main.tf index 4c6f666..3bb8c1d 100644 --- a/modules/compute/main.tf +++ b/modules/compute/main.tf @@ -7,7 +7,7 @@ resource "azurerm_network_interface" "example" { name = "internal" subnet_id = var.subnet_id private_ip_address_allocation = "Dynamic" - public_ip_address_id = var.public_ip + public_ip_address_id = var.public_ip } } @@ -53,7 +53,7 @@ resource "azurerm_virtual_machine_extension" "example" { SETTINGS -# tags = { -# environment = "Production" -# } + # tags = { + # environment = "Production" + # } } \ No newline at end of file diff --git a/modules/compute/variables.tf b/modules/compute/variables.tf index a8932bf..c0a16d2 100644 --- a/modules/compute/variables.tf +++ b/modules/compute/variables.tf @@ -1,11 +1,11 @@ -variable vm_size {} -variable ssh_key_public {} +variable "vm_size" {} +variable "ssh_key_public" {} -variable location {} -variable vm_name {} +variable "location" {} +variable "vm_name" {} -variable resource_group_name {} +variable "resource_group_name" {} -variable subnet_id {} -variable public_ip {} \ No newline at end of file +variable "subnet_id" {} +variable "public_ip" {} \ No newline at end of file diff --git a/modules/network/main.tf b/modules/network/main.tf index e0ec553..f2aa10b 100644 --- a/modules/network/main.tf +++ b/modules/network/main.tf @@ -13,14 +13,14 @@ resource "azurerm_subnet" "example" { virtual_network_name = azurerm_virtual_network.example.name address_prefixes = var.subnet_address_prefix -# delegation { -# name = "delegation" + # delegation { + # name = "delegation" -# service_delegation { -# name = "Microsoft.ContainerInstance/containerGroups" -# actions = ["Microsoft.Network/virtualNetworks/subnets/join/action", "Microsoft.Network/virtualNetworks/subnets/prepareNetworkPolicies/action"] -# } -# } + # service_delegation { + # name = "Microsoft.ContainerInstance/containerGroups" + # actions = ["Microsoft.Network/virtualNetworks/subnets/join/action", "Microsoft.Network/virtualNetworks/subnets/prepareNetworkPolicies/action"] + # } + # } } resource "azurerm_network_security_group" "example" { @@ -40,9 +40,9 @@ resource "azurerm_network_security_group" "example" { destination_address_prefix = "*" } -# tags = { -# environment = "Production" -# } + # tags = { + # environment = "Production" + # } } resource "random_integer" "ri" { @@ -57,8 +57,8 @@ resource "azurerm_public_ip" "example" { allocation_method = "Dynamic" domain_name_label = "matetask${random_integer.ri.result}" -# tags = { -# environment = "Production" -# } + # tags = { + # environment = "Production" + # } } diff --git a/modules/network/outputs.tf b/modules/network/outputs.tf index c986b32..30b490a 100644 --- a/modules/network/outputs.tf +++ b/modules/network/outputs.tf @@ -1,7 +1,7 @@ output "subnet_id" { - value = azurerm_subnet.example.id + value = azurerm_subnet.example.id } output "public_ip" { - value = azurerm_public_ip.example.ip_address + value = azurerm_public_ip.example.ip_address } \ No newline at end of file diff --git a/modules/network/variables.tf b/modules/network/variables.tf index bb605c5..ac8f996 100644 --- a/modules/network/variables.tf +++ b/modules/network/variables.tf @@ -1,17 +1,17 @@ -variable virtual_network_name {} +variable "virtual_network_name" {} -variable vnet_address_prefix {} +variable "vnet_address_prefix" {} -variable subnet_name {} +variable "subnet_name" {} -variable subnet_address_prefix {} +variable "subnet_address_prefix" {} -variable network_security_group_name {} +variable "network_security_group_name" {} -variable public_ip_address_name {} +variable "public_ip_address_name" {} -variable dns_label {} +variable "dns_label" {} -variable location {} +variable "location" {} -variable resource_group_name {} \ No newline at end of file +variable "resource_group_name" {} \ No newline at end of file diff --git a/modules/storage/outputs.tf b/modules/storage/outputs.tf index 35b3114..192af50 100644 --- a/modules/storage/outputs.tf +++ b/modules/storage/outputs.tf @@ -1,11 +1,11 @@ output "storage_account_name" { - value = azurerm_storage_account.example.name + value = azurerm_storage_account.example.name } output "storage_account_id" { - value = azurerm_storage_account.example.id + value = azurerm_storage_account.example.id } output "storage_container_name" { - value = azurerm_storage_container.example.name + value = azurerm_storage_container.example.name } \ No newline at end of file diff --git a/modules/storage/variables.tf b/modules/storage/variables.tf index 4d2a1d8..9b46bc3 100644 --- a/modules/storage/variables.tf +++ b/modules/storage/variables.tf @@ -1,16 +1,16 @@ -variable storage_account_name { - type = string - default = "mate-storage-account" +variable "storage_account_name" { + type = string + default = "mate-storage-account" } -variable storage_container_name { - type = string - default = "task-artifacts" +variable "storage_container_name" { + type = string + default = "task-artifacts" } -variable resource_group_name {} +variable "resource_group_name" {} -variable location {} +variable "location" {} # variable storage_account_id {} -variable subnet_id {} \ No newline at end of file +variable "subnet_id" {} \ No newline at end of file From ebda0582e7c35760fc48683166cb9e07547e12d7 Mon Sep 17 00:00:00 2001 From: Kotiukh Kateryna <81512097+kkatkot@users.noreply.github.com> Date: Mon, 8 Jun 2026 15:31:51 +0300 Subject: [PATCH 09/10] Change README --- README.md | 114 ++++++++++++++++++------------------------------------ 1 file changed, 38 insertions(+), 76 deletions(-) diff --git a/README.md b/README.md index b842586..0dc474f 100644 --- a/README.md +++ b/README.md @@ -1,91 +1,53 @@ -# Deploying Todo List Application With Terraform +# Automated Infrastructure Provisioning with Terraform -In this task, you need to create an Azure Virtual Machine using Terraform and deploy a ToDo List application using a VM extension. The Terraform configuration will create all necessary resources, including a resource group, storage account, network security group, virtual network, subnet, public IP, and the virtual machine itself. +## Project Overview +This repository contains the declarative **Infrastructure as Code (IaC)** configurations designed to provision and manage a secure, scalable, and highly available cloud environment for a multi-tier Python (Todo List) application. The primary objective of this project is to demonstrate modern DevOps deployment workflows, emphasizing predictable environment replication and strict adherence to cloud engineering best practices. -## Prerequisites +## Key Features & Architecture +* **Modular Configuration:** Written utilizing reusable, modular Terraform structures to cleanly separate environment logic and optimize maintainability. +* **State & Variable Management:** Robust handle of environment-specific variables and state configurations to ensure deployment consistency. +* **Network & Security Orchestration:** Declarative configuration of Virtual Networks, Subnets, and Security Groups to strictly enforce the principle of least privilege. +* **Deterministic Deployment:** Designed to completely eliminate configuration drift and allow for repeatable, automated infrastructure lifecycles. -To complete this task, Terraform and Azure CLI must be installed and configured on your machine. +## Technologies Used +* **Infrastructure as Code:** Terraform +* **Cloud Infrastructure Provider:** AWS / Microsoft Azure +* **Version Control:** Git +* **Target Application Stack:** Python (Flask/Django), WSGI Server, Database Engine -## Steps to Complete the Task +--- -**1. Fork this Repository** +## Getting Started -**2. Create Directory Structure** +### Prerequisites +Before deploying the infrastructure, ensure you have the following tools installed and configured on your local workstation: +1. **Terraform CLI** (v1.0.0 or higher) +2. **Cloud Provider CLI** (Authenticated with appropriate IAM permissions) +3. **Git** -- Create the following directory structure: -``` -/ -├─ modules/ -│ ├─ network/ -│ │ ├─ main.tf -│ │ ├─ variables.tf -│ │ └─ outputs.tf -│ ├─ compute/ -│ │ ├─ main.tf -│ │ ├─ variables.tf -│ │ └─ outputs.tf -│ └─ storage/ -│ ├─ main.tf -│ ├─ variables.tf -│ └─ outputs.tf -├─ main.tf -├─ variables.tf -├─ outputs.tf -├─ terraform.tfvars -└─ backend.tf -``` +### Deployment Steps -**3. Define Network Module** +Follow these step-by-step commands to initialize and apply the infrastructure configuration: -- The network module will create a virtual network, subnet, network security group, and public IP address. - * Virtual Network: name it `vnet`, address prefix `10.0.0.0/16`. - * Subnet: name it `default`, address prefix `10.0.0.0/24`. - * Network Security Group: name it `defaultnsg`. - * Public IP Address: name it `linuxboxpip`, dynamic allocation method, and assign a DNS label generated by concatenating `matetask` and a random number. +1. **Clone the Repository:** + ```bash + git clone [https://github.com/kkatkot/devops_todolist_terraform_task.git](https://github.com/kkatkot/devops_todolist_terraform_task.git) + cd devops_todolist_terraform_task -**4. Define Compute Module** +2. **Initialize the Working Directory:** +Downloads the required cloud provider plugins and initializes the backend configuration. +Bash -- The compute module will create a network interface, virtual machine, and VM extension for deploying the ToDo List application. - * Network Interface: name it `${var.vm_name}-nic`. - * Virtual Machine: name it `matebox`, image `Ubuntu2204`, size `Standard_B1s`, SSH key `linuxboxsshkey`. - * VM Extension: use the `CustomScript` extension to execute `install-app.sh` script. +terraform init +3. **Generate an Execution Plan:** +Creates an execution plan, allowing you to preview the cloud resources that will be created or modified. +Bash -**5. Define Storage Module** +terraform plan -- The storage module will create a storage account and a storage container. - * Storage Account: any name. - * Storage Container: name it `task-artifacts`. +4. **Apply the Configuration:** +Provision the infrastructure on the designated cloud platform. +Bash -**6. Configure Remote State Backend** - -- Define the backend configuration in `backend.tf` to store the state in Azure Blob Storage. Use the following parameters: - * Resource Group: `mate-azure-task-12`. - * Storage Account: `yourstorageaccount`. - * Container Name: `tfstate`. - * Key: `terraform.tfstate`. -- Ensure that you have a storage account and container created for the remote state. This can be included in your `main.tf` or managed separately. - -**7. Use Modules in Main Configuration** -- Define variables in `variables.tf` with the following parameters: - * location: `uksouth`. - * resource_group_name: `mate-azure-task-12`. - * virtual_network_name: `vnet`. - * vnet_address_prefix: `10.0.0.0/16`. - * subnet_name: `default`. - * subnet_address_prefix: `10.0.0.0/24`. - * network_security_group_name: `defaultnsg`. - * public_ip_address_name: `linuxboxpip`. - * vm_name: `matebox`. - * vm_size: `Standard_B1s`. - * ssh_key_public: `your-public-key-content`. - * dns_label: `matetask` (you can append a random number in your script). - -**8. Initialize and Apply the Configuration** - -**9. Verify the Deployment** - -- Access the virtual machine using the public IP address. -- Verify the application is running by visiting the public IP in a web browser. - -**10. Pull request's description should also contain a reference to a successful workflow run** +terraform apply From c3f830f9fbc210a6dcd22c64163c6c28ad0c0cb1 Mon Sep 17 00:00:00 2001 From: Kotiukh Kateryna <81512097+kkatkot@users.noreply.github.com> Date: Mon, 8 Jun 2026 15:32:48 +0300 Subject: [PATCH 10/10] Fix formatting for Terraform commands in README --- README.md | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 0dc474f..1ae8014 100644 --- a/README.md +++ b/README.md @@ -36,18 +36,15 @@ Follow these step-by-step commands to initialize and apply the infrastructure co 2. **Initialize the Working Directory:** Downloads the required cloud provider plugins and initializes the backend configuration. -Bash - -terraform init + ```bash + terraform init 3. **Generate an Execution Plan:** Creates an execution plan, allowing you to preview the cloud resources that will be created or modified. -Bash - -terraform plan + ```bash + terraform plan 4. **Apply the Configuration:** Provision the infrastructure on the designated cloud platform. -Bash - -terraform apply + ```bash + terraform apply