Archive for the ‘Scripts’ Category

Let’s say we have this AWS CloudWatch event

2.PNG

And we have tagged EC2 instance with AutoStopSchedule tag, values between 1-5

1.PNG

Following Lambda function will get cron expression from CloudWatch event and will dynamically filter which instances should be turned off

import boto3
import logging

# define rule name
rule_name = "stop_ec2"

#setup simple logging for INFO
logger = logging.getLogger()
logger.setLevel(logging.INFO)

#define the connection
ec2 = boto3.resource('ec2')

# connect to Clouwatch events
client = boto3.client('events')

def lambda_handler(event, context):
   # get cron expression for Specific CloudWatch rule
   response = client.describe_rule(Name=rule_name)
   expression = response['ScheduleExpression']

   # based on current expression create filter variable and populate it with value in range 1-5
   if "cron(20 * * * ? *)" in expression:
      filter = "1"
   elif "cron(0 */1 * * ? *)" in expression:
      filter = "2"
   elif "cron(0 */6 * * ? *)" in expression:
      filter = "3"
   elif "cron(0 */12 * * ? *)" in expression:
      filter = "4"
   elif "cron(0 10 * * ? *)" in expression:
      filter = "5"
   else:
      filter = "0"

   # Use the filter() method of the instances collection to retrieve
    # all running EC2 instances.
   filters = [

        {
            'Name': 'tag:AutoStopSchedule',
            'Values': [filter]
        },
        {
            'Name': 'instance-state-name',
            'Values': ['running']
        }
       ]
    #filter the instances
    #ec2 = boto3.client('ec2', region_name=region)
   instances = ec2.instances.filter(Filters=filters)

    #locate all running instances
   RunningInstances = [instance.id for instance in instances]

    #print the instances for logging purposes
   print (RunningInstances) 

    #make sure there are actually instances to shut down.
   if len(RunningInstances) > 0:
        #perform the shutdown
        shuttingDown = ec2.instances.filter(InstanceIds=RunningInstances).stop()
        #print shuttingDown
   else:
    print "Nothing to see here"

Make sure IAM policy has following

 
{"Action": [

"events:DescribeRule"
],
"Effect": "Allow",
"Resource": "*"
}
Advertisements

This script will search for any email with “Darktrace” in subject and if it find any will move it to Archive folder, all other emails will be moved to test folder

 

#!/usr/bin/python

import email, imaplib
user = 'user@example.com'
pwd = 'Pass'

conn = imaplib.IMAP4_SSL("outlook.office365.com")
conn.login(user,pwd)
conn.select("Inbox")
output=[]
resp, items = conn.uid("search",None, 'All')
items = items[0].split()
for emailid in items:
resp, data = conn.uid("fetch",emailid, "(RFC822)")
if resp == 'OK':
email_body = data[0][1].decode('utf-8')
mail = email.message_from_string(email_body)
#if mail.get_content_maintype() != 'multipart':
#continue
if mail["Subject"].find("Darktrace") > 0:
result = conn.uid('COPY', emailid, "Archive")
output.append(result)
if result[0] == 'OK':
result = mov, data = conn.uid('STORE',emailid, '+FLAGS', '(\Deleted Items)')
#print result
conn.expunge()
else:
result1 = conn.uid('COPY', emailid, "test")
if result1[0] == 'OK':
result1 = mov, data = conn.uid('STORE',emailid, '+FLAGS', '(\Deleted Items)')
conn.expunge()
#out="\n\n".join(output)
print output
conn.close()
conn.logout()

In this post we configured Windows instances to go to hibernation. In this one we’ll modify Node.JS script to shut down EC2 instances if no one is connected via SSH connections.

Setting SSH idle timeout settings

cat /etc/profile.d/ssh-timeout.sh
export TMOUT=900
readonly TMOUT

Reboot

 

Installing SSM Agent on CentOS 7

yum install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm
systemctl status amazon-ssm-agent
systemctl enable amazon-ssm-agent
systemctl start amazon-ssm-agent

How to create SSM role and how to assign it to instance check out here. and here

Create following tags:

 

Capture

 

Change only code in auto_stop/modules/control/index.js

// Import Dependencies
let AWS = require('aws-sdk');
AWS.config.region = "eu-west-1";

