Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions .idea/devops_todolist_terraform_task.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions .idea/inspectionProfiles/Project_Default.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/inspectionProfiles/profiles_settings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 40 additions & 0 deletions .terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions backend.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Configuration for the Azure Remote State Backend
# This file defines where Terraform should store its state file (terraform.tfstate)

terraform {
backend "azurerm" {
resource_group_name = "mate-azure-task-12"
storage_account_name = "yourstorageaccount"
container_name = "tfstate"
key = "terraform.tfstate"
}
}
63 changes: 63 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# 1. PROVIDERS AND RESOURCE GROUP
provider "azurerm" {
features {}
}

# Resource Group
resource "azurerm_resource_group" "main" {
name = var.resource_group_name
location = var.location
}

# Helper resource for a unique DNS label
resource "random_integer" "dns_suffix" {
min = 1000
max = 9999
}

# 2. NETWORK MODULE CALL
module "network" {
source = "./modules/network"

resource_group_name = azurerm_resource_group.main.name
location = azurerm_resource_group.main.location
virtual_network_name = var.virtual_network_name
vnet_address_prefix = var.vnet_address_prefix
subnet_name = var.subnet_name
subnet_address_prefix = var.subnet_address_prefix
network_security_group_name = var.network_security_group_name
public_ip_address_name = var.public_ip_address_name
dns_label = "${var.dns_label}-${random_integer.dns_suffix.result}"
}

# 3. STORAGE MODULE CALL
module "storage" {
# CORRECTED path based on your file structure
source = "./modules/storage"

resource_group_name = azurerm_resource_group.main.name
location = azurerm_resource_group.main.location
storage_account_name = var.storage_account_name
storage_container_name = var.storage_container_name
}

# 4. COMPUTE MODULE CALL
module "compute" {
source = "./modules/compute"

resource_group_name = azurerm_resource_group.main.name
location = azurerm_resource_group.main.location
vm_name = var.vm_name
vm_size = var.vm_size
admin_username = "azureuser"
ssh_key_public = var.ssh_key_public

subnet_id = module.network.subnet_id
public_ip_id = module.network.public_ip_id
nsg_id = module.network.nsg_id

storage_account_name = module.storage.storage_account_name
storage_container_name = module.storage.storage_container_name

script_path = "${path.root}/install-app.sh"
}
81 changes: 81 additions & 0 deletions modules/compute/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# 1. Network Interface (NIC) - name: ${var.vm_name}-nic
resource "azurerm_network_interface" "nic" {
name = "${var.vm_name}-nic"
location = var.location
resource_group_name = var.resource_group_name

ip_configuration {
name = "ipconfig"
subnet_id = var.subnet_id
private_ip_address_allocation = "Dynamic"
public_ip_address_id = var.public_ip_id
}
}

# Attach NSG to the NIC
resource "azurerm_network_interface_security_group_association" "nsg_attach" {
network_interface_id = azurerm_network_interface.nic.id
network_security_group_id = var.nsg_id
}

# 2. Virtual Machine (VM) - name: matebox, size: Standard_B1s, image: Ubuntu
resource "azurerm_linux_virtual_machine" "vm" {
name = var.vm_name
location = var.location
resource_group_name = var.resource_group_name
size = var.vm_size
network_interface_ids = [azurerm_network_interface.nic.id]

# Using Ubuntu 20.04 LTS (stable choice for extensions)
source_image_reference {
publisher = "Canonical"
offer = "0001-com-ubuntu-server-jammy" # Offer for Ubuntu 22.04
sku = "22_04-lts"
version = "latest"
}

os_disk {
caching = "ReadWrite"
storage_account_type = "Standard_LRS"
}

admin_username = var.admin_username
disable_password_authentication = true

admin_ssh_key {
username = var.admin_username
public_key = var.ssh_key_public # linuxboxsshkey
}
}

