Archive for the ‘terraform’ Category

  • Register to Bitbucket (it’s free).
  • Create Repository

1

2

  • Copy code after registration,it will be used to connect to GIT

5

Download GIT client

Choose default editor

3

4

Start Git CMD, browse to folder where you want to store files for GIT

9

Clone  repository:

git clone https://draganvucanovic@bitbucket.org/draganvucanovic/terraform-git.git

You’ll be prompted for Bitbucket username/password

new folder (repository name) will be created, to that folder copy files you want to push to Git

6.PNG

In Git CMD, browse to that folder

Set username/email address, add files for pushing and commit it

cd terraform-git/
git config --global user.name "some@email"
git config --global user.email "some@email"
git add .
$ git commit -m "test"
git push

8

Creating SSH connection to GitHub

Open gitnbash and create key pair:

ssh-keygen

1.PNG

2.PNG

On GitHub account properties click on your account-settings

3

SSH and GPG Keys-New SSH key

4.PNG

Copy content of public key (id_rsa.pub)

Test connection:

ssh -T git@github.com

 

Advertisements

In previous post we deployed single machine by python script using terraform plugin.

In this one we’ll go through JSON file, extract username and count of instances and based on it create x instances for x user.

In this file for Djukes one instance will be created, for JWilson 2, for eflame 3.

JSON file:

{
"squadName": "Super hero squad",
"homeTown": "Metro City",
"formed": 2016,
"secretBase": "Super tower",
"active": true,
"customers": [
{
"name": "Molecule Man",
"age": 29,
"email": "DJukes@gmail.com",
"instances": 1,
"powers": [
"Radiation resistance",
"Turning tiny",
"Radiation blast"
]
},
{
"name": "Madame Uppercut",
"age": 39,
"email": "JWilson@gmail.com",
"instances": 2,
"powers": [
"Million tonne punch",
"Damage resistance",
"Superhuman reflexes"
]
},
{
"name": "Eternal Flame",
"age": 1000000,
"email": "eflame@gmail.com",
"instances": 3,
"powers": [
"Immortality",
"Heat Immunity",
"Inferno",
"Teleportation",
"Interdimensional travel"
]
}
]
}

Terraform files:

Get public IP:

output.tf

output "id" {
description = "List of IDs of instances"
value = ["${aws_instance.win-example.*.public_ip}"]
}

Security group-for each user allow-all will be replaced with particular user,so for every user new Security group will be created-name of security group will be username

resource "aws_security_group" "allow-all" {
name="allow-all"
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 0
to_port = 6556
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
tags {
Name = "allow-RDP"
}
}

vars.tf

variable "AWS_REGION" {
  default = "eu-west-1"
}
variable "WIN_AMIS" {
  type = "map"
  default = {
    us-east-1 = "ami-30540427"
    us-west-2 = "ami-9f5efbff"
    eu-west-1 = "ami-cc821eb5"
  }
}


variable "count" {

default="1"

}



variable "PATH_TO_PRIVATE_KEY" {
  default = "mykey"
}
variable "PATH_TO_PUBLIC_KEY" {
  default = "mykey.pub"
}
variable "INSTANCE_USERNAME" {
#  default = "Terraform"
}
variable "INSTANCE_PASSWORD" {
 default="Passw0rd012345"

}

windows.tf

