AWS Greengrass Groupのデプロイ状態通知を受け取ってアクションを起こす

2019.11.05

はじめに

おはようございます、加藤です。AWS Greengrass Group(以降、Greengrassグループ)のデプロイ状態通知を受け取り、何らかのアクションを起こす方法をご紹介します。

説明

先月アップデートがあり、Greengrassグループのデプロイ状態が変化した際にCloudWatch Eventで検知できるようになりました。

AWS IoT Greengrass が、Amazon EventBridge にデプロイ通知を送信するようになりました。Greengrass グループのデプロイが状態を変更するたびに、Greengrass がイベントを送信します。顧客は、デプロイの変更に基づいてアクションを実行する EventBridge ルールを作成できます。この新機能により、顧客は通知を送信したり、イベント情報を取得したり、修正アクションを実行したり、デプロイのために他のイベントを開始したりすることができます。
たとえば、顧客は、担当者への通知や AWS Lambda 関数の実行など、デプロイ後の操作をトリガーするルールを作成できます。他の顧客は、成功と失敗を Amazon CloudWatch または別のモニタリングシステムに記録するルールの作成を選択できます。
この新機能は、今日からすべての AWS 顧客が利用でき、デバイス上の Greengrass Core ソフトウェアを更新する必要はありません。AWS IoT Greengrass の詳細については、製品ページをご覧ください。
AWS IoT Greengrass がデプロイ通知を提供

これによって、デプロイ状態の変化をトリガーとして様々なアクションを起こすことが可能です。特定のGreengrassグループIDを指定する事も、指定せずに全てのGreengrassグループをトリガーに含める事も可能です。
下記にCloud Watch Eventsから呼び出し可能なAWSサービスを列挙しました。これだけでも、様々なサービスが対応しています。
そして、Lambda functionsが対応しているので対応先の可能性は無限大です。

  • Amazon EC2 instances
  • AWS Lambda functions
  • Streams in Amazon Kinesis Data Streams
  • Delivery streams in Amazon Kinesis Data Firehose
  • Log groups in Amazon CloudWatch Logs
  • Amazon ECS tasks
  • Systems Manager Run Command
  • Systems Manager Automation
  • AWS Batch jobs
  • Step Functions state machines
  • Pipelines in CodePipeline
  • CodeBuild projects
  • Amazon Inspector assessment templates
  • Amazon SNS topics
  • Amazon SQS queues
  • Built-in targets: EC2 CreateSnapshot API call, EC2 RebootInstances API call, EC2 StopInstances API call, and EC2 TerminateInstances API call.
  • The default event bus of another AWS account

What Is Amazon CloudWatch Events? - Amazon CloudWatch Events

Lambda functionsに連携した場合は、下記のフォーマットでeventを受け取ります。

sample_event.json

{
    "version":"0",
    "id":" cd4d811e-ab12-322b-8255-EXAMPLEb1bc8",
    "detail-type":"Greengrass Deployment Status Change",
    "source":"aws.greengrass",
    "account":"123456789012",
    "time":"2018-03-22T00:38:11Z",
    "region":"us-west-2",
    "resources":[],
    "detail":{
        "group-id": "284dcd4e-24bc-4c8c-a770-EXAMPLEf03b8",
        "deployment-id": "4f38f1a7-3dd0-42a1-af48-EXAMPLE09681",
        "deployment-type": "NewDeployment|Redeployment|ResetDeployment|ForceResetDeployment",
        "status": "Building|InProgress|Success|Failure"
    }
}

デプロイ通知の取得 - AWS IoT Greengrass

図ではLambdaですが、前述の通り他のAWSサービスを呼び出す事も可能です。

やってみた

AWSマネジメントコンソールから、実際に設定を行ってみます。なお、前提としてGreengrassグループが既に用意されデプロイ可能な状態になっているものとします。

アクションの作成

デプロイ通知を受け取るLambda functionsを作成します。

Python 3.7でLambda functionsを作成します。検証用途で特に他のサービスは触らない為、アクセス権限は基本的な Lambda アクセス権限で新しいロールを作成で作成します。

