Saturday, 13 November 2021

Lock the user AWS access keys if the access key is inactive for certain days

 About the problem: 


 I got a specific requirement from my client compliance team that they want to disable the AWS access keys automatically if the user key is inactive for certain days . By default AWS IAM didn't provide that option so we have to find another way to meet that compliance .

Solution :


AWS "AccessKeyLastUsed" api helps to check the users last time used the access key. By using that I have build the below script which will disable the user if its disable for 90 days .


Lambda Script:

import json

import boto3

import os

from datetime import datetime, timedelta


def lambda_handler(event, context):

    #Variable declaration section

    iamClient = boto3.client('iam')

    UserMetaDataList = []

    DictionaryOfFate = {}


############################################# Conditional User Keys Activate/Inactivate #########################################


    # To list and append user meta data

    response = iamClient.list_users(MaxItems=150)

    UserMetaDataList.extend(response['Users'])

    while response['IsTruncated'] :

        response = iamClient.list_users(MaxItems=150, Marker = response['Marker'])

        UserMetaDataList.extend(response['Users'])


   

    # Collecting the usernames and creation dates

    for userMeta in UserMetaDataList :

        DictionaryOfFate[userMeta['UserName']] = userMeta['CreateDate'].date()


   

    #DictionaryOfFate = {'testUser':2010}


    # User Modification


    for UserNameAskey in DictionaryOfFate.keys() :

        AccessKeyList = []

        lastActivityDateList = []

        LastActivity = None


        # Collect Access keys

        response = iamClient.list_access_keys(UserName=UserNameAskey,MaxItems=150)

        AccessKeyList.extend(response['AccessKeyMetadata'])

        while response['IsTruncated'] :

            response = iamClient.list_access_keys(UserName=UserNameAskey,MaxItems=150,Marker = response['Marker'])

            AccessKeyList.extend(response['AccessKeyMetadata'])

        #print(AccessKeyList)

   

        # Finding Last Activity Date

        if(len(AccessKeyList)!=0) :

            flagForUnusedUser = 0           # this flag is for user having access keys but never logged in

            for accessKey in AccessKeyList :

                try :

                    response = iamClient.get_access_key_last_used(AccessKeyId=accessKey['AccessKeyId'])

                    LastActivity = response['AccessKeyLastUsed']['LastUsedDate'].date()

                    if(LastActivity != datetime.now().date()) :

                        LastActivity = str(datetime.now().date() - LastActivity)

                        temp = LastActivity.find('day')

                        LastActivity = int(LastActivity[:(temp-1)])

                        # If the User remains inactive for more than 90 days, then initiate deletion

                        if( LastActivity > 90 ) :

                            print("Defaulter : " + UserNameAskey)

                            print("\n")

                            # Access keys

                            if(accessKey['Status']=='Active'):

                                response = iamClient.update_access_key(UserName=UserNameAskey,AccessKeyId=accessKey['AccessKeyId'],Status='Inactive')

                        # print(LastActivity)

                    else :

                        #print("Recently accessed : " + UserNameAskey + "\n")

                        LastActivity = 0


                except Exception as e :

                    #print("Access not Found")

                    continue

                

        else:

            pass


Lock the user AWS account if the account is inactive for certain days

About the problem: 

 I got a specific requirement from my client compliance team that they want to disable the AWS account automatically if the user is inactive for certain days . By default AWS IAM didn't provide that option so we have to find another way to meet that compliance .

Solution :

AWS "PasswordLastUsed" api helps to check the users last time used the password . By using that I have build the below script which will disable the user if its disable for 90 days .


Lambda Script :

import datetime

import dateutil

import boto3

from dateutil import parser



UserMetaDataList = []

IAM = boto3.client('iam')

todaysDate = datetime.date.today() - datetime.timedelta(days=90) [Please change the date as per your requirement]

response=IAM.list_users(MaxItems=200)

#UserMetaDataList.extend(response['Users'])

print (response)

#print UserMetaDataList

userlen = len(response['Users'])

print (userlen)

#timeLimit=datetime.datetime.now() - datetime.timedelta(days=90)


print ("-------------------------------------------------------------")

print ("Login access Created Date" + "\t\t" + "Username")

print ("-------------------------------------------------------------")


#try:

for i in range(userlen):

    #print i

    try:

        Passwordlastused=response['Users'][i]['PasswordLastUsed']

        print (Passwordlastused)

        username=response['Users'][i]['UserName']

        print (username)

        Passwordlastused=response['Users'][i]['PasswordLastUsed']

        try:

            if(str(todaysDate)>=str(Passwordlastused)): 

                #print ( "Disableing user %s" % username")

                IAM.delete_login_profile(UserName=username)

        

        

        except Exception as e:

            print("Some error occured in lambda_handler" + '\n' + str(e))

            pass

        

    except Exception as e:

        print("Some error occured in lambda_handler" + '\n' + str(e))

        pass

        

#except Exception as e:

 #   print(e)



def lambda_handler(event, context):     

    filepath ='/tmp/volume_report.csv'

    filename ='report_Ireland' 

AWS EBS Volume report using python script

 It is very import me to track all the resources created for my client is always compliance with the IT security policy . Most of my clients are prefer to have AWS volume encryption as mandatory but to track it in large environment is an challenge. Also aws volume api support 100 volumes in describe instance api . So its difficult for a system admin to track the AWS volume resource in a larger environment . So i deicide to create an python lambda script which will check the existing volumes attach with the instacnes and send an automated email of the volumes attached with the instacnes .

