この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
おはようございます、加藤です。AWS IoT Greengrass Core(以降、Greengrass)でシークレットを扱いたい際に、最も単純な方法はハードコートを行う事です。とはいえ、ハードコートは行いたくないですよね... Greengrassは、AWS Secret Mangaer(以降、Secrets Manger)と連携する事が可能です。これを利用すると、ハードコートを回避できます!!
環境
- pipenv, version 2018.11.26
- Python, 3.7.4
- jq, jq-1.6
- aws-cli, aws-cli/1.16.191 Python/3.7.4 Darwin/18.7.0 botocore/1.12.181
やってみた
シークレットの作成
- Secrets Manager コンソールにサインインします。
- [新しいシークレットを保存する] を選択します。
- [シークレットの種類を選択] で [その他のシークレット] を選択します。
- Greengrassで利用したいシークレットが他の種類である場合は、それを選択します。 4. [このシークレットに格納するキーと値のペアを指定します] で以下の操作を行います。 1. シークレットキー/値を表の通り入力します。
シークレットキー | 値 |
---|---|
test | abcdefghi |
- 暗号化キーに [DefaultEncryptionKey] を選択してから、 [次へ] を選択します。
- [シークレット名に] 「greengrass-TestSecret」 と入力し、 [次へ] を選択します。
- 今回、ローテーションは不要なので、 [自動ローテーションを無効にする] を選択し、 [次へ] を選択します。
- レビューページで、設定を確認し、 [保存] を選択します。
Greengrass グループにローカルシークレットリソースを追加する
- AWS IoT コンソールにサインインし、 [Greengrass] 、 [グループ] の順に選択します。
- シークレットをデプロイするグループを選択します。
- [リソース] 、 [シークレット] の順に選択します。
- [シークレットリソースの追加] を選択します。
- [選択] 、 [greengrass-TestSecret] の順に選択します。
- ラベルの選択(オプション)ページで、 [次へ] を選択します。
- シークレットリソースに名前を付けるページで、設定を確認し、 [保存] を選択します。
Greengrass用のLambda関数のデプロイパッケージ作成
- Pipenvを利用して環境をセットアップします。
mkdir -p src
pipenv --python 3.7.4
pipenv install greengrasssdk
- サンプルアプリケーションを作成します。
src/secret_test.py
import greengrasssdk
secrets_client = greengrasssdk.client('secretsmanager')
message_client = greengrasssdk.client('iot-data')
message = ''
def function_handler(event, context):
response = secrets_client.get_secret_value(SecretId='greengrass-TestSecret')
secret_value = response.get('SecretString')
if secret_value is None:
message = 'Failed to retrieve secret.'
else:
message = secret_value
message_client.publish(topic='secrets/output', payload=message)
print('published: ' + message)
- 依存するパッケージを含めて、ソースコードをZIP化します。
pipenv lock -r | pip install -r /dev/stdin -t src/
cd src
zip -r ../secret_test_python.zip *
cd ../
Greengrass用のLambda関数のデプロイ
- IAMロールの信頼されたエンティティにLambdaを設定する為の、JSONを作成する。
deploy/trusted_policy_for_lambda.json
{
"Statement": {
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
}
- パラメータを環境変数に設定する。
LAMBDA_FUNCTION_NAME='SecretTest'
LAMBDA_ROLE_NAME='secret-test-python'
- IAMロールを作成する。
LAMBDA_ROLE_ARN=$(aws iam create-role \
--role-name ${LAMBDA_ROLE_NAME} \
--assume-role-policy-document file://deploy/trusted_policy_for_lambda.json \
| jq -r '.Role.Arn')
aws iam attach-role-policy \
--role-name ${LAMBDA_ROLE_NAME} \
--policy-arn 'arn:aws:iam::aws:policy/AWSLambdaExecute'
- Lambda関数を作成し、バージョンとエイリアスを作成する。
aws lambda create-function \
--function-name ${LAMBDA_FUNCTION_NAME} \
--role ${LAMBDA_ROLE_ARN} \
--runtime 'python3.7' \
--handler 'secret_test.function_handler' \
--zip-file fileb://secret_test_python.zip
LAMBDA_VERSION=$(aws lambda publish-version \
--function-name ${LAMBDA_FUNCTION_NAME} \
--description '1' \
| jq -r '.Version')
aws lambda create-alias \
--name 'RELEASE' \
--function-name ${LAMBDA_FUNCTION_NAME} \
--function-version ${LAMBDA_VERSION}
Lambda 関数を Greengrass グループに追加する
- AWS IoT コンソールにサインインし、 [Greengrass] 、 [グループ] の順に選択します。
- シークレットをデプロイするグループを選択します。
- [Lambda] 、 [Lambdaの追加] の順に選択します。
- [既存のLambdaの使用] を選択します。
- 同じボタンが2つありますが、どちらを選択しても大丈夫です。 5. [SecretTest] 、 [次へ] を選択します。 6. [エイリアス: RELEASE] 、 [完了] を選択します。
シークレットリソースを Lambda 関数にアタッチする
- グループページで、[Lambda] 、 [SecretTest] の順に選択します。
- [リソース] 、 [シークレット] 、 [シークレットリソースのアタッチ] の順に選択します。
- [シークレットリソースの選択] を選択します。
- [MyTestSecret] 、 [保存] の順に選択します。
サブスクリプションを Greengrass グループに追加する
- グループページで、[サブスクリプション] 、 [サブスクリプションの追加] の順に選択します。
- [ソースとターゲットの選択] で以下の操作を行います。
- ソースの選択/ターゲットの選択を表の通り入力します。
ソースの選択 | ターゲットの選択 |
---|---|
IoT Cloud | SecretTest |
- [次へ] を選択します。
- [トピックフィルター] に [secrets/input] と入力し、 [次へ] を選択します。
- [完了] を選択します。
続けて、逆方向も追加します。
- グループページで、[サブスクリプション] 、 [サブスクリプションの追加] の順に選択します。
- [ソースとターゲットの選択] で以下の操作を行います。
- ソースの選択/ターゲットの選択を表の通り入力します。
ソースの選択 | ターゲットの選択 |
---|---|
SecretTest | IoT Cloud |
- [次へ] を選択します。
- [トピックフィルター] に [secrets/output] と入力し、 [次へ] を選択します。
- [完了] を選択します。
Greengrass のデプロイ
- グループページで、[アクション] 、 [デプロイ] の順に選択します。
- [自動検出] を選択します。
シークレットの確認
- AWS IoT コンソールにサインインし、 [テスト] を選択します。
- [トピックのサブスクリプション] に [secrets/output] と入力し、 [トピックへのサブスクライブ] を選択します。
- [トピックへサブスクライブする] を選択し、 [トピックのサブスクリプション] に [secrets/input] と入力し、 [トピックへのサブスクライブ] を選択します。
- [secrets/input] 、 [トピックに発行] の順に選択します。
- 画像では secret に なっていますが、 secrets が正しいです
- [secrets/output] を選択します。
- シークレットが表示されます。(数秒かかる場合があります)
シークレットのローテーション
シークレットを変更します。
- Secrets Manager コンソールにサインインします。
- [greengrass-TestSecret] を選択します。
- [シークレットの値を取得する] 、 編集するの順に選択します。
- シークレットの値を [123456] に変更します。
シークレットの確認の手順を実行します。 シークレットは変更前のままです。シークレットの更新を行った後は再度デプロイを行う必要があります。
Greengrass のデプロイの手順を実行します。 再度、シークレットの確認の手順を実行します。 シークレットが変更されている事を確認できました。
自動化したい場合は、Secrets MangaerのローテーションLambda関数を使用して、ローテーション後にデプロイを行うように実装すれば良さそうです。
あとがき
最近、業務でGreengrassを扱っているので、Greengrassのブログを書いてみました。 ローテーションに再デプロイが必要ですが、簡単・安全にシークレットを管理できて、とても便利ですね。