コードは下記の様に記述します。実際利用する際に、使いそうな値と生のeventを出力する様に書きました。

lambda_function.py

def lambda_handler(event, context):

    print(event)

    detail = event['detail']

    status = detail['status']
    gg_grp_id = detail['group-id']
    deployment_id = detail['deployment-id']

    print(f'Greengrass Group Deployment Notifications: Deployment ID: {deployment_id}, Greengrass Group ID={gg_grp_id}, Status={status}')

イベントの作成

Amazon EventBridgeからイベントを作成します。GUIでGreengrassのイベントパターンは用意されていないので、カスタムパターンで作成します。
${GROUP_ID}は環境に応じて置換してください。

event_pattern.json

{
  "source": [
    "aws.greengrass"
  ],
  "detail": {
    "group-id": [
      "${GROUP_ID}"
    ]
  }
}

detailの箇所を削除して、このようにイベントパターンを指定すれば、全てのGreengrassグループをトリガーに含める事ができます。

event_pattern_all.json

{
  "source": [
    "aws.greengrass"
  ]
}

続けて、ターゲットを選択で、先程作成した、Lambda functionsを選択します。

動作テスト

ここまで、設定ができたらGreengrassのデプロイを実行します。
CloudWatch Logsに下記の様に期待した出力が行われました。(見やすいように整形しています)

{
    'version': '0',
    'id': '${ID_1}',
    'detail-type': 'Greengrass Deployment Status Change',
    'source': 'aws.greengrass',
    'account': '${AWS_ACCOUNT_ID}',
    'time': '2019-11-05T07:16:59Z',
    'region': 'ap-northeast-1',
    'resources': [],
    'detail': {
        'group-id': '${GROUP_ID}',
        'deployment-id': '${DEPLOYMENT_ID}',
        'deployment-type': 'NewDeployment',
        'status': 'Building'
    }
}
Greengrass Group Deployment Notifications: Deployment ID: ${DEPLOYMENT_ID},
 Greengrass Group ID=${GROUP_ID},
 Status=Building

{
    'version': '0',
    'id': '${ID_2}',
    'detail-type': 'Greengrass Deployment Status Change',
    'source': 'aws.greengrass',
    'account': '${AWS_ACCOUNT_ID}',
    'time': '2019-11-05T07:17:03Z',
    'region': 'ap-northeast-1',
    'resources': [],
    'detail': {
        'group-id': '${GROUP_ID}',
        'deployment-id': '${DEPLOYMENT_ID}',
        'deployment-type': 'NewDeployment',
        'status': 'InProgress'
    }
}

Greengrass Group Deployment Notifications: Deployment ID: ${DEPLOYMENT_ID},
 Greengrass Group ID=${GROUP_ID},
 Status=InProgress

{
    'version': '0',
    'id': '${ID_3}',
    'detail-type': 'Greengrass Deployment Status Change',
    'source': 'aws.greengrass',
    'account': '${AWS_ACCOUNT_ID}',
    'time': '2019-11-05T07:17:03Z',
    'region': 'ap-northeast-1',
    'resources': [],
    'detail': {
        'group-id': '${GROUP_ID}',
        'deployment-id': '${DEPLOYMENT_ID}',
        'deployment-type': 'NewDeployment',
        'status': 'Failure'
    }
}

Greengrass Group Deployment Notifications: Deployment ID: ${DEPLOYMENT_ID},
 Greengrass Group ID=${GROUP_ID},
 Status=Failure

今回は、元々失敗状態のGreengrassグループに対して、失敗が予想される状態でデプロイを行っています。
状態が BuildingInProgressFailure と変異している事が確認できました。

あとがき

この仕組みがあれば、アプリケーションからGreengrassグループを操作する様な場合に、ポーリングを行わずにイベントドリブンで結果に対する処理を行えますね!!
group-iddeployment-idを取得できているので、Lambda functionsで失敗時の内容などを取得する事も可能です。
以上でした。