Lambda Script:


import os

import json

import boto3

import datetime

import sys

import time

from time import gmtime, strftime

import csv

from email import encoders

from email.mime.multipart import MIMEMultipart

from email.mime.text import MIMEText

from email.mime.application import MIMEApplication

from email.mime.base import MIMEBase

from botocore.exceptions import ClientError



ses = boto3.client('ses',region_name=regionName) [Your AWS region name]


regionFromCopy='ap-south-1' [Your AWS region Name]

s3 = boto3.resource('s3',region_name='ap-south-1') [Your AWS region Name]

#create object for ami.

clientEc2 = boto3.client('ec2',region_name=regionFromCopy)


csvfile= open('/tmp/volume_report.csv', 'w')

writer = csv.writer(csvfile)

inst_name=[]

writer.writerow([

        'Instance ID',

        'Private IP Address',

        'Instance Type',

        'Instance State',

        'Instance SG',

            'Volume ID',

            'Availability Zone',

            'Device mount Point',

            'Encryption State',

            'Volumetype',

            'Createtime',

            'size',

            'Instance Name'])


try:


regionFromCopy='ap-south-1' [Your AWS region Name]

#create object for ami.

clientEc2 = boto3.client('ec2',region_name=regionFromCopy)

          # use below If you need for specific environment based on tagging 

#reservations = clientEc2.describe_instances(Filters = [{'Name': 'tag:Environment' ,'Values': ["Devolopment"]}])

reservations = clientEc2.describe_instances()

#print reservations

instances = [i for r in reservations['Reservations'] for i in r['Instances']]

#generate date for the ami name.

todaysDate = datetime.date.today()

InstanceName=''

for instance in instances:

InstanceID = instance['InstanceId']

print (InstanceID)

PriveIP = instance['PrivateIpAddress']

print (PriveIP)

instancetype = instance['InstanceType']

print (instancetype)

launchtime = instance['LaunchTime']

print (launchtime)

instancestate = instance['State']['Name']

print (instancestate)

instanceSG = instance['SecurityGroups']

print (instanceSG)

instacneSubnet = instance['SubnetId']

print (instacneSubnet)

blockdevice = instance['BlockDeviceMappings']

#print blockdevice

for tag in  instance['Tags']:

if tag['Key'] == "Name":

instanceName = tag['Value']

print (instanceName)

#for tag in  instance['Tags']:

# if tag['Key'] == "Application":

# applicationName = tag['Value']

#    print applicationName

    

for block in blockdevice:

    ebsdrive = block['Ebs']

    print (ebsdrive['VolumeId'])

    vol = ebsdrive['VolumeId']

    volumedit =  clientEc2.describe_volumes(VolumeIds= [str(vol)])

   

    #print volumedit

    

    Availabilityzone= ''

    Availabilityzone=volumedit['Volumes'][0]['AvailabilityZone']

    print (Availabilityzone)

    attachments= ''

    attachments=volumedit['Volumes'][0]['Attachments']

    print (attachments)

    for item in attachments:

        deviceID = (item["Device"] )

        print (deviceID)

                

                

    encrypted= ''

    encrypted=volumedit['Volumes'][0]['Encrypted']

    print (encrypted)

    Volumetype=''

    Volumetype=volumedit['Volumes'][0]['VolumeType']

    print (Volumetype)

    Volumeid= ''

    Volumeid=volumedit['Volumes'][0]['VolumeType']

    print (Volumeid)

    Createtime= '' 

    Createtime=volumedit['Volumes'][0]['CreateTime']

    print (Createtime)

    size= ''

    size=volumedit['Volumes'][0]['Size']

    print (size)

    writer.writerow([InstanceID,PriveIP,instancetype,instancestate,instacneSubnet,vol,Availabilityzone,deviceID,encrypted,Volumetype,Createtime,size,instanceName])

    

except Exception as e:

print("Some error occured in lambda_handler" + '\n' + str(e))



csvfile.close()

print (len(inst_name))

def lambda_handler(event, context): 


    date_fmt = strftime("%Y_%m_%d", gmtime())

    #Give your file path

    filepath ='/tmp/volume_report.csv'

    #filename ='report_Ireland'

    #Give your filename

    mail("Source mail ID","Recipient mail ID","Volume Notification","PFA The Volume resource on AWS Region.",filepath)

    #s3.Object('client-ami-report', filename+'_'+str(date_fmt)+'.csv').put(Body=open(filepath, 'rb'))

def mail(fromAddress,toAddress, subject, text, attach):

    

    #Multiple recipients could be there

    ###################################################################

    if(toAddress.find(',') > 1) :

        toAddress = toAddress.split(',')

    else :

        toAddress = list(toAddress.split())

    ###################################################################

    

    CHARSET = "UTF-8"

    msg = MIMEMultipart('alternative')

    msg['From'] = fromAddress

    msg['To'] = ','.join(toAddress)

    msg['Subject'] = subject

    text = MIMEText(text.encode(CHARSET), 'html', CHARSET)

    msg.attach(text)

    if(attach != None) :

        part = MIMEBase('application', 'octet-stream')

        part.set_payload(open(attach, 'rb').read())

        encoders.encode_base64(part)

        part.add_header('Content-Disposition','attachment; filename="%s"' % os.path.basename(attach))

        msg.attach(part)

    try:

        response = ses.send_raw_email(

            Source=fromAddress,

            Destinations=toAddress,

            RawMessage={

                'Data':msg.as_string(),

            },

        )   

    except Exception as e:

        print("Some Error has occured stating " + str(e))

    else:

        print("Email sent! Message ID: %s" % response['MessageId'])

    


