I summarized it because there was a part I was addicted to when I tried to automatically start an instance with an encrypted EBS root volume using Lambda.
EBS currently supports encryption of the root volume of an instance, as described in the article below. http://aws.typepad.com/aws_japan/2015/12/new-encrypted-ebs-boot-volumes.html This time, I will write about the points I was addicted to when automatically starting an instance with this root volume encryption.
This time I was trying to automate the launch of an instance using AWS Lambda. The script used is the following instance startup batch created based on Lambda function (python) that takes AMI backup. You can also find it on GitHub along with the stop. https://github.com/tatsuo48/Hello-world/tree/master/LambdaFunctions
startinstance.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
import json
import boto3
import pprint
TAG_KEY_AUTO_START = 'auto-start'
print('Loading function')
pp = pprint.PrettyPrinter(indent=4)
#Function name: lambda_handler
def lambda_handler(event, context):
print("Received event: " + json.dumps(event, indent=2))
ec2_client = boto3.client('ec2')
ret = execute_start_instance(ec2_client)
print 'Start instance success(%s).' % (ret)
return 0
raise Exception('Something went wrong')
#Function name: execute_start_instance
#Return value: Execution result
#Arguments: ec2_client
# : ec2_resource
#Function: Start an instance.
def execute_start_instance(ec2_client):
response = ec2_client.describe_instances()
result = None
for ec2_group in response['Reservations']:
for instance_info in ec2_group['Instances']:
ret = is_target(instance_info)
if (ret == False):
continue
instance_id = instance_info.get('InstanceId')
response = ec2_client.start_instances(InstanceIds=[instance_id,])
print response
result = True
return result
#Function name: is_target
#Return value: Whether to start
#Arguments: instance_info <dict>
#Function: Judge whether startup is necessary
def is_target(instance_info):
val = get_tag_value(
instance_info,
TAG_KEY_AUTO_START
)
if val is None:
return False
return True
#Function name: get_tag_value
#Return value: Tag value (None if there is no match for the key)
#Arguments: instance_info <dict>
# : key <str>
#Function: Get the tag value of the specified key from the instance information
def get_tag_value(instance_info, key):
tags = instance_info.get('Tags')
if tags == None:
return None
for tag in tags:
if not (key == tag['Key']):
continue
tag_value = tag['Value']
if tag_value == "true":
return True
return None
However, no matter how many times I executed the Lambda function, the instance did not start even though the correct response was returned as below. .. .. ..
{u'StartingInstances': [{u'InstanceId': 'Instance ID', u'CurrentState': {u'Code': 0, u'Name': 'pending'}, u'PreviousState': {u'Code': 80, u'Name': 'stopped'}}], 'ResponseMetadata': {'HTTPStatusCode': 200, 'RequestId': 'kkksfh084k-l9hh-8iy6-hshs4-ipsug88w9hwh'}}
I did a lot of research, but the cause was very simple. The execution permission of KMS (Key Management Service) was missing. .. This time, I created and used the encryption key myself instead of the default key. In that case, it was necessary to allow the use of the key by the "key user" of the corresponding encryption key or the policy of the execution role. If you want to set it as the "key user" of the encryption key, you can set it with the GUI as follows.
The execution role policy would be like this.
When setting in the execution role policy
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1236596007000",
"Effect": "Allow",
"Action": [
"kms:*"
],
"Resource": [
"ARN of the created key"
]
}
]
}
The cause is quite natural, but it is difficult to get to that point if it is a function that you do not normally use. I thought that I should continue to touch functions that I haven't touched, both inside and outside the business.
Recommended Posts