resource "aws_instance" "win-example" {
  ami = "${lookup(var.WIN_AMIS, var.AWS_REGION)}"
  instance_type = "t2.medium"
  count="${var.count}"
  lifecycle {
ignore_changes="ami"

}

   
  vpc_security_group_ids=["${aws_security_group.allow-all.id}"]
#key_name = "${aws_key_pair.mykey.key_name}"
  user_data = <
net user ${var.INSTANCE_USERNAME} '${var.INSTANCE_PASSWORD}' /add /y
net localgroup administrators ${var.INSTANCE_USERNAME} /add

winrm quickconfig -q
winrm set winrm/config/winrs '@{MaxMemoryPerShellMB="300"}'
winrm set winrm/config '@{MaxTimeoutms="1800000"}'
winrm set winrm/config/service '@{AllowUnencrypted="true"}'
winrm set winrm/config/service/auth '@{Basic="true"}'

netsh advfirewall firewall add rule name="WinRM 5985" protocol=TCP dir=in localport=5985 action=allow
netsh advfirewall firewall add rule name="WinRM 5986" protocol=TCP dir=in localport=5986 action=allow

net stop winrm
sc.exe config winrm start=auto
net start winrm

EOF

  provisioner "file" {
    source = "test.txt"
    destination = "C:/test.txt"
  }
  connection {
    type = "winrm"
    timeout = "10m"
    user = "${var.INSTANCE_USERNAME}"
     password = "${var.INSTANCE_PASSWORD}"
      
}

tags {
Name="${format("${var.INSTANCE_USERNAME}-%01d",count.index+1)}"

}
}

For every user new folder will be created, all above terraform files will be copied to every user’s folder, one copied sg.tf and windows.tf files will be searched for “allow-all” and replaced with username variable,it is needed because for each user new security group needs to be created

#!/bin/python
import sys
import json
import os.path
import shutil
from os import mkdir
from pprint import pprint
from python_terraform import *

#open JSON file
json_data=open('./my.json')
data = json.load(json_data)

json_data.close()

 

#Function which will create instances,parameters are username and count of instances fetched from JSON file

def myfunc():

tf = Terraform(working_dir=final_path, variables={'count':count,'INSTANCE_USERNAME':user})
tf.plan(no_color=IsFlagged, refresh=True, capture_output=False)
approve = {"auto-approve": True}
print(tf.init(reconfigure=True))
print(tf.plan())
print(tf.apply(**approve))
return

 

 

 

# sweep through JSON file and store username and number of instances into user and count variables
for i in range (0, len (data['customers'])):
#print data['customers'][i]['email']
k=data['customers'][i]['email']
#print(k.split('@')[0])
user=k.split('@')[0]
#print(user)
count=data['customers'][i]['instances']
#print(count)
#enter = int(input('Enter number of instances: '))

#define "root" directory
start_path="/home/ja/terraform-course/demo-2b/"

#in order to avoid instance recreation,folder for each user needs to be created


#define subdirectories named by user and create it it folder doesn't exist
final_path=os.path.join(start_path,user)
if not os.path.exists(final_path):
os.makedirs(final_path)
#copy terraform files to each newly created folder for user

shutil.copy2('./vars.tf', final_path)
shutil.copy2('./sg.tf', final_path)
shutil.copy2('./windows.tf', final_path)
shutil.copy2('./provider.tf', final_path)
shutil.copy2('./test.txt', final_path)
shutil.copy2('./output.tf', final_path)

 

#for each user new security group needs to be created.Name of SG will be username
final=os.path.join(final_path,'sg.tf')
final1=os.path.join(final_path,'windows.tf')

#replace current name (allow-all) with variable username in sg.tf and windows.tf files
with open(final, 'r') as file :
filedata = file.read()
filedata = filedata.replace('allow-all', user)
with open(final, 'w') as file:
file.write(filedata)
with open(final1, 'r') as file :
filedata = file.read()
filedata = filedata.replace('allow-all', user)
with open(final1, 'w') as file:
file.write(filedata)

#call function for running terraform
myfunc()

 

#in each user folder open terraform.tfstate file and extract public IP to variable ip

final2=os.path.join(final_path,'terraform.tfstate')
json_data=open(final2)
data1 = json.load(json_data)
json_data.close()
#write Public IP,username and password to /home/ja/terraform-course/demo-2b/.txt file

filename="/home/ja/terraform-course/demo-2b/"+user+".txt"
print(filename)
for i in range (0, len (data1['modules'])):
ip=','.join(data1['modules'][i]['outputs']['id']['value'])
sys.stdout = open(filename,'wt')
print("Username is:"+" "+ user+".Password is Passw0rd01234.IP addrress is:"+ip)

 

python-terraform is a python module provide a wrapper of terraform command line tool.More details here