AWS Volume encryption automatically for all instances for your AWS environment automatically using Shell Script :


About EBS volume Encryption:

EBS encryption as an encryption solution for your EBS resources associated with your aws EC2 instances. With Amazon EBS encryption, you aren't required to build, maintain, and secure your own key management infrastructure. Amazon EBS encryption uses AWS KMS keys when creating encrypted volumes for the ec2 servers.

Encryption operations occur on the servers that host EC2 instances, ensuring the security of both data-at-rest and data-in-transit between an instance and its attached EBS storage volume .

Problem Statement : 

Encrypt Volume encryption is an challenging task in an existing production environment which was  not build with encryption during the environment build . If its an 200 + instance then manually creating the AMI and attaching and detaching the volume manually will take lots of time and its an error prone . 

Solution :

So I decide to automate that task for my client which will detach the unencrypted volume and create an snapshot of the unencrypted volume , create an AWS volume by tracking the availability zone of the previous instance and attach the volume with the instance .   

Script :

Note : Server need to be ins stop state to detach the volume . Also you can add one more liner check in the below script to check if instance is online or in stop state . if you  need help please write back i will update the script

#!/bin/bash

#Script to update unencrypted volume on the account

# Place the input of volume Id to be delete in /tmp/volid.txt


us_region_name='your volume region name'

describe_vol="/usr/bin/aws ec2 describe-volumes"

describe_instance="/usr/bin/aws ec2 describe-instances"

create_snapshot="/usr/bin/aws ec2 create-snapshot"

describe_snapshots="/usr/bin/aws ec2 describe-snapshots"

create_volume="/usr/bin/aws ec2 create-volume"

attach_volume="/usr/bin/aws ec2 attach-volume"

detach_volume="/usr/bin/aws ec2 detach-volume"

create_tags="/usr/bin/aws ec2 create-tags"

kms_key="your KMS key"

for SNAP in `cat /tmp/volid.txt`

do

echo $SNAP


instance_id=`$describe_vol  --volume-ids $SNAP  --query Volumes[*].Attachments[*].InstanceId  --region $us_region_name  --output text`

Availabilityzone=`$describe_vol  --volume-ids $SNAP  --query Volumes[*].AvailabilityZone  --region $us_region_name  --output text`

attachment=`$describe_vol  --volume-ids $SNAP  --query Volumes[*].Attachments[*].Device  --region $us_region_name  --output text`

#instance-name=`$describe_instance --instnce-id $instance_id --query 'Reservations[].Instances[].[Tags[?Key==`Name`]| [0].Value]' --output table`

#instance-name=`\$describe_instance --instance-ids $instance_id --query 'Reservations[].Instances[].[Tags[?Key==`Name`]| [0].Value]' --region $us_region_name  --output text\`

$describe_instance --instance-ids $instance_id --query 'Reservations[].Instances[].[Tags[?Key==`Name`]| [0].Value]' --region $us_region_name  --output text > /tmp/instance-name

ins_name=$(cat /tmp/instance-name)

echo $instance_id

echo $attachment

echo $Availabilityzone

echo $ins_name


vol_name=$ins_name-$attachment:$instance_id


echo $vol_name


SNAP_vol=`$create_snapshot --volume-id $SNAP  --region $us_region_name --output text | awk '{print $3}'`


#SNAP=`$create-snapshot --volume-id $SNAP  --query SnapshotId --region $us_region_name --output text`


aws ec2 create-tags --resources $SNAP_vol --tags Key=Name,Value=$vol_name   --region $us_region_name

aws ec2 create-tags --resources $SNAP_vol --tags Key=Availabilityzone,Value=$Availabilityzone   --region $us_region_name

aws ec2 create-tags --resources $SNAP_vol --tags Key=InstanceID,Value=$instance_id  --region $us_region_name

aws ec2 create-tags --resources $SNAP_vol --tags Key=VolumeID,Value=$SNAP  --region $us_region_name

aws ec2 create-tags --resources $SNAP_vol --tags Key=attachment,Value=$attachment  --region $us_region_name


if [ $? -eq 0 ];

  then

  snap_list+=" $SNAP_vol"


else

  echo "SNAP creation is failed"

fi


done


#Snapshot availability check

for snap in $snap_list;

do

echo $snap

snap_status=`$describe_snapshots --snapshot-ids $snap --query  Snapshots[*].State --region $us_region_name --output text`

