Azure cloud provisioning using Ansible

                Automating the IT Infrastructure is today’s one of major focus of all organizations. This reduces the cost and human workloads. When you make a plan to automating your infrastructure, it should start with provisioning of the resources, this makes managing the resources very easy. Many businesses have adopted cloud computing in their operations in the past years because of its flexibility and high sociability features. When you integrate the cloud infrastructure with today’s open source DevOps tools available in the market, this makes your daily life easier to handling huge environments.

I would rather suggest to go with Ansible as the configuration management tool because of its simplicity and straight forward operation features. This came in market late, but gained solid footing and adopted by many DevOps professionals because of its unique features. Ansible offers huge number of modules for managing the cloud operations for all major cloud providers like Azure AWS and GCP.

The Ansible playbooks which I refer below will help you to provisioning cloud resources in Azure environment, which create a Window VM and configure the VM to connect with Ansible host for any post provision activities, The playbook will perform the following tasks.

Continue reading

  1. Create the resource groups and Network infrastructure
  2. Provisioning of windows VMs
  3. Adding the new host to dynamic inventory for any post provision activities
  4. Enabling the PowerShell execution policy to connect to WinRM
  5. Installing a Firefox package using ansible on the newly created VM
The playbook contains 3 roles which will create Network infrastructure, provision a windows VMs and install the Firefox package on it.
——————- advertisements ——————-
———————————————————-
Let’s go through the main playbook first which includes 3 roles First 2 will run against the localhost which creates the Network infrastructure and Virtual machine respectively. As you can see the third role which install the Firefox package is running against a host group azure_vms which will be created dynamically after provisioning the server

Now let’s go through the first role common which creates the resource group and network infrastructure.

 

- name: Create a resource group
   azure_rm_resourcegroup:      
     name: "{{ rg_name }}"      
     location: "{{ location }}"      
     state: present 

- name: Create a virtual network   
  azure_rm_virtualnetwork:      
    name: "{{ vitual_network }}"      
    resource_group: "{{ rg_name }}"      
    address_prefixes_cidr:         
      - "{{ CIDR }}" 
- name: Create network windows base_security groups   
  azure_rm_securitygroup:     
    resource_group: "{{ rg_name }}"     
    name: windows_base     
    purge_rules: yes     
    rules:        
     - name: 'AllowRDP'          
       protocol: Tcp          
       source_address_prefix: 0.0.0.0/0          
       destination_port_range: 3389          
       access: Allow          
       priority: 100          
       direction: Inbound        
     - name: 'AllowWinRM'          
       protocol: Tcp          
       source_address_prefix: 0.0.0.0/0          
       destination_port_range: 5986          
       priority: 102          
       direction: Inbound        
     - name: 'DenyAll'          
       protocol: Tcp          
       source_address_prefix: 0.0.0.0/0          
       destination_port_range: 0-65535          
       priority: 103          
       direction: Inbound

- name: Create a Subnet and adding the windows_base security group in to it
  azure_rm_subnet:
    name: "{{ subnet }}"
    virtual_network_name: "{{ vitual_network }}"
    resource_group: "{{ rg_name }}"
    address_prefix_cidr: "{{ subnet_CIDR }}"
    security_group_name: windows_base 

——————- advertisements ——————-
———————————————————-

Here it’s creating a Resource group, virtual network and a security group which allow incoming RDP and WinRM traffics. You can either add the security group to the NIC card or to the subnet where we create the Virtual machine. Azure will create a NIC card and allocate to the VM in default if you are not giving any custom NIC cards while provisioning. Here I am not creating any custom NIC cards for the server instead attaching the security group with the subnet.

Let’s go through the second role which creates the Virtual machine.


- name: Create a VM    
  azure_rm_virtualmachine:      
    os_type: Windows      
    resource_group: "{{ rg_name }}"      
    virtual_network_name: "{{ virtual_network_name }}"      
    name: "{{ vm_name }}"      
    admin_username: "{{ admin_user }}"      
    admin_password: "{{ admin_passwd }}"      
    vm_size: Standard_F2s_v2      
    image:         
      offer: WindowsServer         
      publisher: MicrosoftWindowsServer         
      sku: '2016-Datacenter'         
      version: latest    
  register: output  

