夢の島スケートボードパーク
出張で東京へ滞在したので「夢の島スケートボードパーク」へ行ってきました。
https://www.di-ksp.jp/facility/yumenoshima_s
最寄りは駅は新木場駅です。 今回、駅で友達と待ち合わせをして友達の車で移動しましたが、徒歩で行くにはやや遠そうな感じがしました。
スタッフは皆さんフレンドリー! 受付を済ませて、いざ初級エリアへ!(管理棟を挟んで初級エリアと中級エリアに分かれています)
朝9時過ぎに滑り始めましたが、キッズとおじさんスケーターが多く、同じくおじさんの私もとてもリラックスして楽しめました! 大理石のマニュアルパッドをゴリゴリグラインドするのめちゃくちゃ気持ちよかったです。

またすぐにでも行きたいなあ
CLIでAssumeRoleしてみる

Assume Roleについてなんとなく理解はしているつもりでしたが、 手元で動かしたことはなかったのでCLIでAssume Roleをしてみて理解を深めようと思います。
Assume Roleとは?
Returns a set of temporary security credentials that you can use to access AWS resources. These temporary credentials consist of an access key ID, a secret access key, and a security token. Typically, you use AssumeRole within your account or for cross-account access.
AWSのリソースにアクセスするための一時的なセキュリティ認証情報を返します。 これらの一時的な認証情報は「access key ID」「 secret access key」「security token」で構成されています。一般的にあなたのアカウントやクロスアカウントへのアクセスでAssumeRoleを使います。
つまりAssumeRoleとは、AWSのリソースにアクセスするための一時的なクレデンシャルを返す仕組みです。
動かしてみる
今回下記のような状況を想定してAssumeRoleしてみます。
- とあるIAMユーザ(以下IAMユーザAとします)は自身のAWSアカウント内で、Action
iam:ListPoliciesの実行が許可されていません。そのためaws iam list-policiesを実行しても失敗します。 - IAMユーザAが
iam:ListPoliciesの実行が許可されているIAMロールのAssumeRoleを実行し、一時的なクレデンシャルを受け取り、それを使用してaws iam list-policiesを実行します。
それでは必要なIAMポリシーやIAMロールをTerraformで作成していきます。
IAMポリシーとロールの作成
iam:ListPoliciesを許可するポリシーを作成します。
# iam:ListPoliciesを許可するポリシーのドキュメント data "aws_iam_policy_document" "iam-list-policies-policy-document" { statement { sid = "IamListPoliciesPolicyDocument" effect = "Allow" actions = [ "iam:ListPolicies" ] resources = ["*"] } } # iam:ListPoliciesを許可するポリシー resource "aws_iam_policy" "iam-list-policies-policy" { name = "iam-list-policies-policy" policy = data.aws_iam_policy_document.iam-list-policies-policy-document.json }
次にIAMロールの作成です。 次のポリシードキュメントは、作成するIAMロールを誰がAssumeRoleすることができるかを書いたものです。
# 誰にロールを引き渡すかを書いたポリシー data "aws_iam_policy_document" "iam-test-role-policy-document" { statement { sid = "IamTestRolePolicyDocument" effect = "Allow" actions = [ "sts:AssumeRole" ] principals { type = "AWS" identifiers = ["arn:aws:iam::000000000000:user/user_a"] } } }
上記ポリシーを持ったIAMロールを作成します。
# ロールの作成 resource "aws_iam_role" "iam-list-policies-role" { name = "iam-test-role" assume_role_policy = data.aws_iam_policy_document.iam-test-role-policy-document.json }
初めに作成したiam:ListPoliciesを許可するポリシーを上記IAMロールにアタッチします。
# ロールに`iam:ListPolicies`を許可するポリシーをアタッチ resource "aws_iam_role_policy_attachment" "iam-list-policies-role-iam-list-policies-policy-attachment" { role = aws_iam_role.iam-list-policies-role.name policy_arn = aws_iam_policy.iam-list-policies-policy.arn }
以上でIAMユーザAがiam:ListPoliciesの実行可能なIAMロールiam-test-roleをAssumeRoleすることが可能になりました。
AWS CLIからAssumeRoleしてみる
初めにIAMユーザAで下記コマンドを実行してみます。
aws iam list-policies --profile user_a
ユーザAはiam:ListPoliciesが許可されていないので失敗します。
An error occurred (AccessDenied) when calling the ListPolicies operation〜
それでは次にIAMユーザAでAssumeRoleしてみます。
--role-session-nameは任意の文字列です。
aws sts assume-role --role-arn arn:aws:iam::000000000000:role/iam-test-role --role-session-name hoge --profile user_a
すると下記のように一時的なクレデンシャルが返却されます。
{
"Credentials": {
"AccessKeyId": "WWWWWWWWWW",
"SecretAccessKey": "xxxxxxxxxx",
"SessionToken": "yyyyyyyyyy",
"Expiration": "2023-11-03T15:10:06+00:00"
},
"AssumedRoleUser": {
"AssumedRoleId": "ZZZZZZZZZZ:hoge",
"Arn": "arn:aws:sts::000000000000:assumed-role/iam-test-role/hoge"
}
}
これを環境変数にセットして
export ACCESS_KEY_ID=WWWWWWWWWW export SECRET_ACCESS_KEY=xxxxxxxxxx export SESSION_TOKEN=yyyyyyyyyy
下記コマンドを実行すると、今回は成功しました!
aws iam list-policies
AssumeRoleしている状態を抜ける場合は、環境変数を破棄します。
unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN
AssumeRoleを用いて、許可されていないアクションを実行する流れを確認することができました。
LocalStackでAWS KMSを操作してみる