while [ "$snap_status" != "completed" ];

  do

    sleep 5

    echo "Test successful"

    snap_status=`$describe_snapshots --snapshot-ids $snap --query  Snapshots[*].State --region $us_region_name --output text`

  done

  $describe_snapshots --snapshot-ids $snap  --query 'Snapshots[*].{Name:Tags[?Key==`Availabilityzone`]|[0].Value}' --region $us_region_name --output text > /tmp/zone

  $describe_snapshots --snapshot-ids $snap  --query 'Snapshots[*].{Name:Tags[?Key==`Name`]|[0].Value}' --region $us_region_name --output text > /tmp/snp_name

  $describe_snapshots --snapshot-ids $snap  --query 'Snapshots[*].{Name:Tags[?Key==`InstanceID`]|[0].Value}' --region $us_region_name --output text > /tmp/InstanceID

  $describe_snapshots --snapshot-ids $snap  --query 'Snapshots[*].{Name:Tags[?Key==`VolumeID`]|[0].Value}' --region $us_region_name --output text > /tmp/VolumeID

  $describe_snapshots --snapshot-ids $snap  --query 'Snapshots[*].{Name:Tags[?Key==`attachment`]|[0].Value}' --region $us_region_name --output text > /tmp/attach

  zone=$(cat /tmp/zone)

  snap_name=$(cat /tmp/snp_name)

  InstanceID=$(cat /tmp/InstanceID)

  VolumeID=$(cat /tmp/VolumeID)

  attachment_deive=$(cat /tmp/attach)


  vol=`$create_volume --volume-type gp3 --snapshot-id $snap --availability-zone $zone  --encrypted --kms-key-id $kms_key --region $us_region_name --output text| awk '{print $10}'`

  aws ec2 create-tags --resources $vol --tags Key=Name,Value=$snap_name  --region $us_region_name

  sleep 5

  $detach_volume --volume-id $VolumeID --region $us_region_name --output text

  sleep 30

  $attach_volume --volume-id $vol --instance-id $InstanceID --device $attachment_deive --region $us_region_name --output text


  if [ $? -eq 0 ];

  then

    echo "snap is available. Replacing the encrypted volume of the instances"


  else

    echo "snap is not available"


fi


done

Note : Server need to be ins stop state to detach the volume . Also you can add one more liner check in the below script to check if instance is online or in stop state . if you  need help please write back i will update the script

 If you need to check the volume which is not encrypted in your account .Please check my other blog. 

Thursday, 25 May 2017

AWS VPC with a NAT Gateway Cloudformation code