- name: Add new instance to the host group    
  add_host:       
    hostname: "{{ vm_name }}"       
    ansible_host: "{{ azure_vm.properties.networkProfile.networkInterfaces[0].properties.ipConfigurations[0]. properties.publicIPAddress.properties.ipAddress }}"       
    ansible_user: "{{ admin_user }}"       
    ansible_password: "{{ admin_passwd }}"       
    ansible_connection: winrm       
    ansible_port: 5986       
    ansible_winrm_server_cert_validation: ignore       
    ansible_winrm_transport: ssl 
    groupname: azure_vms    
  with_items: output.instances   

- name: create Azure vm extension to enable HTTPS WinRM listener     
  azure_rm_virtualmachine_extension:        
    name: winrm-extension        
    resource_group: "{{ rg_name }}"        
    virtual_machine_name: "{{ vm_name }}"        
    publisher: Microsoft.Compute        
    virtual_machine_extension_type: CustomScriptExtension        
    type_handler_version: 1.9        
    settings: '{"commandToExecute": "powershell.exe -ExecutionPolicy ByPass -   EncodedCommand {{winrm_enable_script}}"}'        
    auto_upgrade_minor_version: true     
  with_items: output.instances   

- name: wait for the WinRM port to come online     
  wait_for:        
    port: 5986        
    host: '{{azure_vm.properties.networkProfile.networkInterfaces[0].properties.ipConfigurations[ 0].properties.publicIPAddress.properties.ipAddress}}'        
    timeout: 600     
  with_items: output.instances
——————- advertisements ——————-
———————————————————-
As you can see in the second task in the role, the newly created server will be added to a host group azure_vms using the ansible add_host module. The third and 4 th task will enable HTTPS WinRM listener for ansible communication.

The third and final role in the playbook will install a Firefox browser in the newly provisioned VM using the ansible win_chocolatey module.

 - name: Install Firefox 
   win_chocolatey:
     name: firefox
     state: present

Here is the main playbook which calls all the 3 roles

---
- hosts: localhost
  gather_facts: yes
  roles:
   - common
   - vm

- hosts: azure_vms
  gather_facts: no
  roles:
   - install_firefox

Hope this post helped you. Please share your feedback/suggestions in the comments below.

Update service-now ticket using a Python script

How cool it will be if you can upload the output of your script in to Service now incident notes or task notes automatically. This python script helps you to run set of command against the Cisco switches and routers and the output of command will upload to service now incident automatically. This will help you to increase the response time of NOC L1  team in troubleshooting task.

Service-now a IT Service management (ITSM) tool based on cloud platform provides end to end transformation of IT services. Service Now provides REST API to communicate with SNOW instance. We will use REST API in our program to interact with service now instance.

We are explaining step by step procedure to achieve this

Following are the components required: Continue reading

  1. Service now developer account
    2. Service now instance
    3. Python with Service now API installed

——————- advertisements ——————-

———————————————————-

Create service now developer account and instance

Please refer our post ‘Create service now developer account and instance’ and create new user for API calls.

Setup environment

We would  require ‘netmiko’ package to take ssh of devices. Please read part 1 and part 2  of our post for details about installing python and running your first program. Please read part 4 if you want to know how to take SSH of a switch.

Install python service-now API package

We also require ‘pysnow’ package which is using to interact with service now using REST API call. Please click here if you would like to know more about ‘pysnow’ package.

Install ‘psysnow’ using following command

‘pip install psynow’

please click here if you did not know how to install a package on python using pip

Script Definition:

The script will get service-now information and device credential initially. Then it will continuously run on server so user can update multiple incident by running the commands against multiple devices. All the required commands have to be saved on ‘command.txt’ file.

——————- advertisements ——————-

———————————————————-

It is using class ‘inc_update’ to gather information and update service-now.  Inside the class, the function ‘collectdata’ using to SSH to device and taking the out put of commands.  The function ‘inc_update’ using to update service now instance with the output.

Following are the script. It is easy to understand, and we have put inline comments for making it easy.

import pysnow
import getpass
from netmiko import ConnectHandler

print “=============================\n”
print “Program to update service now incident notes\n”
print “\n=============================\n”

##class to connect device
class cls_incident:
#initialising variables
def __init__(self,uname,password):
#initialising variables
self.uname = uname
self.password = password
self.secret=password
self.dev_type=’cisco_ios’
self.ip=”
self.output=”

——————- advertisements ——————-

———————————————————-

#creating dictionery for netmiko
self.dict_device = {
‘device_type’: self.dev_type,
‘ip’: self.ip,
‘username’: self.uname,
‘password’: self.password,
‘secret’: self.secret,
‘global_delay_factor’:1,

}

