2018年2月10日土曜日

lambda(python)でEC2を検索して、別のlambda(python)関数を実行する - 1/2


lambdaを使用し、EC2に設定したタグ(Environment)の値が"dev"のサーバでシェルを実行してみます。

下記の記事で使用した lambda関数のSSHFunctionを使用します。


1.EC2を検索する lambda の作成


ソースコードは以下のとおり。
タグ(Environment)に "dev" が設定されているEC2を検索して、lambda関数の SSHFunctionを実行します。
trigger_function.py ファイルに保存します。
import boto3

def trigger_handler(event, context):

    # Get IP addresses of EC2 instances
    ec2 = boto3.client('ec2')
    instances = ec2.describe_instances(
        Filters=[{'Name':'tag:Environment','Values':['dev']}]
    )

    hosts = []
    for r in instances['Reservations']:
        for inst in r['Instances']:
            hosts.append(inst['PrivateIpAddress'])

    if len(hosts) == 0 :
        return {
          'message' : "Trigger function finished: no host"
        }

    # Invoke worker function for each IP address
    la = boto3.client('lambda')
    for host in hosts:
        print "Invoking worker_function on " + host
        response = la.invoke(
            FunctionName='SSHFunction',
            InvocationType='Event',
            LogType='Tail',
            Payload='{"IP":"'+ host +'"}'
        )
        print response

    return {
        'message' : "Trigger function finished"
    }

2. AWS SAM Local で動作確認


上記1のプログラムを AWS SAM Local で動作確認します。
まず、template.yaml を作成し、関数名を TriggerFunction とします。
TriggerFunctionはVPC外で実行します。
AWSTemplateFormatVersion: '2010-09-09'
Description: trigger application.
Transform: AWS::Serverless-2016-10-31
Resources:
  TriggerFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: .
      FunctionName: TriggerFunction
      Handler: trigger_function.trigger_handler
      MemorySize: 128
      Role: arn:aws:iam::xxxxxxx:role/Lambda02_Role
      Runtime: python2.7
      Timeout: 10
      Events:
        ScheduleRate5min:
          Type: Schedule
          Properties:
            Schedule: cron(0/5 * * * ? *)

この TriggerFunction は、スケジュールイベントで実行したいので、以下のようにしてテスト用のイベントデータを作成します。
[root@centos702 lambda2]# sam local generate-event schedule > event.json
A newer version of the AWS SAM CLI is available!
Your version:   0.2.4
Latest version: 0.2.6
See https://github.com/awslabs/aws-sam-local for upgrade instructions

[root@centos702 lambda2]# cat event.json
{
  "account": "123456789012",
  "region": "us-east-1",
  "detail": {},
  "detail-type": "Scheduled Event",
  "source": "aws.events",
  "time": "1970-01-01T00:00:00Z",
  "id": "cdc73f9d-aea9-11e3-9d5a-835b769c0d9c",
  "resources": [
    "arn:aws:events:us-east-1:123456789012:rule/my-schedule"
  ]
}[root@centos702 lambda2]#

用意したファイルは以下のとおり。
[root@centos702 lambda2]# ls
event.json  template.yaml  trigger_function.py

TriggerFunction を実行すると、以下のとおり。
まだ、EC2を用意していないので、SSHFunction を実行する前で処理が終了しています。
[root@centos702 lambda2]# sam local invoke TriggerFunction -e event.json
A newer version of the AWS SAM CLI is available!
Your version:   0.2.4
Latest version: 0.2.6
See https://github.com/awslabs/aws-sam-local for upgrade instructions

2018/02/10 12:55:12 Successfully parsed template.yaml
2018/02/10 12:55:12 Connected to Docker 1.35
2018/02/10 12:55:12 Fetching lambci/lambda:python2.7 image for python2.7 runtime...
python2.7: Pulling from lambci/lambda
Digest: sha256:87a3b9bb1ba6ae666b0087107852b67415cae0660669ae5633a0ab828aea2c69
Status: Image is up to date for lambci/lambda:python2.7
2018/02/10 12:55:14 Invoking trigger_function.trigger_handler (python2.7)
2018/02/10 12:55:14 Mounting /root/lambda2 as /var/task:ro inside runtime container
START RequestId: 8d9565ee-e50e-4ef0-8b40-7945e5cda16c Version: $LATEST
END RequestId: 8d9565ee-e50e-4ef0-8b40-7945e5cda16c
REPORT RequestId: 8d9565ee-e50e-4ef0-8b40-7945e5cda16c Duration: 1338 ms Billed Duration: 1400 ms Memory Size: 128 MB Max Memory Used: 37 MB

{"message": "Trigger function finished: no host"}

[root@centos702 lambda2]#

EC2を用意して、もう一度、実行します。
確認しやすいように、SSHFunction のログは消しておきます。
[root@centos702 lambda2]# aws logs describe-log-groups --output text
LOGGROUPS       arn:aws:logs:us-east-1:544509011205:log-group:/aws/lambda/SSHFunction:* 1518244672189   /aws/lambda/SSHFunction 00
[root@centos702 lambda2]# aws logs delete-log-group --log-group-name /aws/lambda/SSHFunction
[root@centos702 lambda2]#