{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "A VPC environment in two availability zones with an NAT Gateway.",
  "Parameters": {
    "envPrefix": {
      "Description": "Environment name prefix.",
      "Type": "String",
      "Default": "Test"
    },
    "vpcCidr": {
      "Description": "VPC CIDR block.",
      "Type": "String",
      "Default": "10.60.0.0/22",
      "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
      "ConstraintDescription": "Must be a valid IP CIDR range of the form x.x.x.x/x."
    },
    "publicSubnet1Cidr": {
      "Description": "Public subnet 1 CIDR block.",
      "Type": "String",
      "Default": "10.60.0.0/27",
      "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
      "ConstraintDescription": "Must be a valid IP CIDR range of the form x.x.x.x/x and subnet of VPC."
    },
"publicSubnet2Cidr": {
      "Description": "Public subnet 2 CIDR block.",
      "Type": "String",
      "Default": "10.60.0.32/27",
      "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
      "ConstraintDescription": "Must be a valid IP CIDR range of the form x.x.x.x/x and subnet of VPC."
    },
 
    "publicSubnet3Cidr": {
      "Description": "Public subnet 3 CIDR block.",
      "Type": "String",
      "Default": "10.60.0.64/27",
      "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
      "ConstraintDescription": "Must be a valid IP CIDR range of the form x.x.x.x/x and subnet of VPC."
    },
"publicSubnet4Cidr": {
      "Description": "Public subnet 4 CIDR block.",
      "Type": "String",
      "Default": "10.60.0.96/27",
      "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
      "ConstraintDescription": "Must be a valid IP CIDR range of the form x.x.x.x/x and subnet of VPC."
    },
    "privateSubnet1Cidr": {
      "Description": "Private subnet 1 CIDR block.",
      "Type": "String",
      "Default": "10.60.0.128/27",
      "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
      "ConstraintDescription": "Must be a valid IP CIDR range of the form x.x.x.x/x and subnet of VPC."
    },
"privateSubnet2Cidr": {
      "Description": "Private subnet 2 CIDR block.",
      "Type": "String",
      "Default": "10.60.0.160/27",
      "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
      "ConstraintDescription": "Must be a valid IP CIDR range of the form x.x.x.x/x and subnet of VPC."
    },
"privateSubnet3Cidr": {
      "Description": "Private subnet 3 CIDR block.",
      "Type": "String",
      "Default": "10.60.0.192/27",
      "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
      "ConstraintDescription": "Must be a valid IP CIDR range of the form x.x.x.x/x and subnet of VPC."
    },
"privateSubnet4Cidr": {
      "Description": "Private subnet 4 CIDR block.",
      "Type": "String",
      "Default": "10.60.0.224/27",
      "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
      "ConstraintDescription": "Must be a valid IP CIDR range of the form x.x.x.x/x and subnet of VPC."
    },
"privateSubnet5Cidr": {
      "Description": "Private subnet 5 CIDR block.",
      "Type": "String",
      "Default": "10.60.1.0/27",
      "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
      "ConstraintDescription": "Must be a valid IP CIDR range of the form x.x.x.x/x and subnet of VPC."
    },
"privateSubnet6Cidr": {
      "Description": "Private subnet 6 CIDR block.",
      "Type": "String",
      "Default": "10.60.1.32/27",
      "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
      "ConstraintDescription": "Must be a valid IP CIDR range of the form x.x.x.x/x and subnet of VPC."
    },
"privateSubnet7Cidr": {
      "Description": "Private subnet 7 CIDR block.",
      "Type": "String",
      "Default": "10.60.1.64/27",
      "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
      "ConstraintDescription": "Must be a valid IP CIDR range of the form x.x.x.x/x and subnet of VPC."
    },
"privateSubnet8Cidr": {
      "Description": "Private subnet 8 CIDR block.",
      "Type": "String",
      "Default": "10.60.1.96/27",
      "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
      "ConstraintDescription": "Must be a valid IP CIDR range of the form x.x.x.x/x and subnet of VPC."
    },
"privateSubnet9Cidr": {
      "Description": "Private subnet 9 CIDR block.",
      "Type": "String",
      "Default": "10.60.1.128/27",
      "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
      "ConstraintDescription": "Must be a valid IP CIDR range of the form x.x.x.x/x and subnet of VPC."
    },
"privateSubnet10Cidr": {
      "Description": "Private subnet 10 CIDR block.",
      "Type": "String",
      "Default": "10.60.1.160/27",
      "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
      "ConstraintDescription": "Must be a valid IP CIDR range of the form x.x.x.x/x and subnet of VPC."
    },
"privateSubnet11Cidr": {
      "Description": "Private subnet 11 CIDR block.",
      "Type": "String",
      "Default": "10.60.1.192/27",
      "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
      "ConstraintDescription": "Must be a valid IP CIDR range of the form x.x.x.x/x and subnet of VPC."
    },
"privateSubnet12Cidr": {
      "Description": "Private subnet 12 CIDR block.",
      "Type": "String",
      "Default": "10.60.1.224/27",
      "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
      "ConstraintDescription": "Must be a valid IP CIDR range of the form x.x.x.x/x and subnet of VPC."
    },

    "subnet1AZ": {
      "Description": "Subnet 1 availability zone.",
      "Type": "AWS::EC2::AvailabilityZone::Name"
    },
    "subnet2AZ": {
      "Description": "Subnet 2 availability zone.",
      "Type": "AWS::EC2::AvailabilityZone::Name"
    }
 
   },
 
  "Resources": {
    "vpc": {
      "Type": "AWS::EC2::VPC",
      "Properties": {
        "CidrBlock": {"Ref": "vpcCidr"},
        "InstanceTenancy": "default",
        "EnableDnsSupport": "true",
        "EnableDnsHostnames": "true",
        "Tags": [
          {
            "Key": "Name",
            "Value": {"Fn::Join" : ["-", [{"Ref" : "envPrefix"}, "VPC"]]}
          }
        ]
      }
    },
    "publicSubnet1": {
      "Type": "AWS::EC2::Subnet",
      "DependsOn": ["vpc", "attachGateway"],
      "Properties": {
        "CidrBlock": {"Ref": "publicSubnet1Cidr"},
        "AvailabilityZone": {"Ref" : "subnet1AZ"},
        "VpcId": {"Ref": "vpc"},
        "Tags": [
          {
            "Key": "Name",
            "Value": {"Fn::Join" : ["-", [{"Ref" : "envPrefix"}, "Subnet-Public-1"]]}
          }
        ]
      }
    },
 
    "publicSubnet2": {
      "Type": "AWS::EC2::Subnet",
      "DependsOn": ["vpc", "attachGateway"],
      "Properties": {
        "CidrBlock": {"Ref": "publicSubnet2Cidr"},
        "AvailabilityZone": {"Ref" : "subnet2AZ"},
        "VpcId": {"Ref": "vpc"},
        "Tags": [
          {
            "Key": "Name",
            "Value": {"Fn::Join" : ["-", [{"Ref" : "envPrefix"}, "Subnet-Public-2"]]}
          }
        ]
      }
    },
"publicSubnet3": {
      "Type": "AWS::EC2::Subnet",
      "DependsOn": ["vpc", "attachGateway"],
      "Properties": {
        "CidrBlock": {"Ref": "publicSubnet3Cidr"},
        "AvailabilityZone": {"Ref" : "subnet1AZ"},
        "VpcId": {"Ref": "vpc"},
        "Tags": [
          {
            "Key": "Name",
            "Value": {"Fn::Join" : ["-", [{"Ref" : "envPrefix"}, "Subnet-Public-3"]]}
          }
        ]
      }
    },

"publicSubnet4": {
      "Type": "AWS::EC2::Subnet",
      "DependsOn": ["vpc", "attachGateway"],
      "Properties": {
        "CidrBlock": {"Ref": "publicSubnet4Cidr"},
        "AvailabilityZone": {"Ref" : "subnet2AZ"},
        "VpcId": {"Ref": "vpc"},
        "Tags": [
          {
            "Key": "Name",
            "Value": {"Fn::Join" : ["-", [{"Ref" : "envPrefix"}, "Subnet-Public-4"]]}
          }
        ]
      }
    },

"privateSubnet1": {
      "Type": "AWS::EC2::Subnet",
      "DependsOn": ["vpc", "attachGateway"],
      "Properties": {
        "CidrBlock": {"Ref": "privateSubnet1Cidr"},
        "AvailabilityZone": {"Ref" : "subnet1AZ"},
        "VpcId": {"Ref": "vpc"},
        "Tags": [
          {
            "Key": "Name",
            "Value": {"Fn::Join" : ["-", [{"Ref" : "envPrefix"}, "Subnet-Private-1"]]}
          }
        ]
      }
    },

    "privateSubnet2": {
      "Type": "AWS::EC2::Subnet",
      "DependsOn": ["vpc", "attachGateway"],
      "Properties": {
        "CidrBlock": {"Ref": "privateSubnet2Cidr"},
        "AvailabilityZone": {"Ref" : "subnet2AZ"},
        "VpcId": {"Ref": "vpc"},
        "Tags": [
          {
            "Key": "Name",
            "Value": {"Fn::Join" : ["-", [{"Ref" : "envPrefix"}, "Subnet-Private-2"]]}
          }
        ]
      }
    },

"privateSubnet3": {
      "Type": "AWS::EC2::Subnet",
      "DependsOn": ["vpc", "attachGateway"],
      "Properties": {
        "CidrBlock": {"Ref": "privateSubnet3Cidr"},
        "AvailabilityZone": {"Ref" : "subnet1AZ"},
        "VpcId": {"Ref": "vpc"},
        "Tags": [
          {
            "Key": "Name",
            "Value": {"Fn::Join" : ["-", [{"Ref" : "envPrefix"}, "Subnet-Private-3"]]}
          }
        ]
      }
    },

"privateSubnet4": {
      "Type": "AWS::EC2::Subnet",
      "DependsOn": ["vpc", "attachGateway"],
      "Properties": {
        "CidrBlock": {"Ref": "privateSubnet4Cidr"},
        "AvailabilityZone": {"Ref" : "subnet2AZ"},
        "VpcId": {"Ref": "vpc"},
        "Tags": [
          {
            "Key": "Name",
            "Value": {"Fn::Join" : ["-", [{"Ref" : "envPrefix"}, "Subnet-Private-4"]]}
          }
        ]
      }
    },

"privateSubnet5": {
      "Type": "AWS::EC2::Subnet",
      "DependsOn": ["vpc", "attachGateway"],
      "Properties": {
        "CidrBlock": {"Ref": "privateSubnet5Cidr"},
        "AvailabilityZone": {"Ref" : "subnet1AZ"},
        "VpcId": {"Ref": "vpc"},
        "Tags": [
          {
            "Key": "Name",
            "Value": {"Fn::Join" : ["-", [{"Ref" : "envPrefix"}, "Subnet-Private-5"]]}
          }
        ]
      }
    },

"privateSubnet6": {
      "Type": "AWS::EC2::Subnet",
      "DependsOn": ["vpc", "attachGateway"],
      "Properties": {
        "CidrBlock": {"Ref": "privateSubnet6Cidr"},
        "AvailabilityZone": {"Ref" : "subnet2AZ"},
        "VpcId": {"Ref": "vpc"},
        "Tags": [
          {
            "Key": "Name",
            "Value": {"Fn::Join" : ["-", [{"Ref" : "envPrefix"}, "Subnet-Private-6"]]}
          }
        ]
      }
    },

"privateSubnet7": {
      "Type": "AWS::EC2::Subnet",
      "DependsOn": ["vpc", "attachGateway"],
      "Properties": {
        "CidrBlock": {"Ref": "privateSubnet7Cidr"},
        "AvailabilityZone": {"Ref" : "subnet1AZ"},
        "VpcId": {"Ref": "vpc"},
        "Tags": [
          {
            "Key": "Name",
            "Value": {"Fn::Join" : ["-", [{"Ref" : "envPrefix"}, "Subnet-Private-7"]]}
          }
        ]
      }
    },
"privateSubnet8": {
      "Type": "AWS::EC2::Subnet",
      "DependsOn": ["vpc", "attachGateway"],
      "Properties": {
        "CidrBlock": {"Ref": "privateSubnet8Cidr"},
        "AvailabilityZone": {"Ref" : "subnet2AZ"},
        "VpcId": {"Ref": "vpc"},
        "Tags": [
          {
            "Key": "Name",
            "Value": {"Fn::Join" : ["-", [{"Ref" : "envPrefix"}, "Subnet-Private-8"]]}
          }
        ]
      }
    },

"privateSubnet9": {
      "Type": "AWS::EC2::Subnet",
      "DependsOn": ["vpc", "attachGateway"],
      "Properties": {
        "CidrBlock": {"Ref": "privateSubnet9Cidr"},
        "AvailabilityZone": {"Ref" : "subnet1AZ"},
        "VpcId": {"Ref": "vpc"},
        "Tags": [
          {
            "Key": "Name",
            "Value": {"Fn::Join" : ["-", [{"Ref" : "envPrefix"}, "Subnet-Private-9"]]}
          }
        ]
      }
    },

"privateSubnet10": {
      "Type": "AWS::EC2::Subnet",
      "DependsOn": ["vpc", "attachGateway"],
      "Properties": {
        "CidrBlock": {"Ref": "privateSubnet10Cidr"},
        "AvailabilityZone": {"Ref" : "subnet2AZ"},
        "VpcId": {"Ref": "vpc"},
        "Tags": [
          {
            "Key": "Name",
            "Value": {"Fn::Join" : ["-", [{"Ref" : "envPrefix"}, "Subnet-Private-10"]]}
          }
        ]
      }
    },

"privateSubnet11": {
      "Type": "AWS::EC2::Subnet",
      "DependsOn": ["vpc", "attachGateway"],
      "Properties": {
        "CidrBlock": {"Ref": "privateSubnet11Cidr"},
        "AvailabilityZone": {"Ref" : "subnet1AZ"},
        "VpcId": {"Ref": "vpc"},
        "Tags": [
          {
            "Key": "Name",
            "Value": {"Fn::Join" : ["-", [{"Ref" : "envPrefix"}, "Subnet-Private-11"]]}
          }
        ]
      }
    },

"privateSubnet12": {
      "Type": "AWS::EC2::Subnet",
      "DependsOn": ["vpc", "attachGateway"],
      "Properties": {
        "CidrBlock": {"Ref": "privateSubnet12Cidr"},
        "AvailabilityZone": {"Ref" : "subnet2AZ"},
        "VpcId": {"Ref": "vpc"},
        "Tags": [
          {
            "Key": "Name",
            "Value": {"Fn::Join" : ["-", [{"Ref" : "envPrefix"}, "Subnet-Private-12"]]}
          }
        ]
      }
    },

    "inetGateway": {
      "Type": "AWS::EC2::InternetGateway",
      "DependsOn": ["vpc"],
      "Properties": {
        "Tags": [
          {
            "Key": "Name",
            "Value": {"Fn::Join" : ["-", [{"Ref" : "envPrefix"}, "InternetGateway"]]}
          }
        ]
      }
    },
    "attachGateway": {
      "Type": "AWS::EC2::VPCGatewayAttachment",
      "DependsOn": ["vpc", "inetGateway"],
      "Properties": {
        "VpcId": {"Ref": "vpc"},
        "InternetGatewayId": {"Ref": "inetGateway"}
      }
    },
    "rtbPublic": {
      "Type": "AWS::EC2::RouteTable",
      "DependsOn": ["vpc", "attachGateway"],
      "Properties": {
        "VpcId": {"Ref": "vpc"},
        "Tags": [
          {
            "Key": "Name",
            "Value": {"Fn::Join" : ["-", [{"Ref" : "envPrefix"}, "RTB-Public"]]}
          }
        ]
      }
    },
    "routePublic": {
      "Type": "AWS::EC2::Route",
      "DependsOn": ["rtbPublic"],
      "Properties": {
        "DestinationCidrBlock": "0.0.0.0/0",
        "RouteTableId": {"Ref": "rtbPublic"},
        "GatewayId": {"Ref": "inetGateway"}
      }
 
    },
    "subnetRouteTableAssociationPublic1": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "DependsOn": ["rtbPublic", "publicSubnet1"],
      "Properties": {
        "RouteTableId": {"Ref": "rtbPublic"},
        "SubnetId": {"Ref": "publicSubnet1"}
      }
    },
    "subnetRouteTableAssociationPublic2": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "DependsOn": ["rtbPublic", "publicSubnet2"],
      "Properties": {
        "RouteTableId": {"Ref": "rtbPublic"},
        "SubnetId": {"Ref": "publicSubnet2"}
      }
    },
