Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Solution #10

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.terraform
.terraform.lock*
4 changes: 2 additions & 2 deletions app/todoapp.service
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
Description=todoapp service

[Service]
WorkingDirectory=/app
ExecStart=/app/start.sh
WorkingDirectory=/home/azureuser/app
ExecStart=/home/azureuser/app/start.sh
StandardOutput=syslog
StandardError=syslog

Expand Down
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 = "storagemodulesouth"
container_name = "tfstate"
key = "terraform.tfstate"
}
}
22 changes: 14 additions & 8 deletions install-app.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,23 @@
# install system updates and isntall python3-pip package using apt. '-yq' flags are
# 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
sudo apt-get update -yq
sudo apt-get install python3-pip -yq

# Create a directory for the app and download the files.
mkdir /app
sudo mkdir /home/azureuser/app

sudo chown -R azureuser:azureuser /home/azureuser/devops_todolist_terraform_task
sudo chown -R azureuser:azureuser /home/azureuser/app

# 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
cp -r /home/azureuser/devops_todolist_terraform_task/app/* /home/azureuser/app
chmod +x /home/azureuser/app/start.sh

# create a service for the app via systemctl and start the app
mv /app/todoapp.service /etc/systemd/system/
systemctl daemon-reload
systemctl start todoapp
systemctl enable todoapp
sudo mv /home/azureuser/app/todoapp.service /etc/systemd/system/
sudo chmod 644 /etc/systemd/system/todoapp.service
sudo systemctl daemon-reload
sudo systemctl start todoapp
sudo systemctl enable todoapp
78 changes: 78 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "3.105.0"
}
}
}

provider "azurerm" {
features {}
subscription_id = "d345fa5d-4fda-4d1e-abf1-c8a7e4fb0576"
tenant_id = "e84abfc3-c8c5-4892-8f6d-942a64e5bfc4"
}

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

module "network" {
source = "./modules/network"
location = var.location
resource_group_name = azurerm_resource_group.main.name
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
dns_label = var.dns_label
}

module "compute" {
source = "./modules/compute"
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name
vm_name = var.vm_name
vm_size = var.vm_size
subnet_id = module.network.subnet_id
public_ip_address_id = module.network.public_ip_address_id
ssh_key_public = var.ssh_key_public
ssh_key_private = var.ssh_key_private
}

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
storage_container_name = var.storage_container_name
source_file_path = var.source_file_path
}

resource "null_resource" "clone_git_repo" {
provisioner "remote-exec" {
inline = [
"sudo apt-get update",
"sudo apt-get install -y git",
# Check if the directory exists
"if [ ! -d /home/azureuser/devops_todolist_terraform_task ]; then",
" sudo git clone https://github.com/Serveladik/devops_todolist_terraform_task /home/azureuser/devops_todolist_terraform_task",
"else",
" echo 'Directory /home/azureuser/devops_todolist_terraform_task already exists. Skipping clone operation.'",
" # Optionally, you can update the existing repository if needed",
" cd /home/azureuser/devops_todolist_terraform_task && sudo git pull",
"fi"
]

connection {
type = "ssh"
user = "azureuser"
private_key = file(var.ssh_key_public)
host = module.network.public_ip_address
}
}
depends_on = [module.compute]
}

56 changes: 56 additions & 0 deletions modules/compute/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
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_address_id
}
}

resource "azurerm_linux_virtual_machine" "vm" {
name = var.vm_name
resource_group_name = var.resource_group_name
location = var.location
size = "Standard_B1s"
admin_username = "azureuser"
network_interface_ids = [
azurerm_network_interface.nic.id,
]
admin_ssh_key {
username = "azureuser"
public_key = file(var.ssh_key_public)
}
os_disk {
caching = "ReadWrite"
storage_account_type = "Standard_LRS"
disk_size_gb = 30
}
source_image_reference {
publisher = "Canonical"
offer = "0001-com-ubuntu-server-jammy"
sku = "22_04-lts"
version = "latest"
}
}

resource "azurerm_virtual_machine_extension" "custom_script" {
name = "install-app"
virtual_machine_id = azurerm_linux_virtual_machine.vm.id
publisher = "Microsoft.Azure.Extensions"
type = "CustomScript"
type_handler_version = "2.1"

settings = <<SETTINGS
{
"fileUris": ["https://raw.githubusercontent.com/Serveladik/devops_todolist_terraform_task/main/install-app.sh"],
"commandToExecute": "bash install-app.sh"
}
SETTINGS

tags = {
environment = "Production"
}
}
3 changes: 3 additions & 0 deletions modules/compute/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
output "vm_id" {
value = azurerm_linux_virtual_machine.vm.id
}
31 changes: 31 additions & 0 deletions modules/compute/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
variable "location" {
type = string
}

variable "resource_group_name" {
type = string
}

variable "vm_name" {
type = string
}

variable "vm_size" {
type = string
}

variable "subnet_id" {
type = string
}

variable "public_ip_address_id" {
type = string
}

variable "ssh_key_private" {
type = string
}

variable "ssh_key_public" {
type = string
}
44 changes: 44 additions & 0 deletions modules/network/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
resource "azurerm_virtual_network" "vnet" {
name = "vnet"
address_space = ["10.0.0.0/16"]
location = var.location
resource_group_name = var.resource_group_name
}

resource "azurerm_subnet" "subnet" {
name = "default"
resource_group_name = var.resource_group_name
virtual_network_name = azurerm_virtual_network.vnet.name
address_prefixes = ["10.0.0.0/24"]
}

resource "azurerm_network_security_group" "defaultnsg" {
name = "defaultnsg"
location = var.location
resource_group_name = var.resource_group_name

security_rule {
name = "nsgsecuritygroup"
priority = 100
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "*"
source_address_prefix = "*"
destination_address_prefix = "*"
}
}

resource "azurerm_public_ip" "linuxboxpip" {
name = "linuxboxpip"
resource_group_name = var.resource_group_name
location = var.location
allocation_method = "Dynamic"
sku = "Basic"
domain_name_label = "${var.dns_label}${random_id.random_id.hex}"
}

resource "random_id" "random_id" {
byte_length = 2
}
15 changes: 15 additions & 0 deletions modules/network/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
output "subnet_id" {
value = azurerm_subnet.subnet.id
}

output "public_ip_address" {
value = azurerm_public_ip.linuxboxpip.ip_address
}

output "public_ip_address_id" {
value = azurerm_public_ip.linuxboxpip.id
}

output "virtual_network" {
value = azurerm_virtual_network.vnet
}
31 changes: 31 additions & 0 deletions modules/network/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
variable "location" {
type = string
}

variable "resource_group_name" {
type = string
}

variable "virtual_network_name" {
type = string
}

variable "vnet_address_prefix" {
type = string
}

variable "subnet_name" {
type = string
}

variable "subnet_address_prefix" {
type = string
}

variable "network_security_group_name" {
type = string
}

variable "dns_label" {
type = string
}
13 changes: 13 additions & 0 deletions modules/storage/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
resource "azurerm_storage_account" "storage" {
name = var.storage_account_name
resource_group_name = var.resource_group_name
location = var.location
account_tier = "Standard"
account_replication_type = "LRS"
}

resource "azurerm_storage_container" "taskartifacts" {
name = "task-artifacts"
storage_account_name = azurerm_storage_account.storage.name
container_access_type = "private"
}
7 changes: 7 additions & 0 deletions modules/storage/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
output "storage_account_name" {
value = azurerm_storage_account.storage.name
}

output "storage_container_name" {
value = azurerm_storage_container.taskartifacts.name
}
19 changes: 19 additions & 0 deletions modules/storage/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
variable "resource_group_name" {
type = string
}

variable "location" {
type = string
}

variable "storage_account_name" {
type = string
}

variable "storage_container_name" {
type = string
}

variable "source_file_path" {
type = string
}
27 changes: 27 additions & 0 deletions outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
output "resource_group_name" {
value = azurerm_resource_group.main.name
}

output "storage_account_name" {
value = module.storage.storage_account_name
}

output "storage_container_name" {
value = module.storage.storage_container_name
}

output "virtual_network_name" {
value = module.network.virtual_network.name
}

output "subnet_id" {
value = module.network.subnet_id
}

output "public_ip_address" {
value = module.network.public_ip_address
}

output "vm_id" {
value = module.compute.vm_id
}
2 changes: 2 additions & 0 deletions terraform.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
resource_group_name = "mate-azure-task-12"
location = "uksouth"
Binary file added tfplan
Binary file not shown.
Loading