For this project, you will write a Packer template and a Terraform template to deploy a customizable, scalable web server in Azure. In this project, we will assign an azure policy to prevent any new resources without tags from being created. Similarly, we will create an image of the VMs we want to use to act as the load balancer by using packer. Lastly, we will deploy these resources in a scalable immutable way using Terraform.
- Create an Azure Account
- Install the Azure command line interface
- Install Packer
- Install Terraform
-
Clone this repository
-
Create an Azure Policy for your Subscription
-
Create a Service Principle for Packer and Terraform
-
Create a Resource Group for the Packer image
-
Create a variables.json file and update the values provided by the above steps
-
Deploy your packer image
-
Deploy your infraustructure with Terraform
git clone https://github.com/magrathj/Azure-Devops-Deploying-Web-Service.git
Log into your Azure account
az login
az account set --subscription="SUBSCRIPTION_ID"
The policy we will deploy will prevent any new resources from being created without the tag "Udacity".
To run this, use the bash script below:
./azure_policies/deploy_azure_policies.sh
If it works you should be able to view the assigned policy using:
az policy assignment list
You should see something like the screenshot below:
Create Service Principle
az ad sp create-for-rbac --role="Contributor" --scopes="/subscriptions/SUBSCRIPTION_ID"
This command will output 5 values:
{
"appId": "00000000-0000-0000-0000-000000000000",
"displayName": "azure-cli-2017-06-05-10-41-15",
"name": "http://azure-cli-2017-06-05-10-41-15",
"password": "0000-0000-0000-0000-000000000000",
"tenant": "00000000-0000-0000-0000-000000000000"
}
These values map to the variables.json file like so:
appId is the client_id defined above.
password is the client_secret defined above.
tenant is the tenant_id defined above.
Create Resource Group
az group create -l "LOCATION" -n "RESOURCE_GROUP_NAME" --tags "udacity"
You should see something like the screenshot below:
These values map to the variables.json file like so:
LOCATION is the location defined above.
RESOURCE_GROUP_NAME is the resource_group_name defined above.
Create .gitignore file and add variables.json to it
variables.json
{
"client_id": "",
"client_secret": "",
"subscription_id": "",
"tenant_id": "",
"resource_group_name": "",
"image_name": "",
"location": ""
}
Run packer file
packer build -var-file="variables.json" ./packer/server.json
cd terraform/
terraform init
terraform plan
After running the plan you should see the resources that will be built
terraform apply
After running apply you should see the terraform output
You Should update the default values in 'variables.tf' to reflect your project and similarly, you should add values on deployment for the following:
- resource_group_name
- admin_username
- admin_password
- location
- image_id
- numberofvms
For example, you could update the default/add a default for all of the variables below:
variable "resource_group_name" {
description = "rsg for the virtual machine's name which will be created"
}
variable "location" {
description = "azure region where resources will be located .e.g. northeurope"
}
variable "image_id" {
description = "Enter the ID for the image which will be used for creating the Virtual Machines"
}
variable "admin_username" {
description = "Enter username to associate with the machine"
default = "udacity"
}
variable "admin_password" {
description = "Enter password to use to access the machine"
default = "Udacity123"
}
variable "numberofvms" {
description = "number of VMs to create"
}
Following initial set up:
Azure Service Principal
Azure Policy Assignment
Running the Packer commands creates the following resources:
Image resource group
Managed virtual machine image
The following resources are created with the Terraform template:
Resource Group
Virtual Network
Subnet
Network Security Group
Security group rules
Public IP
Load Balancer
Backend Address pools
Availability Set
Network Interface Card(s)
Virtual Machine(s)
Azure Managed Disk(s)