"subnetRouteTableAssociationPublic3": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "DependsOn": ["rtbPublic", "publicSubnet3"],
      "Properties": {
        "RouteTableId": {"Ref": "rtbPublic"},
        "SubnetId": {"Ref": "publicSubnet3"}
      }
    },
"subnetRouteTableAssociationPublic4": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "DependsOn": ["rtbPublic", "publicSubnet4"],
      "Properties": {
        "RouteTableId": {"Ref": "rtbPublic"},
        "SubnetId": {"Ref": "publicSubnet4"}
      }
    },
    "rtbPrivate": {
      "Type": "AWS::EC2::RouteTable",
      "DependsOn": ["vpc"],
      "Properties": {
        "VpcId": {"Ref": "vpc"},
        "Tags": [
          {
            "Key": "Name",
            "Value": {"Fn::Join" : ["-", [{"Ref" : "envPrefix"}, "RTB-Private"]]}
          }
        ]
      }
    },
    "subnetRouteTableAssociationPrivate1": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "DependsOn": ["rtbPublic", "privateSubnet1"],
      "Properties": {
        "RouteTableId": {"Ref": "rtbPrivate"},
        "SubnetId": {"Ref": "privateSubnet1"}
      }
    },
    "subnetRouteTableAssociationPrivate2": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "DependsOn": ["rtbPublic", "privateSubnet2"],
      "Properties": {
        "RouteTableId": {"Ref": "rtbPrivate"},
        "SubnetId": {"Ref": "privateSubnet2"}
      }
    },