#function to login to device and collect output of command
def collectdata(self,ipaddress):
self.dict_device[‘ip’]=ipaddress
self.net_connect = ConnectHandler(**self.dict_device)
#opening command file
cmd_file=open(‘command.txt’)
self.output=”
#loop for reading command one by one
for line in cmd_file:
cmd=line.lstrip()
self.output+=”\nOutput of command “+cmd+” \n”
self.output+=self.net_connect.send_command(cmd)
cmd_file.close()

——————- advertisements ——————-

———————————————————-

print self.output
print “\nCommand Output collected”

#function to update service now
def inc_update(self,inc_number,s_uname,s_password,s_instance):
#connecting with service now
snow = pysnow.Client(instance=s_instance, user=s_uname, password=s_password)
incident = snow.resource(api_path=’/table/incident’)
#payload=self.output
update = {‘work_notes’:self.output, ‘state’: 5}
#updating incident record
updated_record = incident.update(query={‘number’:inc_number}, payload=update)
print “Incident note updated ”

def main():

#Collecting service now details
instance=raw_input(“Enter service now instant name in format of ‘company.service-now.com’ :”)

——————- advertisements ——————-

———————————————————-

instance=instance.rstrip(‘.service-now.com’)
s_uname=raw_input(“Enter service now user name:”)
s_password=getpass.getpass(“Password:”)

##Collecting device credential
dev_uname=raw_input(“\nEnter Device user name :”)
dev_passwd=getpass.getpass(“Password:”)

objDev=cls_incident(dev_uname,dev_passwd)

while True:
try:
inc_number=raw_input(“Enter incident number :”)
ip_address=raw_input(“Enter IP address of device:”)
print “Connecting device and collecting data ”
#creating class object
objDev.collectdata(ip_address)

print (“Updating service now”)
#updaing service nw
objDev.inc_update(inc_number,s_uname,s_password,instance)
print “\nThis program will keep on running, press ctrl C to exit”
print “Enter details for next incident \n”
except Exception,e:
print “Error on execution :”,e
if __name__== “__main__”:
main()

——————- advertisements ——————-

———————————————————-

How to run :

Download the ‘command.txt‘ and ‘incident-update.txt‘ in to same folder of your system. rename ‘incident-update.txt’ in to ‘incident-update.py’. Open the file ‘command.txt’ and add your required commands which need to be run on networking device.. Run the program from command prompt using ‘ python incident-update.py’ . Please provide your input and test . Please ensure you have the reach-ability to service-now instance and network devices from your machine.

Program screen shot

——————- advertisements ——————-

———————————————————-

Service-now screen shot

You could see service now incident notes updated with command output automatically

Hope this will ease your life a bit.. 🙂

Please comment below if you would require customized script based on your requirement which will support multiple device model like Cisco ASA, Juniper, Palo Alto, Checkpoint etc.

Network Automation using Python – Part VII – SSL certificate status validation and alert configuration

Python SSL Certificate Checker 

Continuing our Networking Automation using Python blog series, here is the Part 7.

In this part we are explaining python script which will check the expiry date of a SSL certificate from a list of IP address and send an e-mail automatically if the certificate expiry date is nearing. The IP addresses can be of your load balancer VIP or Server IP address or any device IP address. You can use same script to check SSL certificate for any port number like 443,587,993,995,465 etc.

Basic Requirements Continue reading

  1. Python 3.6
  2. server_ip.txt , a text file which contains all device IP address
  3. A email account on www.outlook.com . You can use any other mail account by editing SMTP server detail on the script. Please let us know if you want customised script which will sent mail from your corporate mail account or Microsoft Outlook.

Please read part 1 and part 2 to get started with python and how to run your first program.

This script have two files

  1. server_ip.txt -> this file store all the device IP address
  2. sslcheck.py -> This is the python script

——————- advertisements ——————-

———————————————————-

How to run :

Step 1. Download the sslcheck and server_ip to the same folder

Step 2. Change the sslcheck.txt to sslcheck.py

Step 3. Open server_ip.txt and save with all your device IP address with port number whose SSL certificate need to be check.

Step 4. Open command prompt “CMD” and navigate to the folder where you have saved script and ‘server_ip.txt’

Step 5. Run script by typing “python sslcheck.py”  on command prompt

Step 6.It will ask for threshold date, from mail id , to mail id and credentials. Please provide the same

Step 7. Script will go though each device SSL certificate and sent mail if anything going to expire within given number of days.

 