AWS KMS。 AWS認定ソリューションアーキテクトアソシエイトの勉強をしていた時や、仕事で読んだコードで度々見かけていましたが、 実際に自分で操作をしたことがなかったのでLocalStackでKMSを操作してみました。
AWS KMSってなに?
AWS Key Management Service (KMS) を利用すると、データ保護に使用される暗号化キーを一元管理できます。
つまり、データ保護に使用する暗号化キーをAWS側が管理してくれるので、我々が暗号化キーを管理する必要がありません。 IAM ユーザやIAM ロールに適切なポリシーを設定することで、暗号化キーを安全に管理することができます。
KMSをLocalStackで操作してみる

ローカルにpassword.txtというファイルを用意しました。 ファイルの中には平文で mypassword と記述してあります。
$ ls -la password.txt $ cat password.txt mypassword
KMSキーを作成する
平文のパスワードを暗号化したいです。 しかし、暗号化するためのキーは自分で管理したくありません。 暗号化されたパスワードと暗号化に使用したキーの両方を盗まれた場合にパスワードを複合されてしまうからです。 そこでKMSの出番です。KMSは暗号化に使用するキーであるKMSキーを管理してくれます。

$ awslocal kms create-key
{
"KeyMetadata": {
"AWSAccountId": "000000000000",
"KeyId": "e6a25557-e58a-4a47-929d-5404b4ac73e1",
"Arn": "arn:aws:kms:ap-northeast-1:000000000000:key/e6a25557-e58a-4a47-929d-5404b4ac73e1",
"CreationDate": "2023-09-13T10:15:00.026118+09:00",
"Enabled": true,
"Description": "",
"KeyUsage": "ENCRYPT_DECRYPT",
"KeyState": "Enabled",
"Origin": "AWS_KMS",
"KeyManager": "CUSTOMER",
"CustomerMasterKeySpec": "SYMMETRIC_DEFAULT",
"KeySpec": "SYMMETRIC_DEFAULT",
"EncryptionAlgorithms": [
"SYMMETRIC_DEFAULT"
],
"MultiRegion": false
}
}
KMSキーを作成するコマンドを実行するとKMSキーの情報が’返却されます。
暗号化をする際にKeyIdを使用します。
KMSキーを使用して平文のパスワードを暗号化する