"subnetRouteTableAssociationPrivate3": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "DependsOn": ["rtbPublic", "privateSubnet3"],
      "Properties": {
        "RouteTableId": {"Ref": "rtbPrivate"},
        "SubnetId": {"Ref": "privateSubnet3"}
      }
    },
"subnetRouteTableAssociationPrivate4": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "DependsOn": ["rtbPublic", "privateSubnet4"],
      "Properties": {
        "RouteTableId": {"Ref": "rtbPrivate"},
        "SubnetId": {"Ref": "privateSubnet4"}
      }
    },
"subnetRouteTableAssociationPrivate5": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "DependsOn": ["rtbPublic", "privateSubnet5"],
      "Properties": {
        "RouteTableId": {"Ref": "rtbPrivate"},
        "SubnetId": {"Ref": "privateSubnet5"}
      }
    },
"subnetRouteTableAssociationPrivate6": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "DependsOn": ["rtbPublic", "privateSubnet6"],
      "Properties": {
        "RouteTableId": {"Ref": "rtbPrivate"},
        "SubnetId": {"Ref": "privateSubnet6"}
      }
    },
"subnetRouteTableAssociationPrivate7": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "DependsOn": ["rtbPublic", "privateSubnet7"],
      "Properties": {
        "RouteTableId": {"Ref": "rtbPrivate"},
        "SubnetId": {"Ref": "privateSubnet7"}
      }
    },
