- Azure subscription
- Linux Virtual Machine (Ubuntu 16.04 or above)
Create Azure resource group using Azure Cloud Shell
- On Azure Portal, Launch cloud shell and check terraform version on the cloud shell
$ terraform version
Terraform v0.13.5
- Create resource group "testResourceGroup"
# Create a service principal that terraform will use to authenticate with Azzure
$ export SUBSCRIPTION_ID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
$ az account set --subscription="${SUBSCRIPTION_ID}"
$ az ad sp create-for-rbac --role="Contributor" --scopes="/subscriptions/${SUBSCRIPTION_ID}"
Creating a role assignment under the scope of "/subscriptions/aaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
{
"appId": "aaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
"displayName": "azure-cli-2019-12-13-08-53-51",
"name": "http://azure-cli-2019-12-13-08-53-51",
"password": "bbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbb",
"tenant": "cccccccc-cccc-cccc-cccc-cccccccccccc"
}
$ export ARM_SUBSCRIPTION_ID=your_subscription_id
$ export ARM_CLIENT_ID=your_appId
$ export ARM_CLIENT_SECRET=your_password
$ export ARM_TENANT_ID=your_tenant_id
$ code test.tf
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "rg" {
name = "testResourceGroup"
location = "westus"
}
# Run terraform init, plan, and apply.
$ terraform init
$ terraform plan
$ terraform apply
- Add variables.tf and outputs.tf to use input and output variables
$ code variable.tf
variable "location" {
description = "This is azure region that this resource will reside"
default = "koreacentral"
}
$ code output.tf
output "resourcegroup_id" {
value = azurerm_resource_group.rg.id
}
$ code terraform.tfvars
location = "westus"
#Modify test.tf to use "location" variable
$ code test.tf
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "rg" {
name = "testResourceGroup"
location = var.location
}
- Move backend to Azurerm backend (Azure Blob storage)
# Create a storage account and container for backend state file
az group create --name terraform-state --location koreacentral
az storage account create --name tfstatedemo111 \
--resource-group terraform-state \
--location koreacentral \
--sku Standard_GRS \
--kind StorageV2
az storage account keys list -g terraform-state -n tfstatedemo111
export AZURE_STORAGE_KEY="<storage account access key from above command>"
az storage container create \
--account-name tfstatedemo111 \
--name tfstate
# Upload terraform.tfstate file to Azure Storage
az storage blob upload \
--account-name tfstatedemo111 \
--container-name tfstate \
--name demo.tfstate \
--file terraform.tfstate
# Create main.tf to specify terraform backend
$ code main.tf
terraform {
backend "azurerm" {
storage_account_name = "tfstatedemo111"
container_name = "tfstate"
key = "demo.tfstate"
access_key = "xxxxp5Nv8kTjdpYj9KwGIxeB+JkvmXKPLdpYjNY9/wE1pLM2RuOglxvuCA7RwLx7vdd2SFNCOCfIyyyyyyyyy==" # storage account key
}
}
# Run terraform init and apply again
$ terraform init
$ terraform apply
- Create Virtual Network
$ code vnet.tf
resource "azurerm_virtual_network" "example" {
name = "myVNet"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
address_space = ["10.0.0.0/16"]
tags = {
environment = "Production"
}
}
resource "azurerm_subnet" "example" {
name = "subnet1"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.example.name
address_prefixes = ["10.0.1.0/24"]
}
- Create Ubuntu VMs in the subnet
$ code vm.tf
locals {
admin_username = "azureuser"
admin_password = "mypassword"
}
module "service1" {
source = "git://github.com/hyundonk/aztf-module-vm.git"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
instances = {
name = "svc1"
vm_num = 2
vm_size = "Standard_D2s_v3"
subnet_ip_offset = 4
vm_publisher = "MicrosoftWindowsServer"
vm_offer = "WindowsServer"
vm_sku = "2016-Datacenter"
vm_version = "latest"
}
subnet_id = azurerm_subnet.example.id
subnet_prefix = azurerm_subnet.example.address_prefix
admin_username = local.admin_username
admin_password = local.admin_password
}
# Run "terraform init" for new module(s)
$ terraform init
# Run terraform plan and apply
$ terraform plan
$ terraform apply
Option #1) Using WSL 2 (Windows Subsystem for Linux 2) on PC. https://docs.microsoft.com/en-us/windows/wsl/wsl2-install
- Ensure that you are running Windows 10 build 18917 or higher
C:\Users\azureuser>ver
Microsoft Windows [Version 10.0.18363.535]
-
If not, go to https://insider.windows.com/en-us/ and click "REGISTER TO GET THE PREVIEW"
-
Then, Go to Settings > Update & Security > Windows Insider Program and click Get Started to access the latest build. Select the 'Fast' ring or the 'Slow' ring.
C:\Users\azureuser>ver
Microsoft Windows [Version 10.0.19041.1]
> dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
> dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
Then reboot the machine...
- On web browser, go to https://aka.ms/wslstore and install "Ubuntu"
Installing, this may take a few minutes...
Please create a default UNIX user account. The username does not need to match your Windows username.
For more information visit: https://aka.ms/wslusers
Enter new UNIX username: azureuser
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
Installation successful!
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.
azureuser@win10:~$
- Set a distro to be backed by WSL 2 using the command line
C:\WINDOWS\system32>wsl --set-version ubuntu 2
Conversion in progress, this may take a few minutes...
For information on key differences with WSL 2 please visit https://aka.ms/wsl2
Conversion complete.
C:\WINDOWS\system32>wsl --set-default-version 2
- Install Windows Terminal (Preview) https://www.microsoft.com/en-us/p/windows-terminal-preview/9n0dx20hk701
Option #2) Using Linux Machine
When using WSL, sometimes terraform runs slow due to memory constraints. In such case, install an Azure Linux VM (e.g. Ubuntu 16.04 or later) instead of WSL
- Install Azure CLI
# Install Azure CLI
$ curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
- On ubuntu bash shell, install terraform (v0.13.5), git, and jq
$ sudo apt-get update -y
$ wget https://releases.hashicorp.com/terraform/0.13.5/terraform_0.13.5_linux_amd64.zip
$ sudo unzip ./terraform_0.13.5_linux_amd64.zip -d /usr/local/bin/
$ terraform -v
$ sudo apt install git-all
$ sudo apt-get install -y jq
- Deploy Landing Zone Level0
# Login to Azure
$ az login
# clone level0
$ git clone https://github.com/hyundonk/level0.git
$ cd level0
# terraform variable "prefix"
$ export TF_VAR_prefix="abcd"
# Run launchpad.sh
$ ./launchpad.sh
tf_action is : ''
tf_command is : ''
blueprint is : ''
Calling initialize_state
Initializing launchpad from launchpad_opensource
rm: cannot remove './.terraform/terraform.tfstate': No such file or directory
rm: cannot remove './terraform.tfstate': No such file or directory
rm: cannot remove 'backend.azurerm.tf': No such file or directory
Initializing the backend...
Initializing provider plugins...
- Checking for available provider plugins...
- Downloading plugin for provider "azurerm" (hashicorp/azurerm) 1.37.0...
- Downloading plugin for provider "azuread" (hashicorp/azuread) 0.6.0...
- Downloading plugin for provider "random" (hashicorp/random) 2.2.1...
The following providers do not have any version constraints in configuration,
so the latest version was installed.
To prevent automatic upgrades to new major versions that may contain breaking
changes, it is recommended to add version = "..." constraints to the
corresponding provider blocks in configuration, with the constraint strings
suggested below.
* provider.random: version = "~> 2.2"
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
var.location
Azure region to deploy the launchpad in the form or 'southeastasia' or 'westeurope'
Enter a value: southeastasia
var.tf_name
Name of the terraform state in the blob storage
Enter a value: level0_launchpad.tfstate
Then check Azure resources created for level 0.
$ git clone https://github.com/aztfmod/landingzones.git
$ cd landingzones/
$ ../level0/launchpad.sh landingzone_caf_foundations apply
# set secrets for monitoring node (VM) in keyvault
$ az keyvault set-policy -n $keyvault --upn username@example.com --secret-permissions set get list
$ az keyvault secret set --vault-name $keyvault --name "adminusername" --value "username"
$ az keyvault secret set --vault-name $keyvault --name "adminpassword" --value "password"
$ git clone https://github.com/aztfmod/landingzones.git
$ cd landingzones/
$ ../level0/launchpad.sh landingzone_vdc_demo apply
# go to workspace root directory
$ cd ../../
# set secrets for fortigate instances (VM) in keyvault
$ az keyvault set-policy -n $keyvault --upn username@example.com --secret-permissions set get list
$ az keyvault secret set --vault-name $keyvault --name "fortigate-adminusername" --value "username"
$ az keyvault secret set --vault-name $keyvault --name "fortigate-adminpassword" --value "password"
$ git clone https://github.com/hyundonk/azure-terraform-fortigate-module.git
$ cd azure-terraform-fortigate-module/firewall/
# get fortigate license files and config.txt file to current directory.
# upload license file and config file to Aprepare_fortigtate_bootstrap.shzure Blob Storage
$ ./prepare_fortigtate_bootstrap.sh
Run terraform init with setting environment vairables
$ . ./terraform_init.sh
Run terraform apply
$ terraform apply
# Appendix
Install docker engine
$ sudo apt-get install
apt-transport-https
ca-certificates
curl
gnupg-agent
software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo add-apt-repository
"deb [arch=amd64] https://download.docker.com/linux/ubuntu
$(lsb_release -cs)
stable"
$ sudo apt-get install docker-ce docker-ce-cli containerd.io $ sudo service docker start $ sudo docker run hello-world
$ sudo chown "$USER":"$USER" /home/"$USER"/.docker -R $ sudo chmod g+rwx "/home/$USER/.docker" -R
1. Create service principal to running terraform
$ export SUBSCRIPTION_ID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" $ az account set --subscription="${SUBSCRIPTION_ID}" $ az ad sp create-for-rbac --role="Contributor" --scopes="/subscriptions/${SUBSCRIPTION_ID}" Creating a role assignment under the scope of "/subscriptions/87b7ed75-7074-41d6-9b53-3bf8894138bb" { "appId": "aaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", "displayName": "azure-cli-2019-12-13-08-53-51", "name": "http://azure-cli-2019-12-13-08-53-51", "password": "bbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbb", "tenant": "cccccccc-cccc-cccc-cccc-cccccccccccc" }
$ export ARM_SUBSCRIPTION_ID=your_subscription_id $ export ARM_CLIENT_ID=your_appId $ export ARM_CLIENT_SECRET=your_password $ export ARM_TENANT_ID=your_tenant_id
$ cat test.tf provider "azurerm" { } resource "azurerm_resource_group" "rg" { name = "testResourceGroup" location = "westus" }
$ terraform init
$ terraform plan
$ terraform apply
1. Prepare Bash shell environment (Windows Terminal with Windows Subsystem for Linux is recommended.)
2. Install terraform (v0.12.12), jq, git, docker
$ sudo apt-get update -y $ wget https://releases.hashicorp.com/terraform/0.12.12/terraform_0.12.12_linux_amd64.zip $ sudo unzip ./terraform_0.12.12_linux_amd64.zip -d /usr/local/bin/ $ terraform -v
$ sudo apt-get install -y jq $ sudo apt install git-all
For docker daemon installation, refer https://docs.docker.com/install/linux/docker-ce/ubuntu/
3. Deploy Landing Zone Level0
$ wget -O - --no-cache https://raw.githubusercontent.com/aztfmod/rover/master/install.sh | bash $ cd ~/git/github.com/aztfmod/rover
~/git/github.com/aztfmod/rover$ make setup_dev_githttp
locals { tfstate-blob-name = var.tf_name prefix = "abcd" }
resource "azurerm_resource_group" "rg" { name = "${local.prefix}-terraform-state" #name = "${random_string.prefix.result}-terraform-state"
resource "azuread_application" "tfstate" { name = "${local.prefix}tfstate" #name = "${random_string.prefix.result}tfstate" }
resource "azuread_application" "devops" { name = "${local.prefix}devops" #name = "${random_string.prefix.result}devops" }
resource "random_string" "kv_name" { length = 23 - length(local.prefix) #length = 23 - length(random_string.prefix.result) special = false upper = false number = true }
locals { kv_name = "${local.prefix}${random_string.kv_middle.result}${random_string.kv_name.result}" #kv_name = "${random_string.prefix.result}${random_string.kv_middle.result}${random_string.kv_name.result}" }
resource "azurerm_key_vault_secret" "tfstate_prefix" { provider = azurerm.sp_tfstate
name = "tfstate-prefix"
value = local.prefix
#value = random_string.prefix.result
key_vault_id = azurerm_key_vault.tfstate.id
}
resource "azurerm_user_assigned_identity" "tfstate" { resource_group_name = azurerm_resource_group.rg.name location = azurerm_resource_group.rg.location
name = "${local.prefix}tfstate_msi" #name = "${random_string.prefix.result}tfstate_msi" }
- jq
- docker
- git
$ sudo service docker start
$ make local
$ ./rover.sh login [subscription_guid] [tenantname.onmicrosoft.com or tenant_guid]
$ az account show
$./rover.sh
var.location Azure region to deploy the launchpad in the form or 'southeastasia' or 'westeurope'
Enter a value: koreacentral
var.tf_name Name of the terraform state in the blob storage
Enter a value: level0_launchpad.tfstate
$ cd level0/ $ $ cp level0/ level0_launchpad
$ git clone https://github.com/aztfmod/level0.git