下記のコマンドで平文のパスワードpassword.txtを暗号化し、
encrypted_password.txtを作成します。
KMSキーを作成した際に取得したKeyIdを--key-idに渡します。
$ awslocal kms encrypt \
--key-id e6a25557-e58a-4a47-929d-5404b4ac73e1 \
--plaintext fileb://password.txt \
--output text \
--query CiphertextBlob | base64 \
--decode > encrypted_password.txt
暗号化されたパスワードの書かれているencrypted_password.txtを確認すると
平文のパスワードは暗号化されており、KeyIdが記述されています。
$ cat encrypted_password.txt
e6a25557-e58a-4a47-929d-5404b4ac73e1?{o???'>pZ??l??A??1?????Ui?&??b??9??+?"??
このKeyId が記述されていることにより、encrypted_password.txtを複合化する際にKMSは
このKeyId を持つKMSキーを使用します。
平文パスワードの削除

暗号化されたパスワード encrypted_password.txtがあり、
それを複合化するためのKMSキーがAWS KMSで管理されています。
平文のパスワードpassword.txtをローカルに置いておく必要はないので削除します。
$ rm password.txt $ ls -la encrypted_password.txt
暗号化されたパスワードの複合化

暗号化されたパスワードにKMSキーのKeyIdが記述されているので、
複合化する際はKMSにKeyIdを知らせる必要はありません。
$ awslocal kms decrypt \
--ciphertext-blob fileb://encrypted_password.txt \
| jq -r '.Plaintext' | base64 --decode > password.txt
$ ls -la encrypted_password.txt password.txt $ cat password.txt mypassword
暗号化されたパスワードを平文で取得できました!
AWS Glue crawlerとAthenaを使ってS3に置いてあるCSVファイルへSQLを実行する
AWS Athenaを使ってS3に置いてあるCSVファイルへSQLを実行する機会はあるのですが、自分で環境構築をしたことがありませんでした。 また、AWS Glueは様々な機能を持っていて、Athenaとどう関係があるのかを理解できていませんでした。 そこで、Athenaの環境構築をTerraformでやってみます。
最低限下記の3つを作成する必要があります。
テーブルについては手動で作成することもできますが、Glueクローラーを使ってCSVファイルから自動で作成することもできます。 今回はGlueクローラーを使います。
Glueクローラーの作成
Glueクローラーを作成するために下記を行います。
resource "aws_glue_catalog_database" "aws_glue_catalog_database_example" {
name = "athena-example-database"
}
data "aws_s3_bucket" "hoge_test_athena_bucket" {
bucket = "hoge-test-athena"
}
data "aws_iam_role" "glue_crawler_athena_example_role" {
name = "glue_crawler_athena_example_role"
}
resource "aws_glue_crawler" "glue_crawler_athena_example" {
database_name = aws_glue_catalog_database.aws_glue_catalog_database_example.name
name = "athena-example-crawler"
role = data.aws_iam_role.glue_crawler_athena_example_role.arn
s3_target {
path = "s3://${data.aws_s3_bucket.hoge_test_athena_bucket.bucket}"
}
}
Glueクローラーを実行してテーブルの作成
今回は下記の内容でCSVファイルを用意し、hoge-test-athena bucketへ置きました。
name,amount,price,producer,country apple,10,1500,Michael,Japan
それでは先ほど作成したクローラの名前を指定して、クローラを実行します。
aws glue start-crawler --name athena-example-crawler
しばらくするとAWSコンソール > AWS Glue > Data Catalog > Databases > Tables
にhoge_test_athenaというテーブルが作成され、テーブルスキーマが生成されていることが確認できました。

SQLの実行
Athenaを使ってSQLを実行します。
実行するにはワークグループを指定する必要があります。
今回は下記のようにdeveloperという名前のワークグループを作成しました。
CloudWatchメトリクスは今回不要なのでfalseに、
また、result_configuration.output_locationでクエリの結果を保存するS3 bucketを指定しています。
data "aws_s3_bucket" "hoge_test_athena_result_bucket" {
bucket = "hoge-test-athena-result"
}
resource "aws_athena_workgroup" "developer" {
name = "developer"
configuration {
publish_cloudwatch_metrics_enabled = false
result_configuration {
output_location = "s3://${data.aws_s3_bucket.hoge_test_athena_result_bucket.bucket}"
}
}
}
それではクローラによって作成されたテーブルに対してSELECT文を実行してみます。 ワークグループはdeveloperを指定します。

期待通りの結果が確認できました。