Installation is simple:

pip install python-terraform

Now we can use python script to interact with terraform. In this example we’ll pass number of instances as variable to python script and new instances will be created

Python script

 

#!/bin/python

enter = int(input('Enter number of instances: '))

from python_terraform import *
tf = Terraform(working_dir='/home/ja/terraform/demo-3', variables={'count':enter})
tf.plan(no_color=IsFlagged, refresh=False, capture_output=True)
approve = {"auto-approve": True}
print(tf.plan())
print(tf.apply(**approve))

 

variables={‘count’:enter}

count is variable name specified in vars.tf file, enter is variable specified in python script to which we’ll pass number of instances interactively

Because enter variable is variable, single quotes had to be removed, otherwise, quotes needs to be put around that variable also

 

Running script above will spin-up as many instances as we specified at prompt:

Capture

 

Files in /home/ja/terraform/demo-3 folder

instances.tf

resource "aws_instance" "example" {
  ami = "${lookup(var.AMIS, var.AWS_REGION)}"
  instance_type = "t2.micro"

count="${var.count}"

tags {
Name="${format("test-%01d",count.index+1)}"
}

 output "ime" {
   value = ["${aws_instance.example.*.tags.Name}","${aws_instance.example.*.public_ip}"]
}

 

vars.tf (variable file)

 

variable "AWS_ACCESS_KEY" {
}

variable "count" {
default=2
}

variable "AWS_SECRET_KEY" {
}
variable "AWS_REGION" {
  default = "eu-west-1"
}
variable "AMIS" {
  type = "map"
  default = {
    us-east-1 = "ami-13be557e"
    us-west-2 = "ami-06b94666"
    eu-west-1 = "ami-844e0bf7"
  }
}

 

provider.tf

 

provider "aws" {
    access_key = "${var.AWS_ACCESS_KEY}"
    secret_key = "${var.AWS_SECRET_KEY}"
    region = "${var.AWS_REGION}"
}

 

vars.tf

In this file region, path to private/public key is specified,AMI,as well as RDS password

variable "AWS_REGION" {
  default = "eu-west-1"
}
variable "PATH_TO_PRIVATE_KEY" {
  default = "mykey"
}
variable "PATH_TO_PUBLIC_KEY" {
  default = "mykey.pub"
}
variable "AMIS" {
  type = "map"
  default = {
    us-east-1 = "ami-13be557e"
    us-west-2 = "ami-06b94666"
    eu-west-1 = "ami-844e0bf7"
  }
}
variable "RDS_PASSWORD" {
default="MyRDSsimplePassword"
}

instance.tf

instance type,VPC subnet, security group and public key for instance-all returned from vars.tf

resource "aws_instance" "example" {
ami = "${lookup(var.AMIS, var.AWS_REGION)}"
instance_type = "t2.micro"

# the VPC subnet
subnet_id = "${aws_subnet.main-public-1.id}"

# the security group
vpc_security_group_ids = ["${aws_security_group.example-instance.id}"]

# the public SSH key
key_name = "${aws_key_pair.mykeypair.key_name}"

}

sg.tf

In this file 2 security groups are specified: one will allow access to port 3306  from security group  (example-instance,specified in same file), and second one the incoming traffic on port 22 from  anywhere (0.0.0.0/0)

resource "aws_security_group" "example-instance" {
vpc_id = "${aws_vpc.main.id}"
name = "allow-ssh"
description = "security group that allows ssh and all egress traffic"
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}

ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
tags {
Name = "example-instance"
}
}

resource "aws_security_group" "allow-mariadb" {
vpc_id = "${aws_vpc.main.id}"
name = "allow-mariadb"
description = "allow-mariadb"
ingress {
from_port = 3306
to_port = 3306
protocol = "tcp"
security_groups = ["${aws_security_group.example-instance.id}"] # allowing access from our example instance
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
self = true
}
tags {
Name = "allow-mariadb"
}
}

vpc.tf

