Categories
Amazon Web Services Cloud Architecting Python Technology

Where Is It Five O’Clock Pt: 3

So I left this project at a point where I felt it needed to be re-architected based on the fact that Flask only executes the function once and not every time the page loads.

I re-architected the application in my head to include an API that calls the Lambda function and returns a list of places where it is and is not acceptable to be drinking based on the 5 O’Clock rules. These two lists will be JSON objects that have a single key with multiple values. The values will be the timezones appropriate to be drinking in.

After the JSON objects are generated I can reference them through the web frontend and display them in an appropriate way.

At this point I have the API built out and fully funcitoning the way I think I want it. You can use it by executing the following:
curl https://5xztnem7v4.execute-api.us-west-2.amazonaws.com/whereisit5

I will probably only have this publically accessible for a few days before locking it back down.

Hopefully, in part 4 of this series, I will have a frontend demo to show!

Categories
Amazon Web Services Cloud Architecting Networking Python Technology

Where Is It Five O’Clock Pt: 1

I bought the domain whereisitfiveoclock.net a while back and have been sitting on it for quite some time. I had an idea to make a web application that would tell you where it is five o’clock. Yes, this is a drinking website.

I saw this project as a way to learn more Python skills, as well as some more AWS skills, and boy, has it put me to the test. So I’m going to write this series of posts as a way to document my progress in building this application.

Part One: Building The Application

I know that I want to use Python because it is my language of choice. I then researched what libraries I could use to build the frontend with. I came across Flask as an option and decided to run with that. The next step I had to do was actually find out where it was 5PM.

In my head, I came up with the process that if I could first get a list of all the timezone and identify the current time in them I could filter out which timezones it was 5PM. Once establishing where it was 5PM, I can then get that information to Flask and figure out a way to display it.

Here is the function for identifying the current time in all timezones and then storing each key pair of {Timezone : Current_Time }

def getTime():
    now_utc = datetime.now(timezone('UTC'))
    #print('UTC:', now_utc)
    timezones = pytz.all_timezones
    #get all current times and store them into a list
    tz_array = []
    for tz in timezones:
        current_time = now_utc.astimezone(timezone(tz))
        values = {tz: current_time.hour}
        tz_array.append(values)
        
    return tz_array

Once everything was stored into tz_array I took that info and passed it through the following function to identify it was 5PM. I have another function that identifies everything that is NOT 5PM.

def find5PM():
    its5pm = []
    for tz in tz_array:
        timezones = tz.items()
        for timezone, hour in timezones:
            if hour >= 17:
                its5pm.append(timezone)
    return its5pm

I made a new list and stored just the timezone name into that list and return it.

Once I had all these together I passed them through as variables to Flask. This is where I first started to struggle. In my original revisions of the functions, I was only returning one of the values rather than returning ALL of the values. This resulted in hours of struggling to identify the cause of the problem. Eventually, I had to start over and completely re-work the code until I ended up with what you see above.

The code was finally functional and I was ready to deploy it to Amazon Web Services for public access. I will discuss my design and deployment in Part Two.

http://whereisitfiveoclock.net

Categories
Amazon Web Services Cloud Architecting Python

EC2 Action Slack Notification

I took a brief break from my Lambda function creation journey to go on vacation but, now i’m back!

This function will notify a Slack channel of your choosing when an EC2 instance enters “Starting, Stopping, Stopped, or Shutting-Down” status. I thought this might be useful for instances that reside under a load balancer. It would be useful to see when your load balancer is scaling up or down in real-time via Slack notification.

In order to use this function, you will need to create a Slack Application with an OAuth key and set that key as an environment variable in your Lambda function. If you are unsure of how to do this I can walk you through it!

Please review the function below

import logging
import requests
import boto3
import os
from urllib.parse import unquote_plus
from slack import WebClient
from slack.errors import SlackApiError
logging.basicConfig(level=logging.DEBUG)

# Check EC2 Status
def lambda_handler(event, context):
    detail = event['detail']
    ids = detail['instance-id']
    eventname = detail['state']
    ec2 = boto3.resource('ec2')
# Slack Variables
    slack_token = os.environ["slackBot"]
    client = WebClient(token=slack_token)
    channel_string = "XXXXXXXXXXXXXXXXXXXX"

