##TL;DR
- 検証環境など複数メンバーで利用していると、管理者不明のリソースが発生することがある。
- LambdaでEC2起動時にタグ付けする解決策が一般的だと思うが、
複数の環境/リージョンがあると都度登録するのも面倒。 - ServerlessFramework を使って誰でも簡単に実装できるようにした。
※本稿ではServerlessFrameworkの導入手順は触れていないので
導入方法は公式ドキュメントを参照してください。
##1. Lambda関数の準備
- 起動者の情報をタグ付けするLambda関数ファイル(コードは後述)を用意します。
- 今回はIAMユーザーとAssumeRoleしているユーザーに対応させています。
handler.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import boto3
import logging
import os
# set the simple logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
region = os.environ['AWS_REGION']
account = os.environ['AWS_ACCOUNT']
def ec2_tagging(event, context):
logger.info(event)
# Requestor Check
userType = event['detail']['userIdentity']['type']
if userType == 'IAMUser':
Owner = event['detail']['userIdentity']['userName']
elif userType == 'AssumedRole':
roleID = event['detail']['userIdentity']['sessionContext']['sessionIssuer']['userName']
Owner = (event['detail']['userIdentity']['arn'].replace("arn:aws:sts::" + str(account) + ":assumed-role/"+str(roleID)+"/", ""))
logger.info("Owner: " + Owner)
# Target Resource Check
instanceIDs = event['detail']['responseElements']['instancesSet']['items']
logger.info(instanceIDs)
instance_count = len(instanceIDs)
try:
for i in range(0, instance_count):
instanceID = instanceIDs[i]['instanceId']
logger.info("target: " + str(instanceID))
ec2 = boto3.client('ec2')
r = ec2.create_tags(
Resources=[instanceID],
Tags=[
{
'Key': 'Owner',
'Value': Owner
},
]
)
except Exception as e:
logger.error("error: " + str(e))
##2. Lambda実行用のIAM Role作成
- Lambda実行に必要となる下記権限を有するIAMロールを準備します。
- CloudwachLogへのログ書き込みの権限
- EC2にタグを付与する権限
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": [
"arn:aws:logs:*"
],
"Effect": "Allow"
},
{
"Action": [
"ec2:CreateTags"
],
"Resource": [
"*"
],
"Effect": "Allow"
}
]
}
##3. serverless.ymlの作成
- serverless.ymlでLambda関数の設定を定義しています。
- Lambda関数ファイルがあるディレクトリにserverless.yml(内容は後述)を配置します。
- 環境に応じて修正が必要なパラメータは
custom
ブロックにまとめましたので、
AWS AccountIDやリージョン、手順2で作成したIAMロール名等を修正してください。
serverless.yml
service: ${self:custom.service}
provider:
name: aws
runtime: python3.6
stage: ${opt:stage, self:custom.defaultStage}
region: ${opt:region, self:custom.defaultRegion}
memorySize: 128
timeout: 60
role: arn:aws:iam::${self:custom.account}:role/${self:custom.iam}
environment:
AWS_ACCOUNT: ${self:custom.account}
custom:
account: hoge ## AWS AccountIDを入力してください。
defaultStage: dev
defaultRegion: fuga ## Regionを入力してください。(e.g.ap-northeast-1)
description: EC2 Auto Tagging Function
service: Ec2AutoTag
iam: piyo ## Lambdaを実行するIAM Role名を入力してください。
functions:
Ec2AutoTag:
name: ${self:custom.service}
handler: handler.ec2_tagging
description: ${self:custom.description}
events:
- cloudwatchEvent:
event:
source:
- "aws.ec2"
detail-type:
- "AWS API Call via CloudTrail"
detail:
eventSource:
- "ec2.amazonaws.com"
eventName:
- "RunInstances"
##4. deploy
Lambda関数ファイルがあるディレクトリにてデプロイコマンド sls deploy
を実行するだけです。
$ ls -l
total 8
-rw-rw-r-- 1 ubuntu ubuntu 1453 Aug 29 02:56 handler.py
-rw-rw-r-- 1 ubuntu ubuntu 1012 Aug 29 03:00 serverless.yml
$
$ sls deploy
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Creating Stack...
Serverless: Checking Stack create progress...
.....
Serverless: Stack create finished...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service .zip file to S3 (774 B)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
...................
Serverless: Stack update finished...
Service Information
service: Ec2AutoTag
stage: dev
region: ap-northeast-1
stack: Ec2AutoTag-dev
api keys:
None
endpoints:
None
functions:
Ec2AutoTag: Ec2AutoTag-dev-Ec2AutoTag
##5. 確認
インスタンスを起動してみて、起動者のユーザー名が付与されることを確認できました。
##6. 最後に
- ServerlessFrameworkでLambdaの登録は簡単にできる。
- StackSetに対応していれば、マルチリージョンに一度にデプロイできて、
より便利に使えそう。(これから調査)
##参考