やりたかったこと
OpenSearch Serviceのドメインを構築し、CodeBuildからそのドメインにインデックスを作成するためのリクエストを送信したかった
前提
- ドメインはアクセスポリシーを設定しており署名付きリクエスト以外は受付けない
- AWS CLI v2を使用している
- buildspecでシェルにbashを指定している
env:
shell: bash
CodeBuildでの処理
buildspecのcommandsに下記の処理を書いていく
$(aws configure export-credentials --format env)
curl -vsSL --fail-with-body -X PUT -d @- \
--aws-sigv4 aws:amz:$AWS_REGION:es \
--user $AWS_ACCESS_KEY_ID:$AWS_SECRET_ACCESS_KEY \
-H "x-amz-security-token: $AWS_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
https://... <<< '{...}'
現状、Standard:7.0ではcurlの --json
オプションが使えなかった
どうもそのバージョンがそのUbuntuの最新ぽくアップグレードもできなかった
AmazonLinuxのcurlの場合 --json
が使えるのでヘッダーの記述を省略できる
とはいえ、そのためにイメージを変更したくなかったので、AWS CDK標準のStandard:7.0のままにした
本当は明示的に指定するべきだが、AWS CDKのバージョンアップで勝手にアップデートして欲しいので未指定にした
curl -vsSL --fail-with-body -X PUT --json @- \
--aws-sigv4 aws:amz:$AWS_REGION:es \
--user $AWS_ACCESS_KEY_ID:$AWS_SECRET_ACCESS_KEY \
-H "x-amz-security-token: $AWS_SESSION_TOKEN" \
https://... <<< '{...}'
解説
認証情報のエクスポート
$(aws configure export-credentials --format env)
未確認だが aws configure export-credentials
はAWS CLI v1にはないかもしれない
ここではデフォルトでインストールされているAWS CLI v2を使った
AWS CLIを自分でインストールする必要はなかった(configureも不要)
--format env
を指定することで下記のような形で認証情報が出力されるので、そのままコマンド置換してエクスポートしている
export AWS_ACCESS_KEY_ID=...
export AWS_SECRET_ACCESS_KEY=...
export AWS_SESSION_TOKEN=...
export AWS_CREDENTIAL_EXPIRATION=2023-01-01T00:00:00+00:00
署名付きリクエストの作成
curlに --awssigv4
オプションが実装されたので簡単に署名付きリクエストを作成できるようになった
7.75.0 からあったらしい
curl -vsSL --fail-with-body -X PUT -d @-
これらのオプションは適当
詳細にログに出力したかったので -f
ではなく --fail-with-body
を使った
--aws-sigv4 aws:amz:$AWS_REGION:es \
$AWS_REGION
はCodeBuildの環境変数としてエクスポート済みのようなので、そのまま使った
末尾の es
の部分に送信先のサービスを指定する
エンドポイントにサービス名が含まれていれば指定不要っぽいが、曖昧なのでここでは指定した
ちなみにサービスコードは aws service-quotas list-services --query 'Services[].ServiceCode'
で取得できる
--user $AWS_ACCESS_KEY_ID:$AWS_SECRET_ACCESS_KEY \
-H "x-amz-security-token: $AWS_SESSION_TOKEN" \
ここでエクスポートした認証情報を使う
AssumeRoleしているので $AWS_SESSION_TOKEN
も指定している
-H "x-amz-content-sha256: UNSIGNED_PAYLOAD" \
OpenSearch Service Serverlessの場合など追加で x-amz-content-sha256
ヘッダーが必要な場合もあるらしい
今回はServerlessを使っていないので指定していない
なので詳細については未確認