# Post to slack that the instance is running
    if eventname == 'running':
        try:
          instance = ids
          response_string = f"The instance: {instance} has started"
          response = client.chat_postMessage(
            channel= channel_string,
          	text="An Instance has started",
           	blocks = [{"type": "section", "text": {"type": "plain_text", "text": response_string}}]
	        	)
        except SlackApiError as e:
          assert e.response["error"]  

		#Post to slack that instance is shutting down
    elif eventname == 'shutting-down':
    	try:
	        instance = ids
	        response_string = f"The instance: {instance} is shutting down"
	        response = client.chat_postMessage(
	        	channel= channel_string,
	        	text="An Instance is Shutting Down",
	        	blocks = [{"type": "section", "text": {"type": "plain_text", "text": response_string}}]
	        	)
    	except SlackApiError as e:
           assert e.response["error"]
	      	
    elif eventname == 'stopped':
    	try:
	        instance = ids
	        response_string = f"The instance: {instance} has stopped"
	        response = client.chat_postMessage(
	        	channel= channel_string,
	        	text="An Instance has stopped",
	        	blocks = [{"type": "section", "text": {"type": "plain_text", "text": response_string}}]
	        	)
    	except SlackApiError as e:
    		assert e.response["error"]
	      	
    elif eventname == 'stopping':
    	try:
	        instance = ids
	        response_string = f"The instance: {instance} is stopping"
	        response = client.chat_postMessage(
	        	channel= channel_string,
	        	text="An Instance is stopping",
	        	blocks = [{"type": "section", "text": {"type": "plain_text", "text": response_string}}]
	        	)
    	except SlackApiError as e:
    		assert e.response["error"]

As always the function is available on GitHub as well:
https://github.com/avansledright/ec2ActionPostToSlack

If you find this function helpful please share it with your friends or repost it on your favorite social media platform!

Categories
Amazon Web Services Cloud Architecting Python

Check EC2 Instance Tags on Launch

In my ever-growing quest to automate my AWS infrastructure deployments, I realized that just checking my tags wasn’t good enough. I should force myself to put tags in otherwise my instances won’t launch at all.

I find this particularly useful because I utilize AWS Backup to do automated snapshots nightly of all of my instances. If I don’t put the “Backup” tag onto my instance it will not be included in the rule. This concept of forced tagging could be utilized across many different applications including tagging for development, production, or testing environments.

To do this I created the Lambda function below. Utilizing EventBridge I have this function every time there is an EC2 instance that enters the “running” state.

import json
import boto3

def lambda_handler(event, context):
    detail = event['detail']
    ids = detail['instance-id']
    eventname = detail['state']
    ec2 = boto3.resource('ec2')
    
    while eventname == 'Running':
        print(ids)       
    #Check to see if backup tag is added to the instance
        tag_to_check = 'Backup'
        instance = ec2.Instance(ids)
        for tag in instance.tags:
            if tag_to_check not in [t['Key'] for t in instance.tags]:
                instance.stop()
                print("Stopping Instance: ", instance)
    #Get instance state to break the infinite loop
                state = instance.state['Name']          
                if state == "shutting-down":
                    print("instance is shutting-down")
                    break
                elif state == "stopped":
                    print("Instance is already stopped")
                    break
                elif state == "stopping":
                    print("instance is stopping")
                    break
        break
            

The function then will check the status of the instance to ensure that it is stopped and then break the loop.

You can clone the repository from GitHub here:
https://github.com/avansledright/aws-force-ec2-launch-tags

If you utilize the script please share it with your friends. Feel free to modify it as you please and let me know how it works for you! As always, if you have any questions feel free to reach out here or on any other platform!

Categories
Amazon Web Services Cloud Architecting Python Technology

Automatically Transcribing Audio Files with Amazon Web Services

I wrote this Lambda function to automatically transcribe audio files that are uploaded to an S3 bucket. This is written in Python3 and utilizes the Boto3 library.

You will need to give your Lambda function permissions to access S3, Transcribe and CloudWatch.

The script will create an AWS Transcribe job with the format: 'filetranscription'+YYYYMMDD-HHMMSS

I will be iterating over the script to hopefully add in a web front end as well as potentially branching to do voice call transcriptions for phone calls and Amazon Connect.

You can view the code here

If you have questions or comments feel free to reach out to me here or on any Social Media.

Categories
Amazon Web Services

The Security Specialty Certification

Today I sat the AWS Security Specialty Exam. While I didn’t pass I thought to provide some commentary on the experience in relation to the training that I sought out to assist myself in the process.

I have been a big fan of ACloudGuru.¬†They helped me pass my Solutions Architect exam last year so naturally, I returned to train and learn from them again. Much of the content that I found in this course I found to be a repeat of what I saw in the Solutions Architect material. I didn’t think much of it because I assumed this to be the correct curriculum.

Boy was I wrong.

Upon sitting down at the exam center I utilized my standard method of test taking. Answer the questions that you know the answer to first and then go back and hammer out the harder ones using the process of elimination and your knowledge.

Ryan Kroonenburg does a great job of explaining all the features of AWS and how to utilize them in a lab environment, we miss the actual application level that AWS is asking for in the exam. Now, I’m not saying that Ryan doesn’t know what he is talking about. Quite the contrary. Nor am I blaming my failure on ACloudGuru.

Advice

On top of learning all the content outlined in ACloudGuru or LinuxAcademy or whichever training resource you want to utilize, you really need to seek out real life application to these topics. 

I will be going back over all the labs in the training material and applying them into my product environments (after testing). I think that this is the only way to truly learn what is needed.

Current Exam Rankings

Hardest to Easiest (based on what I’ve taken):

  1. Security Specialty
  2. Solutions Architect Associate
  3. SysOps Associate

If you have any questions regarding the exams feel free to reach out!