# 3. Upload install-app.sh to Storage Blob
# The CustomScript extension requires a URI to download the file.
resource "azurerm_storage_blob" "app_script" {
name = "install-app.sh"
storage_account_name = var.storage_account_name
storage_container_name = var.storage_container_name
type = "Block"
source = var.script_path # Path to local install-app.sh
content_type = "text/plain"
}

# 4. VM Extension (CustomScript) to execute install-app.sh
resource "azurerm_virtual_machine_extension" "custom_script_deploy" {
name = "custom-script-deploy"
virtual_machine_id = azurerm_linux_virtual_machine.vm.id
publisher = "Microsoft.Azure.Extensions"
type = "CustomScript"
type_handler_version = "2.1"
auto_upgrade_minor_version = true

# The CustomScript settings: defines the file to download and the command to run.
settings = jsonencode({
fileUris = [
"${azurerm_storage_blob.app_script.url}" # Direct URL to the uploaded blob
]
commandToExecute = "chmod +x install-app.sh && ./install-app.sh"
})

# Ensure the blob is uploaded before the extension runs
depends_on = [azurerm_storage_blob.app_script]
}
8 changes: 8 additions & 0 deletions modules/compute/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
output "vm_id" {
description = "The ID of the Virtual Machine."
value = azurerm_linux_virtual_machine.vm.id
}
output "nic_id" {
description = "The ID of the Network Interface."
value = azurerm_network_interface.nic.id
}
52 changes: 52 additions & 0 deletions modules/compute/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
variable "resource_group_name" {
description = "The name of the Azure resource group."
type = string
}
variable "location" {
description = "The Azure region for deployment."
type = string
}
variable "vm_name" {
description = "The name of the Virtual Machine (matebox)."
type = string
}
variable "vm_size" {
description = "The size of the VM (Standard_B1s)."
type = string
}
variable "admin_username" {
description = "The admin username for the VM."
type = string
}
variable "ssh_key_public" {
description = "The public SSH key content for authentication."
type = string
}

# Inputs from the Network Module
variable "subnet_id" {
description = "The ID of the Subnet to attach the NIC to."
type = string
}
variable "public_ip_id" {
description = "The ID of the Public IP to attach to the NIC."
type = string
}
variable "nsg_id" {
description = "The ID of the NSG to attach to the NIC."
type = string
}

# Inputs from the Storage Module (for CustomScript file transfer)
variable "storage_account_name" {
description = "The name of the Storage Account."
type = string
}
variable "storage_container_name" {
description = "The name of the Storage Container."
type = string
}
variable "script_path" {
description = "The local path to the install-app.sh script."
type = string
}
57 changes: 57 additions & 0 deletions modules/network/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# 1. Virtual Network (vnet)
resource "azurerm_virtual_network" "vnet" {
name = var.virtual_network_name
location = var.location
resource_group_name = var.resource_group_name
address_space = [var.vnet_address_prefix]
}

# 2. Subnet (default)
resource "azurerm_subnet" "subnet" {
name = var.subnet_name
resource_group_name = var.resource_group_name
virtual_network_name = azurerm_virtual_network.vnet.name
address_prefixes = [var.subnet_address_prefix]
}

# 3. Public IP Address (linuxboxpip)
resource "azurerm_public_ip" "pip" {
name = var.public_ip_address_name
location = var.location
resource_group_name = var.resource_group_name
allocation_method = "Dynamic"
domain_name_label = var.dns_label # matetask + random number
}

# 4. Network Security Group (defaultnsg)
resource "azurerm_network_security_group" "nsg" {
name = var.network_security_group_name
location = var.location
resource_group_name = var.resource_group_name

# Allow SSH (Port 22)
security_rule {
name = "SSH_Allow"
priority = 100
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "22"
source_address_prefix = "Internet"
destination_address_prefix = "*"
}

# Allow HTTP (Port 80) for the ToDo App
security_rule {
name = "HTTP_Allow"
priority = 101
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "80"
source_address_prefix = "Internet"
destination_address_prefix = "*"
}
}
Loading