Script Details

import ssl
from datetime import datetime
import pytz
import OpenSSL
import socket
import getpass
from datetime import timedelta
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

——————- advertisements ——————-

———————————————————-

print(“Program to check SSL certificate validity \n”)
##opening file
ipfile=open(‘server_ip.txt’)
cur_date = datetime.utcnow()
mailbody=””
expcount=0

##getting details
expday=input(“Please provide threshold expiry date :”)
from_mail=input(“Your mail id : “)
passwd=getpass.getpass(“password : “)
to_mail=input(“Target mail id : “)
##checking certificate validity. for loop to go through each IP in server_ip.txt file

for ip in ipfile:
try:
host = ip.strip().split(“:”)[0]
port = ip.strip().split(“:”)[1]
print(“\nChecking certifcate for server “,host)
ctx = OpenSSL.SSL.Context(ssl.PROTOCOL_TLSv1)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, int(port)))
cnx = OpenSSL.SSL.Connection(ctx, s)
cnx.set_connect_state()
cnx.do_handshake()
cert=cnx.get_peer_certificate()
s.close()
server_name = cert.get_subject().commonName
print (server_name)

——————- advertisements ——————-

———————————————————-

##checking expiry date
edate=cert.get_notAfter()
edate=edate.decode()

##converting in to system time format
exp_date = datetime.strptime(edate,’%Y%m%d%H%M%SZ’)
days_to_expire = int((exp_date – cur_date).days)
print(“day to expire”,days_to_expire)
##preparing mail body
if days_to_expire < int(expday) :
expcount=expcount+1
mailbody=mailbody+”\n Server name =”+server_name+”, Days to expire:”+str(days_to_expire)

except:
print (“error on connection to Server,”,host)
print (mailbody)

#sending mail if any certificate going to expire within threshold days
if expcount >= 1 :
try:
print(“\nCertifcate alert for “+str(expcount)+” Servers,Sending mails”)

body=”Following certificate going to expire, please take action \n”+mailbody
s = smtplib.SMTP(host=’smtp-mail.outlook.com’, port=587) # change here if you want to use other smtp server
s.starttls()
s.login(from_mail,passwd)

——————- advertisements ——————-

———————————————————-

msg = MIMEMultipart() # create a message
msg[‘From’]=from_mail
msg[‘To’]=to_mail
msg[‘Subject’]=”Certificate Expire alert”
# add in the message body
msg.attach(MIMEText(str(body),’plain’))

# send the message via the server set up earlier.
s.send_message(msg)
print(“Mail sent”)
s.close()
except:
print (“Sending mail failed”)
else :
print(“All certificate are below the threshold date”)

print (‘\nCert check completed’)

 

Sample Output 

Below images are sample script and a sample e-mail alert.

——————- advertisements ——————-

———————————————————-

Sample e-mail alert

Hope this post helped you. You can read more posts on Network automation using Python here. Please use the comments section for any queries/suggestions .

Reference :

https://www.python.org/

http://www.tutorialspoint.com/python/ 

Network Automation using Python – Part VI – Automatic backup of multiple switches

Python Backup Script

 

Continuing our Networking Automation using Python blog series, here is the Part 6.

Here we are explaining a simple script to take the backup of multiple Cisco switches/routers quickly. You can schedule the script using crone or job scheduler so it will automatically take daily backup without your intervention. The script will take the output of ‘sh run’ and save to the file. The file name would be  device IP address + today’s date .

Please read part 1 and part 2 to get started with python and to run your first program. Please read part 4 for detailed steps on how to take an SSH session of a switch.

Continue reading

The script have two files

  1. ipfile.txt -> this file store all the device IP address
  2. autobackup.py -> This is the python script

How to run :

Step 1. Download the autobackup and iplist to the same folder

Step 2. Change the autobackup.txt to autobackup-cisco.py

Step 3. Open iplist.txt and save with all your device IP address which need to be backed up.

——————- advertisements ——————-

———————————————————-

Step 4. Open command prompt “CMD” and navigate to the folder where you have saved script and ‘iplist.txt’

Step 5. Run script by typing “python autobackup-cisco.py”  on command prompt

Step 6. You can see the backup of device on same folder with the filename device IP address+ date

——————- advertisements ——————-

———————————————————-

Sample screenshot below.

Hope this post helped you.

You can read more posts on Network automation using Python here. Please use the comments section for any queries/suggestions .

Reference :

https://www.tutorialspoint.com/python

https://www.python.org/