AWS IoTを使用してエッジデバイスからAWSのリソース、例えばAWS S3にアクセスしたくなることがあります。エッジデバイスからS3にアクセスする方法としていくつかありますが、この記事ではAuthorizing Direct Callという仕組みを使用してAWSリソースにアクセスします。
この記事は、こちらの記事で作成したモノ・証明書を使用するため事前に準備を済ませて下さい。
Authorizing Direct Calls
エッジデバイスからAWS S3にアクセスする為に、AWS S3のアクセスを公開設定にしてしまえばエッジデバイスを含む誰からもアクセス可能ですが、公開設定にせず、管理するデバイスからのアクセスを可能とする為に、Authorizing Direct Callsという仕組みを使用します。
AWS S3へのアクセスを可能にする別の方法として、AWS S3の署名付きURLを使用することもできますが、署名付きURLは有効期限があるため目的に応じて使い分けます。
Authorizing Direct Callsを利用するために以下の設定を行います。
- IAMロールの作成
- 作成したIAMロールにS3のファイル取得を許可するポリシーを設定
- IAMロールを参照するIoTロールエイリアスを作成する
- 証明書を使用して上記で作成したIAMロール権限を付与するためのIoTポリシーを作成する
- IoTポリシーと証明書をアタッチする
IoTデバイスに直接IAMロール権限を付与できないため、IoTロールエイリアスを経由し、IAMロール権限を取得します。それぞれの関係は以下の通りです。
IAMロールの作成
IAMロールrole-s3-read
を作成します。
$ cat << EOS > role-s3-read.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "credentials.iot.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOS
$ aws iam create-role --role-name role-s3-read --assume-role-policy-document file://role-s3-read.json
Code language: Bash (bash)
IAMポリシーの作成
IAMポリシーpolicy-s3-read
を作成し、IAMロールrole-s3-read
に設定します。S3バケットxxxxxxxxxx-iot-test-files/
以下のファイルを取得可能に設定します。xxxxxxxxxx
にはアカウントIDを指定してください。(別の記事でこのバケットを使用するためxxxxxxxxxx
はアカウントIDを指定します)
$ cat << EOS > policy-s3-read.json
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::xxxxxxxxxx-iot-test-files/*"
}
]
}
EOS
$ aws iam put-role-policy --policy-name policy-s3-read --role-name role-s3-read --policy-document file://policy-s3-read.json
Code language: Bash (bash)
IoTロールエイリアスの作成
IoTロールエイリアスiot-role-alias-s3-read
を作成し、IAMロールrole-s3-read
と紐づけします。
aws iot create-role-alias --role-alias iot-role-alias-s3-read --role-arn arn:aws:iam::xxxxxxxxxxxx:role/role-s3-read
Code language: Bash (bash)
arn:aws:iam::xxxxxxxxxxxx:role/role-s3-read
は適切なアカウントIDに置き換えます。アカウントIDは以下で取得可能です。
aws sts get-caller-identity|jq -r .Account
Code language: Bash (bash)
IoTポリシーの作成
IoTポリシーiot-policy-s3-read
を作成
$ cat << EOS > iot-policy-s3-read.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "iot:AssumeRoleWithCertificate",
"Resource": "arn:aws:iot:us-east-1:xxxxxxxxxxxx:rolealias/iot-role-alias-s3-read"
}
]
}
EOS
$ aws iot create-policy --policy-name iot-policy-s3-read --policy-document file://iot-policy-s3-read.json
Code language: Bash (bash)
arn:aws:iot:us-east-1:xxxxxxxxxxxx
は適切なアカウントIDに置き換えて下さい。
IoT証明書にIoTポリシーをアタッチ
IoT証明書にIoTポリシーiot-policy-s3-read
をアタッチします。--target arn:aws:iot:us-east-1:xxxxxxxxxxxxx:cert/xxxxxxxxxxxxx
はこちらの記事で作成した証明書のARNです。
aws iot attach-policy --policy-name iot-policy-s3-read --target arn:aws:iot:us-east-1:xxxxxxxxxxxxx:cert/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Code language: Bash (bash)
動作確認
まずはクレデンシャルプロバイダーのエンドポイントを調べます。
$ aws iot describe-endpoint --endpoint-type iot:CredentialProvider
{
"endpointAddress": "xxxxx.credentials.iot.us-east-1.amazonaws.com"
}
Code language: Bash (bash)
取得したクレデンシャルプロバイダーからトークンを取得します。
$ curl --cert ./certificate.pem --key ./private.key -H "x-amzn-iot-thingname: test-thing" https://xxxxxxxxxxxx.credentials.iot.us-east-1.amazonaws.com/role-aliases/iot-role-alias-s3-read/credentials | jq -r .
{
"credentials": {
"accessKeyId": "ASXXXXXXXXXXXXXXXX",
"secretAccessKey": "otXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"sessionToken": "IQXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"expiration": "2022-12-03T14:14:07Z"
}
}
Code language: Bash (bash)
S3にxxxxxxxxxx-iot-test-files
バケットを作成し、確認用ファイルを保存します。(繰り返しにないりますが、xxxxxxxxxx
はアカウントIDを指定します)
aws s3 mb s3://xxxxxxxxxx-iot-test-files
echo hoge > hoge.txt
aws s3 cp hoge.txt s3://xxxxxxxxxx-iot-test-files/
Code language: Bash (bash)
取得したトークンを使用してS3からファイルをダウンロードします。
$ AWS_ACCESS_KEY_ID="ASXXXXXXXXXXXXXXXX" \
AWS_SECRET_ACCESS_KEY="otXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
AWS_SESSION_TOKEN="IQXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
aws s3 cp s3://xxxxxxxxxx-iot-test-files/hoge.txt .
download: s3://xxxxxxxxxx-iot-test-files/hoge.txt to ./hoge.txt
Code language: Bash (bash)
S3へのアクセスはs3:GetObject
しか許可していないため、リスト操作ができないことを確認します。
$ AWS_ACCESS_KEY_ID="ASXXXXXXXXXXXXXXXX" \
AWS_SECRET_ACCESS_KEY="otXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
AWS_SESSION_TOKEN="IQXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
aws s3 ls s3://xxxxxxxxxx-iot-test-files/hoge.txt
An error occurred (AccessDenied) when calling the ListObjectsV2 operation: Access Denied
Code language: Bash (bash)
正しく動作していそうです。
以上です。