TiggerFunction を実行すると以下のとおり。
AWSに登録した SSHFunction が実行されました。
[root@centos702 lambda2]# sam local invoke "TriggerFunction" -e event.json
A newer version of the AWS SAM CLI is available!
Your version:   0.2.4
Latest version: 0.2.6
See https://github.com/awslabs/aws-sam-local for upgrade instructions

2018/02/10 15:42:30 Successfully parsed template.yaml
2018/02/10 15:42:30 Connected to Docker 1.35
2018/02/10 15:42:30 Fetching lambci/lambda:python2.7 image for python2.7 runtime...
python2.7: Pulling from lambci/lambda
Digest: sha256:87a3b9bb1ba6ae666b0087107852b67415cae0660669ae5633a0ab828aea2c69
Status: Image is up to date for lambci/lambda:python2.7
2018/02/10 15:42:33 Invoking trigger_function.trigger_handler (python2.7)
2018/02/10 15:42:33 Mounting /root/lambda2 as /var/task:ro inside runtime container
START RequestId: 5f9dc595-2346-42d1-baf2-b400ddfe53c0 Version: $LATEST
Invoking worker_function on 10.0.11.189
{u'Payload': <botocore.response.StreamingBody object at 0x7f06e174e7d0>, 'ResponseMetadata': {'RetryAttempts': 0, 'HTTPStatusCode': 202, 'RequestId': '95152c29-0e2d-11e8-bd14-b9436f2119d9', 'HTTPHeaders': {'x-amzn-requestid': '95152c29-0e2d-11e8-bd14-b9436f2119d9', 'content-length': '0', 'x-amzn-trace-id': 'root=1-5a7e945d-0a492b15067bfbb92fd8e167;sampled=0', 'x-amzn-remapped-content-length': '0', 'connection': 'keep-alive', 'date': 'Sat, 10 Feb 2018 06:42:37 GMT'}}, u'StatusCode': 202}
END RequestId: 5f9dc595-2346-42d1-baf2-b400ddfe53c0
REPORT RequestId: 5f9dc595-2346-42d1-baf2-b400ddfe53c0 Duration: 2856 ms Billed Duration: 2900 ms Memory Size: 128 MB Max Memory Used: 39 MB

{"message": "Trigger function finished"}


[root@centos702 lambda2]#

SSHFunction のログを見てみます。
[root@centos702 lambda2]# aws logs describe-log-groups --output text
LOGGROUPS       arn:aws:logs:us-east-1:544509011205:log-group:/aws/lambda/SSHFunction:* 1518244957766   /aws/lambda/SSHFunction 00
[root@centos702 lambda2]# aws logs describe-log-streams --log-group-name /aws/lambda/SSHFunction --output=text                   LOGSTREAMS      arn:aws:logs:us-east-1:544509011205:log-group:/aws/lambda/SSHFunction:log-stream:2018/02/10/[$LATEST]c157d903671c49f1aef959d7e46ee9fa    1518244957800   1518244957394   1518244957394   1518244972984   2018/02/10/[$LATEST]c157d903671c49f1aef959d7e46ee9fa     0       49578651561709524302585247451449080513328803549848761458
[root@centos702 lambda2]# aws logs get-log-events --log-group-name /aws/lambda/SSHFunction --log-stream-name '2018/02/10/[$LATEST]c157d903671c49f1aef959d7e46ee9fa' --output=text
b/33857993943797576004760612550598371585409610073464832000      f/33857993994397966860226596477071430965818472836432855052
EVENTS  1518244957823   START RequestId: 95152c29-0e2d-11e8-bd14-b9436f2119d9 Version: $LATEST
        1518244957394
EVENTS  1518244972984   Connecting to 10.0.11.189
        1518244957454
EVENTS  1518244972984   Connected to 10.0.11.189
        1518244957778
EVENTS  1518244972984   Executing /usr/bin/aws s3 cp s3://blue21.dev.local/HelloWorld.sh /tmp/HelloWorld.sh --region us-east-1
        1518244957778
download: s3://blue21.dev.local/HelloWorld.sh to ../../tmp/HelloWorld.shile(s) remaining
        1518244958444
EVENTS  1518244972984

Executing /usr/bin/chmod 700 /tmp/HelloWorld.sh
        1518244958444
EVENTS  1518244972984

Executing /tmp/HelloWorld.sh
        1518244958529
EVENTS  1518244972984   Sat Feb 10 06:42:38 UTC 2018
        1518244958608
EVENTS  1518244972984   ip-10-0-11-189.ec2.internal
        1518244958608
EVENTS  1518244972984   Hello
        1518244958608
EVENTS  1518244972984

Executing /bin/rm /tmp/HelloWorld.sh
        1518244958608
EVENTS  1518244972984   END RequestId: 95152c29-0e2d-11e8-bd14-b9436f2119d9
        1518244958662
EVENTS  1518244972984   REPORT RequestId: 95152c29-0e2d-11e8-bd14-b9436f2119d9  Duration: 1265.48 ms    Billed Duration: 1300 ms Memory Size: 128 MB     Max Memory Used: 59 MB
        1518244958662
EVENTS  1518244972984

        1518244959663
[root@centos702 lambda2]#

TriggerFunction から SSHFunction が実行され、EC2で HelowWorld.sh が実行されたのがわかります。