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
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.terraform/
*.tfstate
*.tfstate.*
terraform.tfvars
override.tf
override.tf.json
crash.log
43 changes: 43 additions & 0 deletions .terraform.lock.hcl

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

8 changes: 8 additions & 0 deletions backend.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
terraform {
backend "azurerm" {
resource_group_name = "tfstate"
storage_account_name = "terra5"
container_name = "tfstate"
key = "terraform.tfstate"
}
}
80 changes: 80 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
terraform {
required_version = ">= 1.5.0, < 2.0.0"

required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.75"
}
random = {
source = "hashicorp/random"
version = "~> 3.5"
}
}
}

provider "azurerm" {
features {}
subscription_id = var.subscription_id
}

resource "random_integer" "dns_suffix" {
min = 1000
max = 9999
}

locals {
dns_label = "${var.dns_label}${random_integer.dns_suffix.result}"

common_tags = merge(
{
environment = var.environment
project = var.resource_group_name
managed_by = "terraform"
},
var.tags
)
}

resource "azurerm_resource_group" "rg" {
name = var.resource_group_name
location = var.location
tags = local.common_tags
}

module "network" {
source = "./modules/network"

resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
virtual_network_name = var.virtual_network_name
vnet_address_prefix = var.vnet_address_prefix # fixed: was [var.vnet_address_prefix]
subnet_name = var.subnet_name
subnet_address_prefix = var.subnet_address_prefix # fixed: was [var.subnet_address_prefix]
network_security_group_name = var.network_security_group_name
public_ip_address_name = var.public_ip_address_name
dns_label = local.dns_label # fixed: now globally unique
}

module "storage" {
source = "./modules/storage"

resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
storage_account_name = var.storage_account_name # fixed: matched to variable name below
storage_container_name = var.storage_container_name # fixed: matched to variable name below
}

module "compute" {
source = "./modules/compute"

resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
vm_name = var.vm_name
vm_size = var.vm_size
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
script_url = module.storage.script_url
}
70 changes: 70 additions & 0 deletions modules/compute/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Creates the Network Interface for the VM and associates the NSG.
resource "azurerm_network_interface" "main" {
name = "${var.vm_name}-nic"
location = var.location
resource_group_name = var.resource_group_name

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

# Associates the Network Security Group with the Network Interface.
resource "azurerm_network_interface_security_group_association" "main" {
network_interface_id = azurerm_network_interface.main.id
network_security_group_id = var.nsg_id
}

# Creates the SSH public key resource as required by the task.
resource "azurerm_ssh_public_key" "main" {
name = "linuxboxsshkey"
resource_group_name = var.resource_group_name
location = var.location
public_key = var.ssh_key_public
}

# Creates the Linux Virtual Machine.
resource "azurerm_linux_virtual_machine" "main" {
name = var.vm_name
resource_group_name = var.resource_group_name
location = var.location
size = var.vm_size
admin_username = "azureuser"
network_interface_ids = [azurerm_network_interface.main.id]

admin_ssh_key {
username = "azureuser"
public_key = azurerm_ssh_public_key.main.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"
}
}

# Creates the VM extension to download and execute the installation script.
resource "azurerm_virtual_machine_extension" "main" {
name = "${var.vm_name}-install-app"
virtual_machine_id = azurerm_linux_virtual_machine.main.id
publisher = "Microsoft.Azure.Extensions"
type = "CustomScript"
type_handler_version = "2.0"

settings = <<SETTINGS
{
"fileUris": ["${var.script_url}"],
"commandToExecute": "bash install-app.sh"
}
SETTINGS
}
22 changes: 22 additions & 0 deletions modules/compute/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
output "vm_id" {
value = azurerm_linux_virtual_machine.main.id
description = "The ID of the virtual machine."
}

# Corrected the value to get the private IP from the IP configuration.
output "vm_private_ip" {
value = azurerm_network_interface.main.ip_configuration[0].private_ip_address
description = "The private IP address of the virtual machine."
}

# Added public IP output for easier verification.
output "vm_public_ip" {
value = azurerm_network_interface.main.ip_configuration[0].public_ip_address_id != null ? data.azurerm_public_ip.vm_pip.ip_address : ""
description = "The public IP address of the virtual machine."
}

data "azurerm_public_ip" "vm_pip" {
name = split("/", azurerm_network_interface.main.ip_configuration[0].public_ip_address_id)[8]
resource_group_name = var.resource_group_name
depends_on = [azurerm_linux_virtual_machine.main]
}
46 changes: 46 additions & 0 deletions modules/compute/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
variable "resource_group_name" {
description = "Name of the resource group"
type = string
}

variable "location" {
description = "Azure region for resources"
type = string
}

variable "vm_name" {
description = "Name of the virtual machine"
type = string
}

variable "vm_size" {
description = "Size of the virtual machine"
type = string
}

variable "ssh_key_public" {
description = "Public SSH key for the virtual machine"
type = string
sensitive = true
}

variable "subnet_id" {
description = "ID of the subnet to connect the VM to"
type = string
}

variable "public_ip_id" {
description = "ID of the public IP address to associate with the VM"
type = string
}

# Added variable for the Network Security Group ID.
variable "nsg_id" {
description = "ID of the Network Security Group to associate with the NIC"
type = string
}

variable "script_url" {
description = "URL of the script to execute on the VM"
type = string
}
59 changes: 59 additions & 0 deletions modules/network/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
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
}

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
}

resource "azurerm_network_security_group" "nsg" {
name = var.network_security_group_name
location = var.location
resource_group_name = var.resource_group_name

security_rule {
name = "SSH"
priority = 1001
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "22"
source_address_prefix = "*"
destination_address_prefix = "*"
}
security_rule {
name = "HTTP"
priority = 1002
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "80"
source_address_prefix = "*"
destination_address_prefix = "*"
}
}

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}${random_integer.r.result}"

tags = {
environment = "dev"
}
}

resource "random_integer" "r" {
min = 10000
max = 99999
}
29 changes: 29 additions & 0 deletions modules/network/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# The subnet ID.
output "subnet_id" {
description = "The ID of the subnet."
value = azurerm_subnet.subnet.id
}

# The Public IP Address ID. Required for NIC association.
output "public_ip_id" {
description = "The ID of the Public IP Address."
value = azurerm_public_ip.pip.id
}

# The Network Security Group ID. Required for NIC association.
output "nsg_id" {
description = "The ID of the Network Security Group."
value = azurerm_network_security_group.nsg.id
}

# The Public IP address of the Linux VM.
output "public_ip_address" {
description = "The Public IP Address of the Linux VM."
value = azurerm_public_ip.pip.ip_address
}

# The FQDN of the Public IP Address.
output "public_ip_fqdn" {
description = "The FQDN of the Public IP Address."
value = azurerm_public_ip.pip.fqdn
}
Loading
Loading