AWS Development — Chalice Framework — 5 minutes for Lambda and API Gateway

Since first days in my IT career I was struggling between 2 choices to be infrastructure administrator or developer — I like both. Circumstances pushed me to be infrastructure administrator, and for some time development was just my hobby.
In recent years I was discovering more and more tools from AWS, which was bringing my dream to be developer and infrastructure administrator at the same time — tools making Infrastructure as code reality.

One of the tools is AWS Chalice framework

Best definition of Chalice Framework is:

AWS Chalice is a Python Serverless Microframework for AWS and allows you to quickly create and deploy applications that use Amazon API Gateway and AWS Lambda.

Chalice provides developers with the options:

  1. Quick deploy resources using integrated deploy tool
  2. Test code locally

Administrators can integrate and deploy Chalice application using CDK, Cloud Formation, Terraform . See AWS blog for CDK deployment

There is always question: Which tool to use — Chalice, SAM, CDK, Flask?

Chalice is suitable for small quick deployment:

  1. Developer — to quick test applications.
  2. Deployment in small environment

The scenario #2 is why I exactly decided to use Chalice.
Talking to customer about his EC2 instance pricing, I got the requirements which must be met:

  • Windows Server with 2 remote users to login
  • No Inbound open ports in Security group — Y-e-e-h!
  • No VPN — Guess — this is from Step above
  • Outgoing connections are allowed.
  • Time zones PST/EST/CET — USA/Europe
  • 5 min is ok to start server
  • Server needs to be fast, and we need to save money — Y-e-e-h!
  • No server management from customer

Solution:

  1. Deploy Lambda and API Gateway which will start/stop instance when users connect to server — this will save cost, as total server usage is not expected to be more than 12 hours.
  2. Configure customer side with SSM management plugin installed, and script to start server
  3. Stop EC2 instance when no user activity for an hour — script inside windows server

Implementation: Step 1

  • Docker container with Chalice installed — We are always using containers for Development environment. See Docker file
  • Start container

docker run -v ~/chalice:/root/chalice -v /root/.aws:/root/.aws/ -it -p 2022:22 ubuntu:chalice /bin/bash

chalice new-project control-ec2

cd control-ec2

python3 -m pip show boto3|grep Version|sed 's/Version: /boto3==/'>>requirements.txt #this will add the latest boto3 version to requirements for local testing. You do not to do this if you are ok with code

  • Edit app.py file:

from chalice import Chalice
import boto3
app = Chalice(app_name='control-ec2')

@app.authorizer(ttl_seconds=30)
def my_auth(auth_request):
# Validate auth_request.token, and then:
return AuthResponse(routes=['/'], principal_id='arn:aws:::xxxxxxxxxx:root/*')

# Create route to start instance
@app.route('/start/{name}', authorizer=my_auth)
def instance(name):
instances = [name]
ec2 = boto3.client('ec2', region_name='us-west-2')
ec2.start_instances(InstanceIds=instances)
return {'InstanceId started': name}

# Create route to stop instance
@app.route('/stop/{name}', authorizer=my_auth)
def instance_stop(name):
instances = [name]
ec2 = boto3.client('ec2', region_name='us-west-2')
ec2.stop_instances(InstanceIds=instances)
return {'InstanceId stopped': name}

What we are doing here:

  • Creating Authorizer which allows only IAM user to invoke API method
  • 2 functions to start/stop EC2 instances based on instance Id passed

Note: Change region in boto3 clients and principal id to whatever role/username you need
principal_id='arn:aws:::xxxxxxxxxx:root/*')

In less than 5 minutes you have it ready

How to invoke API?

*Method 1:
Python code

import requests
from requests_aws_sign import AWSV4Sign
from boto3 import session

session = session.Session()
credentials = session.get_credentials()
region = session.region_name
service = 'execute-api'

url = "REPLACE_THIS_LINE_WITH_URI_AND_INSTANCE_ID"
auth = AWSV4Sign(credentials, region, service)
response = requests.get(url, auth=auth)
print(response.text)

Note: you need to modify code to pass instance Id, or explicitly specify URLs with instance ID — e.g. 2 files to start and stop instance

aws apigateway test-invoke-method --rest-api-id API_ID --resource-id RESOURCE_ID --http-method GET --path-with-query-string /stop/<instanceId here>

— rest-api-id — returned after chalice deploy or cat .chalice/deployed/prod.json
--resource-id - find in console on particular method , or from
aws apigateway get-resources --rest-api-id API_ID

From solution we implemented only Step 1.
Stay tune how to configure customer side for Steps 2 and 3

Originally published at https://dev.to on September 7, 2020.

--

--

--

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Discord is for Your Communities

Using Codemagic CI/CD for React Native apps

Detecting Player with the Security Cameras (Made with Unity)

Team Updates — New Twitch channels and more (oh my!)

Rewind Dev Log #3

[TWIL: 2019–05–12]Slow Is Fast (hope so)

Why RxSwift may NOT be the solution you are looking for.

The 4 Keyboards I Have Installed on my Mobile Devices

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
John Gakhokidze

John Gakhokidze

More from Medium

Using an EV to generate passive income: a modelled case study.

How mobility app HumanForest is using gamification to make the world a better place

Clone for H&M website

E-Prescribing Software with cloud infrastructure gives bigger features.