In this file Virtual Private Network is specified,3 public and 3 private subnets, internet gateway,route table and will associate public subnets to route table (so subnets can be available from the internet)

# Internet VPC
resource "aws_vpc" "main" {
    cidr_block = "10.0.0.0/16"
    instance_tenancy = "default"
    enable_dns_support = "true"
    enable_dns_hostnames = "true"
    enable_classiclink = "false"
    tags {
        Name = "main"
    }
}


# Subnets
resource "aws_subnet" "main-public-1" {
    vpc_id = "${aws_vpc.main.id}"
    cidr_block = "10.0.1.0/24"
    map_public_ip_on_launch = "true"
    availability_zone = "eu-west-1a"

    tags {
        Name = "main-public-1"
    }
}
resource "aws_subnet" "main-public-2" {
    vpc_id = "${aws_vpc.main.id}"
    cidr_block = "10.0.2.0/24"
    map_public_ip_on_launch = "true"
    availability_zone = "eu-west-1b"

    tags {
        Name = "main-public-2"
    }
}
resource "aws_subnet" "main-public-3" {
    vpc_id = "${aws_vpc.main.id}"
    cidr_block = "10.0.3.0/24"
    map_public_ip_on_launch = "true"
    availability_zone = "eu-west-1c"

    tags {
        Name = "main-public-3"
    }
}
resource "aws_subnet" "main-private-1" {
    vpc_id = "${aws_vpc.main.id}"
    cidr_block = "10.0.4.0/24"
    map_public_ip_on_launch = "false"
    availability_zone = "eu-west-1a"

    tags {
        Name = "main-private-1"
    }
}
resource "aws_subnet" "main-private-2" {
    vpc_id = "${aws_vpc.main.id}"
    cidr_block = "10.0.5.0/24"
    map_public_ip_on_launch = "false"
    availability_zone = "eu-west-1b"

    tags {
        Name = "main-private-2"
    }
}
resource "aws_subnet" "main-private-3" {
    vpc_id = "${aws_vpc.main.id}"
    cidr_block = "10.0.6.0/24"
    map_public_ip_on_launch = "false"
    availability_zone = "eu-west-1c"

    tags {
        Name = "main-private-3"
    }
}

# Internet GW
resource "aws_internet_gateway" "main-gw" {
    vpc_id = "${aws_vpc.main.id}"

    tags {
        Name = "main"
    }
}

# route tables
resource "aws_route_table" "main-public" {
    vpc_id = "${aws_vpc.main.id}"
    route {
        cidr_block = "0.0.0.0/0"
        gateway_id = "${aws_internet_gateway.main-gw.id}"
    }

    tags {
        Name = "main-public-1"
    }
}

# route associations public
resource "aws_route_table_association" "main-public-1-a" {
    subnet_id = "${aws_subnet.main-public-1.id}"
    route_table_id = "${aws_route_table.main-public.id}"
}
resource "aws_route_table_association" "main-public-2-a" {
    subnet_id = "${aws_subnet.main-public-2.id}"
    route_table_id = "${aws_route_table.main-public.id}"
}
resource "aws_route_table_association" "main-public-3-a" {
    subnet_id = "${aws_subnet.main-public-3.id}"
    route_table_id = "${aws_route_table.main-public.id}"
}

provider.tf

Gets region from vars.tf

provider "aws" {
    region = "${var.AWS_REGION}"
}

rds.tf

This file specifies subnet group (in which subnet database will be in-group will consist of 2 private subnets), parameter group (parameters to change settings in the database),db instance type,credentials, availability zone, subnet and security group

resource "aws_db_subnet_group" "mariadb-subnet" {
name = "mariadb-subnet"
description = "RDS subnet group"
subnet_ids = ["${aws_subnet.main-private-1.id}","${aws_subnet.main-private-2.id}"]
}

