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
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.terraform/
*.tfstate
*.tfstate.*

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Backend config must match checklist item #9: use mate-azure-task-12 as resource_group_name and yourstorageaccount as storage_account_name, with container tfstate and key terraform.tfstate. The current values (tfstate-rg, tfstate2426127369) do not comply.

.terraform.tfstate.lock.info

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The task requires location to be uksouth (checklist #16); your default is denmarkeast, which does not match the specification.

crash.log
crash.*.log
*.tfplan
override.tf
override.tf.json
*_override.tf
*_override.tf.json
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 = "mate-azure-task-12"
storage_account_name = "yourstorageaccount"
container_name = "tfstate"
key = "terraform.tfstate"
}
}
10 changes: 6 additions & 4 deletions install-app.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@
# used to suppress any interactive prompts - we won't be able to confirm operation
# when running the script as VM extention.
apt-get update -yq
apt-get install python3-pip -yq
apt-get install python3-pip git -yq

# Create a directory for the app and download the files.
mkdir /app
mkdir -p /app
cd /tmp
# make sure to uncomment the line bellow and update the link with your GitHub username
# git clone https://github.com/<your-gh-username>/azure_task_12_deploy_app_with_vm_extention.git
cp -r devops_todolist_terraform_task/app/* /app
git clone https://github.com/volodymyrlp/devops_todolist_terraform_task.git
cp -r /tmp/devops_todolist_terraform_task/app/* /app
chmod +x /app/start.sh

# create a service for the app via systemctl and start the app
mv /app/todoapp.service /etc/systemd/system/
Expand Down
58 changes: 58 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
terraform {
required_providers {
Comment on lines +1 to +2

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIC naming via ${var.vm_name}-nic satisfies the requirement that the network interface be named ${var.vm_name}-nic (checklist #36), so this part is fine.

azurerm = {
source = "hashicorp/azurerm"
version = "~> 4.0"
}
random = {
source = "hashicorp/random"
version = "~> 3.0"
}
}
}

provider "azurerm" {
features {}
}

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

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
}
Comment on lines +32 to +35

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The VM is using Ubuntu 22.04 via Jammy LTS image, which is correct in practice, but the checklist calls for image Ubuntu2204. If the validation is strict, you might need to ensure your configuration matches the expected label or document the mapping from Ubuntu2204 to this Canonical image.


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

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

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

resource_group_name = azurerm_resource_group.main.name
location = azurerm_resource_group.main.location
Comment on lines +40 to +49

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The VM extension correctly uses the CustomScript extension and executes install-app.sh, which meets the requirement to deploy the ToDo app via a VM extension (checklist #3 and #38). Just ensure the script URL and contents match your forked repo as required elsewhere.

vm_name = var.vm_name
vm_size = var.vm_size
admin_username = var.admin_username
ssh_key_public = var.ssh_key_public
install_script_url = var.install_script_url

subnet_id = module.network.subnet_id
public_ip_id = module.network.public_ip_id
}
51 changes: 51 additions & 0 deletions modules/compute/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
resource "azurerm_network_interface" "nic" {
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
}
}

resource "azurerm_linux_virtual_machine" "vm" {
name = var.vm_name
resource_group_name = var.resource_group_name
location = var.location
size = var.vm_size
admin_username = var.admin_username
network_interface_ids = [azurerm_network_interface.nic.id]

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The task description and checklist refer to a variable ssh_key_public and an SSH key named linuxboxsshkey. Here you use ssh_public_key instead, which is a naming mismatch. Consider renaming this variable to ssh_key_public and aligning with the required SSH key name.

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" "app" {
name = "install-app"
virtual_machine_id = azurerm_linux_virtual_machine.vm.id
publisher = "Microsoft.Azure.Extensions"
type = "CustomScript"
type_handler_version = "2.1"

settings = jsonencode({
fileUris = [var.install_script_url]
commandToExecute = "bash install-app.sh"
Comment on lines +40 to +49

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The VM extension correctly uses the CustomScript type and executes install-app.sh, which satisfies the requirement to deploy the ToDo app via a VM extension (checklist #3 and #38). Just ensure the script URL actually points to the raw install-app.sh file in your fork.

})
}
9 changes: 9 additions & 0 deletions modules/compute/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
output "vm_name" {
description = "Name of the virtual machine"
value = azurerm_linux_virtual_machine.vm.name
}

output "vm_id" {
description = "Resource ID of the virtual machine"
value = azurerm_linux_virtual_machine.vm.id
}
44 changes: 44 additions & 0 deletions modules/compute/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
variable "resource_group_name" {
description = "Name of the resource group for the compute resources"
type = string
}

variable "location" {
description = "Azure region"
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 "admin_username" {
description = "Admin username for the virtual machine"
type = string
}

variable "ssh_key_public" {
description = "SSH public key used for VM authentication"
type = string
}

variable "subnet_id" {
description = "ID of the subnet the network interface attaches to"
type = string
}

Comment on lines +32 to +35

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The VM image is clearly Ubuntu 22.04 (Jammy), but the checklist specifies Ubuntu2204 as the image. If the evaluation expects that exact label, you may need to adjust the image reference or at least confirm that this mapping is acceptable.

variable "public_ip_id" {
description = "ID of the public IP attached to the network interface"
type = string
}

variable "install_script_url" {
description = "Raw GitHub URL of install-app.sh for the VM extension"
type = string
}
61 changes: 61 additions & 0 deletions modules/network/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
resource "azurerm_virtual_network" "vnet" {
name = var.virtual_network_name
address_space = [var.vnet_address_prefix]
location = var.location
resource_group_name = var.resource_group_name
}

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 = "AllowSSH"
priority = 1001
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "22"
source_address_prefix = "*"
destination_address_prefix = "*"
}

security_rule {
name = "AllowAppHttp"
priority = 1002
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "8080"
source_address_prefix = "*"
destination_address_prefix = "*"
}
}

resource "azurerm_subnet_network_security_group_association" "subnet_nsg" {
subnet_id = azurerm_subnet.subnet.id
network_security_group_id = azurerm_network_security_group.nsg.id
}

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

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.dns.result}"
}
14 changes: 14 additions & 0 deletions modules/network/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
output "subnet_id" {
description = "ID of the subnet (used by the network interface in the compute module)"
value = azurerm_subnet.subnet.id
}

output "public_ip_id" {
description = "ID of the public IP (attached to the network interface in the compute module)"
value = azurerm_public_ip.pip.id
}

output "public_ip_fqdn" {
description = "Full DNS name of the public IP (used to open the app in a browser)"
value = azurerm_public_ip.pip.fqdn
}
44 changes: 44 additions & 0 deletions modules/network/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
variable "resource_group_name" {
description = "Name of the resource group for the network resources"
type = string
}

variable "location" {
description = "Azure region (e.g. westeurope)"
type = string
}

variable "virtual_network_name" {
description = "Name of the virtual network"
type = string
}

variable "vnet_address_prefix" {
description = "Address space of the virtual network in CIDR format (e.g. 10.0.0.0/16)"
type = string
}

variable "subnet_name" {
description = "Name of the subnet"
type = string
}

variable "subnet_address_prefix" {
description = "Address range of the subnet in CIDR format (e.g. 10.0.0.0/24)"
type = string
}

variable "network_security_group_name" {
description = "Name of the network security group (NSG)"
type = string
}

variable "public_ip_address_name" {
description = "Name of the public IP resource"
type = string
}

variable "dns_label" {
description = "DNS label prefix for the public IP (a random number is appended)"
type = string
}
19 changes: 19 additions & 0 deletions modules/storage/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
resource "random_string" "storage" {
length = 6
upper = false
special = false
}

resource "azurerm_storage_account" "storage" {
name = "${var.storage_account_name}${random_string.storage.result}"
resource_group_name = var.resource_group_name
location = var.location
account_tier = "Standard"
account_replication_type = "LRS"
}

resource "azurerm_storage_container" "container" {
name = "task-artifacts"
storage_account_id = azurerm_storage_account.storage.id
container_access_type = "private"
}
Loading
Loading