module.exports.getInstanceIds = () => {
return new Promise(
(resolve, reject) => {
let ec2 = new AWS.EC2();
let params = {
Filters: [
{ Name: "instance-state-name",
Values: ["running"]
},
{
Name: "tag:Auto_Stop_Schedule",
Values: ["1"]
},
{
Name: "tag:Auto_Stop_Enabled",
Values: ["True","true", "Yes", "yes"]
},
{
Name: "tag:Auto_Stop_Type",
Values: ["Linux","linux"]
}
]
};

ec2.describeInstances(params, (err, data) => {
if (err) reject(err);

let instanceIds = [];
let reservations = "";
try {
reservations = data.Reservations;
}
catch(err) {
reject(err);
}
if(Array.isArray(reservations)) {
reservations.forEach((reservation) => {
reservation.Instances.forEach((instance) =>{
instanceIds.push(instance.InstanceId);
});
});
if(instanceIds.length >= 1) {
resolve(
{
"InstanceIds": instanceIds
}
);
}
else {
console.log("[Info] getInstanceIds: No instances found.");
resolve();
}
}
else {
reject(new Error("[Error] getInstanceIds: Reservations is not an array."));
}
});
}
);
};

module.exports.shutdownInstances = (controlObj) => {
return new Promise(
(resolve, reject) => {
let ssm = new AWS.SSM();

let instanceIds = controlObj.InstanceIds;
instanceIds.forEach((i) => {
let ssmParams = {
InstanceIds: [i],
DocumentName: "AWS-RunShellScript",
Parameters: {
"workingDirectory":[""],
"executionTimeout":["300"],
"commands":["#!/bin/bash","LOGFOLDER=\"/var/log/ssh_check\"","LOGFILE=\"auto_stop_activity.log\"","","# Check if the ssh_check Log dir exists. If not, create it.","[ -d $LOGFOLDER ] || mkdir -p $LOGFOLDER","","if [[ \"$(/usr/bin/w | wc -l)\" -gt 2 ]];"," then"," echo \"$(date) >>> Live SSH session detected\" "," echo \"$(date) >>> Live SSH session detected\" >> \"$LOGFOLDER/$LOGFILE\""," else"," # If no active SSH sessions are found, shutdown the instance."," echo \"$(date) >>> No running sessions detected\" "," echo \"$(date) >>> Shutting down...\"",""," echo \"$(date) >>> No running sessions detected\" >> \"$LOGFOLDER/$LOGFILE\" "," echo \"$(date) >>> Shutting down...\" >> \"$LOGFOLDER/$LOGFILE\" "," shutdown -P -t 30 > /dev/null 2>&1"," exit 0"," fi"]
},
MaxErrors: "0",
TimeoutSeconds: 120
}

// Hibernate instances
ssm.sendCommand(ssmParams, function(err, data) {
if (err) {
console.log(`Error: ${err}`);
}
console.log("Command Sent");
console.log(`Instance to shutdown: ${instanceIds}`);
});
});
}
);
};

 

import boto3
ec2 = boto3.resource('ec2',region_name='eu-west-1')
def lambda_handler(event, context):
     for vol in ec2.volumes.all():
      if vol.state=='available':
        for tag in vol.tags:
         if tag in vol.tags or tag==None:
           print "VolumeID:"+ vol.id, "Volume Name:"+tag['Value'] + " AWS Region:Ireland"

 

 

This Python boto3 script will get notification if instances are stopped for more than 30 days