resource "aws_db_parameter_group" "mariadb-parameters" {
name = "mariadb-parameters"
family = "mariadb10.1"
description = "MariaDB parameter group"

parameter {
name = "max_allowed_packet"
value = "16777216"
}
}
resource "aws_db_instance" "mariadb" {
allocated_storage = 100 # 100 GB of storage, gives us more IOPS than a lower number
engine = "mariadb"
engine_version = "10.1.14"
instance_class = "db.t2.small" # use micro if you want to use the free tier
identifier = "mariadb"
name = "mariadb"
username = "root" # username
password = "${var.RDS_PASSWORD}" # password
db_subnet_group_name = "${aws_db_subnet_group.mariadb-subnet.name}"
parameter_group_name = "${aws_db_parameter_group.mariadb-parameters.name}"
multi_az = "false" # set to true to have high availability: 2 instances synchronized with each other
vpc_security_group_ids = ["${aws_security_group.allow-mariadb.id}"]
storage_type = "gp2"
backup_retention_period = 30 # how long you’re going to keep your backups
availability_zone = "${aws_subnet.main-private-1.availability_zone}" # prefered AZ

tags {
Name = "mariadb-instance"
}
}

 

Create key pair and spin up the instance:

 

 ssh-keygen -f mykey && echo "yes" | terraform apply

 

1.PNG

1.PNG

As we can see, RDS id really located on private network (as we specified in security group)

host mariadb.c3wxcgbi9ky2.eu-west-1.rds.amazonaws.com
mariadb.c3wxcgbi9ky2.eu-west-1.rds.amazonaws.com has address 10.0.4.159

Amazon Route 53 (Route 53) is a scalable and highly available Domain Name System (DNS). It is part of Amazon.com’s cloud computing platform, Amazon Web Services (AWS). The name is a reference to TCP or UDP port 53, where DNS server requests are addressed

route3.tf file

In this file DNS zone astrahome.xyz is created, added two A records, one for WWW and second for server1, then one MX record with TTL (time-to-live),determines how frequently your DNS records get updated.MX records are in fact google mail servers

104.236.247.8 presents public IP address

Last section just outputs Amazon name servers

resource "aws_route53_zone" "some-zone" {
name = "astrahome.xyz"
}
resource "aws_route53_record" "server1-record" {
zone_id = "${aws_route53_zone.some-zone.zone_id}"
name = "server1.astrahome.xyz"
type = "A"
ttl = "300"
records = ["104.236.247.8"]
}
resource "aws_route53_record" "www-record" {
zone_id = "${aws_route53_zone.some-zone.zone_id}"
name = "www.astrahome.xyz"
type = "A"
ttl = "300"
records = ["104.236.247.8"]
}
resource "aws_route53_record" "mail1-record" {
zone_id = "${aws_route53_zone.some-zone.zone_id}"
name = "aztrahome.xyz"
type = "MX"
ttl = "300"
records = [
"1 aspmx.l.google.com.",
"5 alt1.aspmx.l.google.com.",
"5 alt2.aspmx.l.google.com.",
"10 aspmx2.googlemail.com.",
"10 aspmx3.googlemail.com."
]
}

output "ns-servers" {
value = "${aws_route53_zone.some-zone.name_servers}"
}

provider.tf-specifies AWS region

provider "aws" {
    region = "${var.AWS_REGION}"
}

vars.tf-variable file, in this case we defined only one variable-aws region

variable "AWS_REGION" {
  default = "eu-west-1"
}

Unlike previous examples, in this one we don’t need file with AWS credentials, because we can install AWS CLI tools, but first we need to install python, because i’m used CentOS minimal, i used this approach to install it. Then i installed AWS CLI.

Now keys are located on local machine (ls ~/.aws), so no need for storing it on terraform file.When Route 53 is deployed using terraform

1.PNG

 

We can check AWS console

1.PNG

 

In one of previous posts we created multiple EC2 instances using modules, instead of using modules, we can just add following line instance.tf file