"subnetRouteTableAssociationPrivate8": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "DependsOn": ["rtbPublic", "privateSubnet8"],
      "Properties": {
        "RouteTableId": {"Ref": "rtbPrivate"},
        "SubnetId": {"Ref": "privateSubnet8"}
      }
    },
"subnetRouteTableAssociationPrivate9": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "DependsOn": ["rtbPublic", "privateSubnet9"],
      "Properties": {
        "RouteTableId": {"Ref": "rtbPrivate"},
        "SubnetId": {"Ref": "privateSubnet9"}
      }
    },
"subnetRouteTableAssociationPrivate10": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "DependsOn": ["rtbPublic", "privateSubnet10"],
      "Properties": {
        "RouteTableId": {"Ref": "rtbPrivate"},
        "SubnetId": {"Ref": "privateSubnet10"}
      }
    },
"subnetRouteTableAssociationPrivate11": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "DependsOn": ["rtbPublic", "privateSubnet11"],
      "Properties": {
        "RouteTableId": {"Ref": "rtbPrivate"},
        "SubnetId": {"Ref": "privateSubnet11"}
      }
    },
"subnetRouteTableAssociationPrivate12": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "DependsOn": ["rtbPublic", "privateSubnet12"],
      "Properties": {
        "RouteTableId": {"Ref": "rtbPrivate"},
        "SubnetId": {"Ref": "privateSubnet12"}
      }
    },
    "NAT" : {
  "DependsOn" : "rtbPrivate",
  "Type" : "AWS::EC2::NatGateway",
  "Properties" : {
    "AllocationId" : { "Fn::GetAtt" : ["EIP", "AllocationId"]},
    "SubnetId" : { "Ref" : "publicSubnet1"}
  }
},
"EIP" : {
  "Type" : "AWS::EC2::EIP",
  "Properties" : {
    "Domain" : "vpc"
  }
},
"routePrivate" : {
  "Type" : "AWS::EC2::Route",
  "DependsOn": ["rtbPrivate"],
  "Properties" : {
    "RouteTableId" : { "Ref" : "rtbPrivate" },
    "DestinationCidrBlock" : "0.0.0.0/0",
    "NatGatewayId" : { "Ref" : "NAT" }
  }
}
 

  }

}

Tuesday, 4 October 2016

AWS Volume tagging based on the block device

                                        AWS Volume tagging based on the block device 

#!/usr/bin/env python2


import boto3
REGION = 'ap-southeast-1'
client = boto3.client('ec2',REGION)


#instanceName=''

response = client.describe_volumes()
#response['Volumes'][0]['Attachments'][0]['VolumeId']
for i in response['Volumes']:
    for j in i['Attachments']:
        print "Volume_Id:"+ j['VolumeId']
        volume_id=j['VolumeId']
        print "Instance_Id:"+j['InstanceId']
        instance_id=j['InstanceId']
        print "Device:"+j['Device']
        device=j['Device']
        response = client.describe_instances(
           InstanceIds=[
               instance_id,
           ],
        )

        #print response
        for i in response['Reservations']:
            temp= i['Instances']
            #print temp
            for j in temp:
                #print j['InstanceId']
                for m in j['Tags']:
                    key=m['Key']
                    if (  key == 'Name' ):
                        print"InstanceName:"+ m['Value']+ "\n"
                        #global instanceName
                        instanceName=m['Value']
                   
                        response = client.create_tags(
                            DryRun=False,
                            Resources=[
                                volume_id,
                            ],
                            Tags=[
                                {
                                    'Key': 'Name',
                                    'Value':instanceName + ":" + device
                                },
                            ]
                        )

Create the Security Group rules using python boto API

                           Create the Security Group rules using python boto API
                                             
#!/usr/bin/env python

import boto3
import boto.ec2

#client = boto3.client('ec2',region_name="ap-southeast-1")
ec2 = boto3.resource('ec2',region_name="ap-southeast-1")
vpc = ec2.Vpc("vpc-a65187c3")
security_group = ec2.SecurityGroup('id')

web1 = vpc.create_security_group(
   DryRun=False,
   GroupName='Apache_5',
   Description='testing',
)
web1.authorize_ingress(IpProtocol="tcp",CidrIp="0.0.0.0/0",FromPort=80,ToPort=80)
web1.authorize_ingress(IpProtocol="tcp",CidrIp="0.0.0.0/0",FromPort=20,ToPort=21)
web1.authorize_ingress(IpProtocol="tcp",CidrIp="0.0.0.0/0",FromPort=443,ToPort=443)
web1.authorize_ingress(IpProtocol="tcp",CidrIp="0.0.0.0/0",FromPort=22,ToPort=22)
#web1.authorize_egress(IpProtocol="tcp",CidrIP="0.0.0.0/0",FromPort=443,ToPort=443)
print web1

conn = boto.ec2.connect_to_region("ap-southeast-1")
SG="Apache_5"
groups = conn.get_all_security_groups(filters={'group-name':[SG]})
for group in groups:
   print group.name
   for rule in group.rules:
       print rule.ip_protocol, rule.from_port, rule.to_port, rule.grants