はじめに
AWS IoT Greengrass V2は、Docker Containerに対応し、コンテナベースのコンポーネントを作成できます。また、GreengrassコンポーネントからAWSリソースにアクセスする際、認証処理を簡素化するため、TokenExchangeServiceというコンポーネントが用意されています。今回、コンテナベースのコンポーネントから、TokenExchangeServiceを使い、AWSリソースにアクセスする方法を試してみました。AWSリソースへのアクセスとして、DynamoDBへレコードを追加するという例を用いて確認しました。
まとめ
Greengrass deviceで、認証情報(Token)をコンテナ内へ渡すためには、(1)認証情報を環境変数としてコンテナへ引き渡し、(2)コンテナのネットワーク接続をホストモードで接続する、事で可能となります。認証情報をコンテナ内に渡すことで、コード内に認証情報を記述することなくAWSサービスにアクセスすることができます。
- コンテナへ引き渡す環境変数:
--env AWS_CONTAINER_AUTHORIZATION_TOKEN --env AWS_CONTAINER_CREDENTIALS_FULL_URI
- クレデンシャルへのアクセスを可能とするためのネットワーク接続設定:
--net=host
概要
Greengrass Device から直接、DynamoDB(テーブル名:SampleDynamoTable)にレコードをPutするコンポーネントを作成し、デプロイします。コンポーネントのコンテナイメージをECR(レポジトリ名:dynamo_access_sample)に格納し、Greengrass Deviceへ配信します。
権限設定:IAMポリシー、IAMロールの作成
まずは、Greengrass デバイスに対して付与するAWSリソースへのアクセス権限ポリシーを作成します。今回、コンテナイメージレポジトリとしてECRを使うためECRへのアクセス権限と、DynamoDBへのレコード追加権限を付与するIAMポリシーを作成します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ecr:GetAuthorizationToken",
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"dynamodb:PutItem",
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage"
],
"Resource": [
"arn:aws:dynamodb:ap-northeast-1:*:table/SampleDynamoTable",
"arn:aws:ecr:ap-northeast-1:*:repository/dynamodb_access_sample"
]
}
]
}
上記で作成した、IAMポリシーを登録します。
aws iam create-policy \
--policy-name MyGreengrassV2AccessPolicy \
--policy-document file://token_exchange_policy.json
続いて、Greengrass device のIAMロール(GreengrassV2TokenExchangeRole)に、上記ポリシーをアタッチし権限を付与します。
コンポーネント作成:コンテナの作成、登録
AWSリソースとして、DynamoDBにレコードを追加するサンプルコードを用意します。
import boto3
import datetime
import os
aws_region = os.getenv("AWS_REGION", "ap-northeast-1")
device_name = os.getenv("AWS_IOT_THING_NAME", "greengrass")
timestamp = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
dynamodb = boto3.resource('dynamodb', region_name=aws_region)
table = dynamodb.Table('SampleDynamoTable')
response = table.put_item(
Item = {
'device_name': device_name,
'timestamp': timestamp
}
)
print(response)
環境変数(AWS_REGION
、AWS_IOT_THING_NAME
)を用い、AWSのリージョン名、Greengrass coreのThing名をそれぞれ取得しています。
次に、コンテナ化するためのDockerfileを書きます。
FROM python:3.9-slim-buster
WORKDIR /root
RUN python -m pip install --upgrade pip && python -m pip install boto3
COPY dynamodb_access_sample_from_ggv2_container.py dynamodb_access_sample_from_ggv2_container.py
CMD [ "python", "/root/dynamodb_access_sample.py" ]
そして、Docker Container を Build し、 ECR へ Push します。
aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin <AWS ACCOUNT>.dkr.ecr.ap-northeast-1.amazonaws.com
docker build -t dynamodb_access_sample .
docker tag dynamodb_access_sample:latest <AWS ACCOUNT>.dkr.ecr.ap-northeast-1.amazonaws.com/dynamodb_access_sample:latest
docker push <AWS ACCOUNT>.dkr.ecr.ap-northeast-1.amazonaws.com/dynamodb_access_sample:latest
Greengrass Component登録:レシピの作成、登録
Greengrass Componentのレシピを作成します。
---
RecipeFormatVersion: '2020-01-25'
ComponentName: com.example.AccessDynamoDb
ComponentVersion: 0.0.1
ComponentDescription: A component for testing token exchange service with docker container.
ComponentDependencies:
aws.greengrass.DockerApplicationManager:
VersionRequirement: ^2.0.0
DependencyType: HARD
aws.greengrass.TokenExchangeService:
VersionRequirement: ^2.0.0
DependencyType: HARD
Manifests:
- Platform:
os: all
Lifecycle:
Install: |
docker tag <YOUR AWS ACCOUNT>.dkr.ecr.ap-northeast-1.amazonaws.com/dynamodb_access_sample:latest dynamodb_access_sample:latest
Startup: |
docker run \
--env AWS_CONTAINER_AUTHORIZATION_TOKEN \
--env AWS_CONTAINER_CREDENTIALS_FULL_URI \
--env AWS_REGION \
--env AWS_IOT_THING_NAME \
--net=host --rm dynamodb_access_sample:latest
Artifacts:
- URI: "docker:<YOUR AWS ACCOUNT>.dkr.ecr.ap-northeast-1.amazonaws.com/dynamodb_access_sample:latest"
AWSクレデンシャルへのアクセス情報をコンテナへ渡すため、環境変数(AWS_CONTAINER_AUTHORIZATION_TOKEN
、AWS_CONTAINER_CREDENTIALS_FULL_URI
)を指定し、アクセスを可能とするため、ネットワーク接続を--net=host
とします。
また、dynamodb_access_sample.py
で利用する環境変数(AWS_REGION
,AWS_IOT_THING_NAME
)も同時に引き渡します。
レシピを基に、Greengrass Componentを作成します。
aws greengrassv2 create-component-version --inline-recipe fileb://recipe.yaml
Deployment の Configuration を作成します。
{
"targetArn": "arn:aws:iot:ap-northeast-1:<YOUR AWS ACCOUNT>:thing/<Greengrass Core Name>",
"deploymentName": "Deployment for MyGreengrassCore",
"components": {
"com.example.AccessDynamoDb": {
"componentVersion": "0.0.1"
}
},
"deploymentPolicies": {
"failureHandlingPolicy": "DO_NOTHING",
"componentUpdatePolicy": {
"timeoutInSeconds": 60,
"action": "NOTIFY_COMPONENTS"
},
"configurationValidationPolicy": {
"timeoutInSeconds": 60
}
}
}
Greengrass core へデプロイします。
aws greengrassv2 create-deployment \
--cli-input-json file://cli-deployment.json
参考情報