count=X (where X is number of instances
tags {
Name="${format("test-%01d",count.index+1)}"
}

01d is number of “zero” prefixes-1 (test-01) if we want more zeros change number in front of d (test-%03d would be test002,for example).For the sake of simplicity i created just one terraform file

provider "aws" {
access_key="access keys here"
secret_key="secret keys here"
region = "eu-west-1"
}

variable "count" {
default=2
}


resource "aws_instance" "example" {
count="${var.count}"
ami = "ami-d834aba1"
instance_type = "t2.micro"
tags { Name="${format("test-%01d",count.index+1)}" }
}

output "ip" {
    value = "${aws_instance.example.*.public_ip}"
}

In this case 2 instances were created, with test-1/2 tags

1

In previous post we collected Subscription ID, tenant ID,Client ID and Client secret.Now it’s time to use it.

terraform.tfvars (all sensitive data are stored in this file, it shouldn’t be publicly accessible, here are stored credentials for virtual machine

AZURE_SUBSCRIPTION_ID="some ID"
AZURE_CLIENT_ID="client id"
AZURE_CLIENT_SECRET="secret"
AZURE_TENANT_ID="tenant id"
VM_ADMIN="ja"
VM_PASSWORD="Passw0rd01234!"

vars.tf  (variables are declared in this file)

variable "AZURE_SUBSCRIPTION_ID" {}
variable "AZURE_CLIENT_ID" {}
variable "AZURE_CLIENT_SECRET" {}
variable "AZURE_TENANT_ID" {} 

#to get all sizes:https://docs.microsoft.com/en-us/azure/virtual-machines/windows/sizes-general

variable "vm_size" {
// Get-AzureRmVMSize -Location 'uksouth' | select name, NumberOfCores, MemoryInMB, ResourceDiskSizeInMB | ft
//https://azure.microsoft.com/en-us/documentation/articles/cloud-services-sizes-specs/
//https://azure.microsoft.com/en-gb/documentation/articles/virtual-machines-windows-sizes/
//https://azure.microsoft.com/en-us/pricing/details/virtual-machines/windows/
description = "VM instance size"
default = "Standard_B1ms"
}

variable "vm_image_publisher" {
// Get-AzureRmVMImagePublisher -Location 'uksouth' | Select PublisherName
description = "vm image vendor"
default = "MicrosoftWindowsServer"
}
variable "vm_image_offer" {
//Get-AzureRMVMImageOffer -Location 'uksouth' -Publisher 'MicrosoftWindowsServer' | Select Offer
description = "vm image vendor's VM offering"
default = "WindowsServer"
}

variable "vm_image_sku" {
default = "2016-Datacenter"
}

variable "vm_image_version" {
description = "vm image version"
default = "latest"
}
variable "VM_ADMIN" {
//Disallowed values: "administrator", "admin", "user", "user1", "test", "user2", "test1", "user3", "admin1", "1", "123", "a", "actuser", "adm", "admin2", "aspnet", "backup", "console", "david", "guest", "john", "owner", "root", "server", "sql", "support", "support_388945a0", "sys", "test2", "test3", "user4", "user5".
}

variable "VM_PASSWORD" {
}

provider.tf (used to connect and authorize terraform agains Azure)

provider "azurerm" {
subscription_id="${var.AZURE_SUBSCRIPTION_ID}"
client_id="${var.AZURE_CLIENT_ID}"
client_secret="${var.AZURE_CLIENT_SECRET}"
tenant_id="${var.AZURE_TENANT_ID}"
}

storage.tf (storage account is defined here)

resource "azurerm_storage_account" "storage_acc" {
name = "mystorageaccount201801"
resource_group_name = "${azurerm_resource_group.res_group.name}"
location = "${azurerm_resource_group.res_group.location}"
account_tier = "Standard"
account_replication_type = "LRS"

tags {
environment = "Storage-Acount-Test"
}
}

rg.tf (resource group is specified here)

resource "azurerm_resource_group" "res_group" {
  name     = "myrg1"
  location = "West Europe"
}

virtual_network.tf-in this file virtual network,public IP and subnets are specified

#Create Public IP

resource "azurerm_public_ip" "datasourceip" {
name = "testPublicIp"
location="${azurerm_resource_group.res_group.location}"
resource_group_name = "${azurerm_resource_group.res_group.name}"
public_ip_address_allocation="dynamic"
}

 

# Create a virtual network within the resource group
resource "azurerm_virtual_network" "my_virt_net" {
name = "production-network"
address_space = ["10.0.0.0/16"]
location = "${azurerm_resource_group.res_group.location}"
resource_group_name = "${azurerm_resource_group.res_group.name}"

}

#create subnets
resource "azurerm_subnet" "test1" {
name = "subnet1"
resource_group_name = "${azurerm_resource_group.res_group.name}"
virtual_network_name="${azurerm_virtual_network.my_virt_net.name}"
address_prefix = "10.0.1.0/24"
}

resource "azurerm_subnet" "test2" {
name = "subnet2"
resource_group_name = "${azurerm_resource_group.res_group.name}"
virtual_network_name="${azurerm_virtual_network.my_virt_net.name}"
address_prefix = "10.0.2.0/24"
}

resource "azurerm_subnet" "test3" {
name = "subnet3"
resource_group_name = "${azurerm_resource_group.res_group.name}"
virtual_network_name="${azurerm_virtual_network.my_virt_net.name}"
address_prefix = "10.0.3.0/24"
}

 

#Create network interface

resource "azurerm_network_interface" "my_int" {
name = "myWindowsServer_NIC"
location = "${azurerm_resource_group.res_group.location}"
resource_group_name = "${azurerm_resource_group.res_group.name}"
#network_security_group_id = "${var.vm_security_group_id}"
ip_configuration {
name = "Server2016"
subnet_id = "${azurerm_subnet.test1.id}"
private_ip_address_allocation = "dynamic"
public_ip_address_id = "${azurerm_public_ip.datasourceip.id}"
}
}

vm.tf – Virtual machine details are specified here, 2 additional disks will be attached

resource "azurerm_managed_disk" "test" {
name = "datadisk_existing"
location="${azurerm_resource_group.res_group.location}"
resource_group_name = "${azurerm_resource_group.res_group.name}"
storage_account_type = "Standard_LRS"
create_option = "Empty"
disk_size_gb = "1023"
}

resource "azurerm_virtual_machine" "test" {
name = "myvm"
location="${azurerm_resource_group.res_group.location}"
resource_group_name = "${azurerm_resource_group.res_group.name}"
network_interface_ids = ["${azurerm_network_interface.my_int.id}"]
vm_size = "Standard_DS1_v2"
delete_os_disk_on_termination = "true"
delete_data_disks_on_termination = "true"

storage_image_reference {
publisher = "${var.vm_image_publisher}"
offer = "${var.vm_image_offer}"
sku = "${var.vm_image_sku}"
version = "${var.vm_image_version}"
}

storage_os_disk {
name = "datadisk_new_2018_01"
caching = "ReadWrite"
create_option = "FromImage"
managed_disk_type="Standard_LRS"
}

# Adding additional disk 1

storage_data_disk {
name = "datadisk_new"
managed_disk_type = "Standard_LRS"
create_option = "Empty"
lun = 0
disk_size_gb = "1023"
}

#Additional disk 2

storage_data_disk {
name = "${azurerm_managed_disk.test.name}"
managed_disk_id = "${azurerm_managed_disk.test.id}"
create_option = "Attach"
lun = 1
disk_size_gb = "${azurerm_managed_disk.test.disk_size_gb}"
}

#define credentials
os_profile {
computer_name = "SERVER2016"
admin_username = "${var.VM_ADMIN}"
admin_password = "${var.VM_PASSWORD}"
}

os_profile_windows_config {
provision_vm_agent = "true"
enable_automatic_upgrades = "true"
winrm {
protocol = "http"
certificate_url =""
}
}

}

#get public IP
data "azurerm_public_ip" "test" {
name = "${azurerm_public_ip.datasourceip.name}"
resource_group_name = "${azurerm_resource_group.res_group.name}"
depends_on = ["azurerm_virtual_machine.test"]
}

output "ip_address" {
value = "${data.azurerm_public_ip.test.ip_address}"
}

 

1.PNG

 

2.PNG