import json
import boto3
import re
import smtplib
import datetime
import time
from datetime import datetime
from datetime import date
from dateutil.relativedelta
import relativedeltainstance_ids = []
instance_names = []
stopped_reasons = []
output=[]
transition_timestamps=[]
ses = boto3.client('ses')
def send_mail(email_from, email_to, subject, body):
smtp_address = 'smtp.office365.com'
provider_username = 'sender@example.com'
provider_password = 'Pass'
smtpserver = smtplib.SMTP(smtp_address, 587)
smtpserver.ehlo()
smtpserver.starttls()
smtpserver.ehlo() # extra characters to permit edit
smtpserver.login(provider_username, provider_password)
header = 'To: ' + email_to + '\n' + 'From: ' + email_from + '\n' + 'Subject: ' + subject + '\n'
msg = header + '\n ' + body + ' \n\n'
smtpserver.sendmail(provider_username, email_to, msg)
smtpserver.quit()
def lambda_handler(event, context):
 client = boto3.client('ec2',region_name='eu-west-2')
 reservations = client.describe_instances().get('Reservations', [])
 for reservation in reservations:
    for instance in reservation['Instances']:
      tags = {}
      for tag in instance['Tags']:
            tags[tag['Key']] = tag['Value']
            if tag['Key'] == 'Name':
                name=tag['Value']
    if instance['State']['Name'] == 'stopped':
       instance_ids.append(instance['InstanceId'])
       instance_names.append(name)
       stopped_reason = instance['StateTransitionReason']
       stopped_reasons.append(stopped_reason)
       transition_timestamp = datetime.strptime(instance['StateTransitionReason'][16:39], '%Y-%m-%d %H:%M:%S %Z')
       transition_timestamps.append(str(transition_timestamp))
       days=(datetime.now() - transition_timestamp).days
       if days > 30:
          a = "InstanceID:" + instance['InstanceId'] + "," + ' Instance Name:' +name + "," + " Shutdown Time: "+str(transition_timestamp)
          output.append(a)
body= "\n\n".join(output)
if body:
emailbody = "The following instances are stopped for more than 30 days in London region\n\n\n\n" +body + "\n\n\n If instances are not needed anymore please terminate it or start it otherwise"
send_mail('sender@example.com', 'recipient@example.com', 'Notification of stopped instances', emailbody)

On SQL server create stored procedure for collecting Job status:

CREATE PROCEDURE [dbo].[usp_job_server_error] @job_name VARCHAR(100) AS
BEGIN
SET NOCOUNT ON
SELECT j.NAME AS '[JOB]',
CASE
WHEN jh.run_statusIN ( 0, 1, 2, 3, 4 ) THEN jh.run_status
ELSE ( CASE
WHEN ja.run_requested_dateIS NOT NULL
AND ja.stop_execution_dateIS NULL THEN 4
ELSE -1
END ) END  AS '[STATUS]',
ja.run_requested_date AS '[LAST_EXECUTION]'
WHERE  ja.session_id = (SELECT Max(session_id)
AND j.enabled = 1
AND j.name = ISNULL(@job_name, j.name)
--AND (j.name LIKE ISNULL(@identifier, 'HIGH')+'%' OR j.name LIKE ISNULL(@identifier, 'DISASTER')+'%')
SET NOCOUNT OFF
END;
GO

Script for getting data from stored procedure and sending it to Zabbix:

 

$data = $(foreach ($line in sqlcmd -Q "exec dbo.usp_job_server_error @job_name=sql job" -E -s ":") { $l=$line.split()[0]; $s=$line.split(":")[1] ; "$s"})
$result=$data[2..$data.length]
cd "C:\Program Files\Zabbix Agent\bin\win64"
.\zabbix_sender.exe-z zabbix_server -p 10051 -s zabbix_host -c "C:\Program Files\Zabbix Agent\conf\zabbix_agentd.win.conf" -k sql.job[myjob]-o $result -vv
Create Zabbix item:
5.PNG
And trigger:
{server:sql.job[myjob].last()}=0
Schedule above script with Task Scheduler:

Program/script: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe

Add argument: -file “C:\File\Scripts\jobstatus.ps1”

Start In: C:\File\Scripts

 

This code will list all EC2 instances for every region and if termination protection is enabled, it will be disabled

import json
import boto3
def lambda_handler(event, context):
  client = boto3.client('ec2')
  ec2_regions = [region['RegionName'] for region in client.describe_regions()['Regions']]
  for region in ec2_regions:
     client = boto3.client('ec2', region_name=region)
     conn = boto3.resource('ec2',region_name=region)
     instances = conn.instances.filter()
     for instance in instances:
       if instance.state["Name"] == "running":
       #print instance.id # , instance.instance_type, region)
        terminate_protection=client.describe_instance_attribute(InstanceId =instance.id,Attribute = 'disableApiTermination')
        protection_value=(terminate_protection['DisableApiTermination']['Value'])
        if protection_value == True:
          client.modify_instance_attribute(InstanceId=instance.id,Attribute="disableApiTermination",Value= "False" )