エラー MalformedPolicy: Policy has invalid resource で S3 のバケットポリシーを作成できなかった話 (Terraform)
問題の Terraform コンフィグ
まずは下記のコンフィグを apply する。
(provider 等の指定は省略している。)
resource "aws_s3_bucket" "b" { acl = "private" } resource "aws_s3_bucket_policy" "b" { bucket = aws_s3_bucket.b.id policy = data.aws_iam_policy_document.b.json } data "aws_iam_policy_document" "b" { statement { effect = "Allow" principals { type = "AWS" identifiers = [ "arn:aws:iam::111111111111:role/iam-role-name", "arn:aws:iam::222222222222:role/iam-role-name" ] } actions = [ "s3:AbortMultipartUpload", "s3:GetBucketLocation", "s3:GetObject", "s3:ListBucket", "s3:ListBucketMultipartUploads", "s3:PutObject", "s3:PutObjectAcl" ] resources = [ "${aws_s3_bucket.b.arn}/", "${aws_s3_bucket.b.arn}/*" ] } }
すると、S3バケットポリシーを作成するタイミングで下記のエラーが発生する。
aws_s3_bucket_policy.b: Still creating... [10s elapsed] aws_s3_bucket_policy.b: Still creating... [20s elapsed] aws_s3_bucket_policy.b: Still creating... [30s elapsed] aws_s3_bucket_policy.b: Still creating... [40s elapsed] aws_s3_bucket_policy.b: Still creating... [50s elapsed] ╷ │ Error: Error putting S3 policy: MalformedPolicy: Policy has invalid resource
原因
statement 内の resources の指定が誤っていた。
誤
resources = [ "${aws_s3_bucket.b.arn}/", "${aws_s3_bucket.b.arn}/*" ]
${aws_s3_bucket.b.arn}
の後の /
が余計だった。
正
resources = [ "${aws_s3_bucket.b.arn}", "${aws_s3_bucket.b.arn}/*" ]
あらためてドキュメントを読む
ARN (Amazon Resource Name ) は下記の共通の形式を持っている。
arn:partition:service:region:namespace:relative-id
S3 の場合は region および namespace が省略されるので以下の通りである。
arn:aws:s3:::relative-id
S3 においてこの relative-id として許容されるのは bucket-name
もしくは bucket-name/object-key
らしい。
つまり、いずれにも当てはまらない bucket-name/
が存在したことによって MalformedPolicy と判断されたのであった。
AWS アカウントの代替の連絡先 (alternate contacts) を AWS CLI から登録する
はじめに
2021/9/30 の当該アップデートで下記 3つの API が追加されました。
- DeleteAlternateContact
- GetAlternateContact
- PutAlternateContact
その名の通り AWS アカウントの「代替の連絡先」を削除・取得・登録する API です。
勤務先で Organizations を導入したばかりのところにこのアップデートがやってきたので、全アカウントにセキュリティコンタクトを登録してみました。
事前準備
AWS CLI のアップデート(2021/10/03時点)
私の CloudShell の環境では AWS CLI のバージョンが旧く、登録のための aws account
コマンドが使用できませんでした。
同様の状況だった場合は下記のコマンドで AWS CLI をアップデートしてください。
$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" $ unzip awscliv2.zip $ sudo ./aws/install --update
$ aws --version aws-cli/2.2.43 Python/3.8.8 Linux/4.14.243-185.433.amzn2.x86_64 exec-env/CloudShell exe/x86_64.amzn.2 prompt/off
「信頼されたアクセス」の有効化
Organizations 経由で代替の連絡先を登録するためには「信頼されたアクセス」を有効化してあげる必要があります。
管理アカウントで下記コマンドを実行して有効化します。
$ aws organizations enable-aws-service-access --service-principal account.amazonaws.com
登録手順(メンバーアカウント)
基本的にこのブログにそって登録していきます。 以下の手順は管理アカウントの CloudShell から実施しています。
シェルスクリプトの準備
ブログ内の手順では2つのシェルスクリプトを使用してセキュリティコンタクトの登録を行っています。
loop-through-accounts.sh の準備
下記のコマンドを CloudShell で実行してシェルスクリプトの作成・パーミッションの変更を実施します。
cat << EOF > loop-through-accounts.sh #! /bin/bash managementaccount=\`aws organizations describe-organization --query Organization.MasterAccountId --output text\` for account in \$(aws organizations list-accounts --query 'Accounts[].Id' --output text); do if [ "\$managementaccount" -eq "\$account" ] then echo 'Skipping management account.' continue fi ./put-security-contact.sh -a \$account sleep 0.2 done EOF chmod 755 loop-through-accounts.sh
このシェルスクリプトでは Organizations の組織配下に存在するメンバーアカウントのアカウント ID をリストし put-security-contact.sh
(後述) に渡しています。
if ブロックで管理アカウントのアカウント ID が除外されている理由については後述します。
また、組織配下の AWS アカウント数が 1000 を超える場合は pagination で処理する必要があるのでご注意ください。
Using AWS CLI pagination options - AWS Command Line Interface
put-security-contact.sh の準備
下記のコマンドを CloudShell で実行してシェルスクリプトの作成・パーミッションの変更を実施します。
aws account put-alternate-contact
のオプションの Email アドレス・電話番号・役職・氏名は適切なものに変更してください。
cat << EOF > put-security-contact.sh #! /bin/bash while getopts a: flag do case "\${flag}" in a) account_id=\${OPTARG};; esac done echo 'Put security contact for account '\$account_id'...' aws account put-alternate-contact \ --account-id \$account_id \ --alternate-contact-type=SECURITY \ --email-address=security-contact@example.com \ --phone-number="+1(555)555-5555" \ --title="Security Contact" \ --name="Mary Major" echo 'Done putting security contact for account '\$account_id'.' EOF chmod 755 put-security-contact.sh
前述の loop-through-accounts.sh
から受け取った AWS アカウント ID を元に代替の連絡先を登録するシェルスクリプトです。
登録の実行
上記2ファイルの準備が終わったら、loop-through-accounts.sh
を実行して登録します。
./loop-through-accounts.sh
登録手順(管理アカウント)
管理アカウントに代替の連絡先を登録するためには下記のコマンドを実行します。
メンバーアカウントと同様に、Email アドレス・電話番号・役職・氏名を適切なものに変更したあと実行してください。
aws account put-alternate-contact \ --alternate-contact-type=SECURITY \ --email-address=security-contact@example.com \ --phone-number="+1(555)555-5555" \ --title="Security Contact" \ --name="Mary Major"
メンバーアカウント用のコマンドとの差異は --account-id
オプションの有無にあります。
代替の連絡先を登録するオペレーションには Standalone context と Organizations contextの2種類があり、--account-id
オプションでアカウント ID を指定しない場合 Standalone context として実行されます。
管理アカウントの代替の連絡先はこの Standalone context でのみ登録可能であるため、loop-through-accounts.sh
では明示的に管理アカウントの ID を除外していました。
両 context の詳細については下記ドキュメントを参照してください。
Adding or updating the primary and alternate contact information - AWS Account Management
登録の確認
せっかくなので GetAlternateContact API を利用して各アカウントにセキュリティコンタクトが正しく登録されているか確認してみましょう。
下記のコマンドを CloudShell で実行してシェルスクリプトの作成・パーミッションの変更を実施します。
cat << EOF > check-security-contact.sh #! /bin/bash managementaccount=\`aws organizations describe-organization --query Organization.MasterAccountId --output text\` for account in \$(aws organizations list-accounts --query 'Accounts[].Id' --output text); do echo AWS Account ID: \$account if [ "\$managementaccount" -eq "\$account" ] then aws account get-alternate-contact --alternate-contact-type=SECURITY continue fi aws account get-alternate-contact --account-id \$account --alternate-contact-type=SECURITY sleep 0.2 done EOF chmod 755 check-security-contact.sh
作成したシェルスクリプトを実行します。
$ ./check-security-contact.sh AWS Account ID: 111111111111 { "AlternateContact": { "AlternateContactType": "SECURITY", "EmailAddress": "security-contact@example.com", "Name": "xiyegen", "PhoneNumber": "+81(0X0)XXXX-XXXX", "Title": "Security Contact" } } AWS Account ID: 222222222222 { "AlternateContact": { "AlternateContactType": "SECURITY", "EmailAddress": "security-contact@example.com", "Name": "xiyegen", "PhoneNumber": "+81(0X0)XXXX-XXXX", "Title": "Security Contact" } } AWS Account ID: 333333333333 { "AlternateContact": { "AlternateContactType": "SECURITY", "EmailAddress": "security-contact@example.com", "Name": "xiyegen", "PhoneNumber": "+81(0X0)XXXX-XXXX", "Title": "Security Contact" } } (省略)
同一の代替の連絡先がすべてのアカウントに登録できていることを確認できました。
参考
2021/09/30 - AWS Account - 3 new api methods
Programmatically managing alternate contacts on member accounts with AWS Organizations
Lightsail ロードバランサー向けのエイリアスレコードを Route 53 で作成する
本日7月7日はクラスメソッド株式会社の創立記念日です。
なので(?)私もブログを書いてみます。
結論
- Lightsail のロードバランサーにも Route 53 でエイリアスレコードを設定できる
- Route 53 コンソールのロードバランサー一覧には Lightsail のロードバランサーがでてこない
- Lightsail ロードバランサーの DNS 名を直接入力してあげればOK
問題
Lightsail でロードバランサーを作成すると、Lightsail 専用のコンソールから DNS 名を確認できます。
このロードバランサーに対してエイリアスレコードを設定しようとしてもロードバランサーの一覧に出てきません。
Lightsail で作成したロードバランサーはカスタマーのアカウントの外にあるからですね。
ではどうするか。
解決方法
一覧の中にあるロードバランサーを選択するのではなく、ロードバランサーの DNS 名を直接入力してください。
このようにすればレコードが作成可能です。
DNS 名は先述のとおり Lightsail コンソールから確認可能です。
参考資料
Lightsail のドキュメントをちゃんと読んでみるとこの方法が書いてありました。
enter or paste the endpoint URL (i.e., DNS name) of your Lightsail load balancer.
Point your domain to your Lightsail load balancer | Lightsail Documentation
子猫のこの先の成長をざっくり把握したかった
5月の2週目に足立区の保護主さんから子猫を譲り受けた。
そいつ(後にピータンと名付けられる)が我が家の一員となってからは毎日かかさず体重を量り Google スプレッドシートに記入している。
やりたいことができた
2ヶ月ほどで初日の3倍程度に成長したので今後どうなるかをざっくり見てみたいと思った。ここに回帰直線を引きたい pic.twitter.com/fziYBe6b4v
— Nishino Wataru (@xiyegen) 2021年7月5日
「傾き」「切片」「最小二乗法」などの言葉がかすかに脳裏をよぎったものの、結論としては Google スプレッドシートの標準機能であっけないほど簡単に実現できてしまった。
やり方
対象のグラフを選択した後、
① グラフ右上の縦三点リーダーをクリックする。
② 「グラフを編集」をクリックする。
③ グラフエディタ上部の「カスタマイズ」をクリックする。
④ 「系列」をクリックする。
⑤ 系列メニュー内の「トレンドライン」にチェックを入れる。
ただこれだけ。
元のグラフに回帰直線が追加されている。
このまま順調に成長すれば3週間後には 2500g を超えそうだ。
参考資料
トレンドラインを追加、編集する - パソコン - ドキュメント エディタ ヘルプ
(Gスプレッドシート)グラフに近似直線(曲線)・近似式・決定係数を表示する - いきなり答える備忘録
GitLab / GitHub でそれぞれ SSH 鍵を使い分けるために準備したこと
現在の勤務先ではコードリポジトリ・CI/CD ツールとして GitLab を使っています。
プライベートのお勉強用に GitHub を使ってみようとおもったので、それぞれ別の SSH 鍵を使うように設定してみました。
実行環境
- macOS Big Sur 11.4
- MacBook Pro (13inch, M1, 2020)
設定
GitHub 用 SSH 鍵の作成
GitLab 用の SSH 鍵として ~/.ssh/id_rsa(.pub)
を作成済みなので、GitHub Docs の手順にしたがい新たに使用するキーのみ作成します。
Generating a new SSH key and adding it to the ssh-agent
$ ssh-keygen -t ed25519 -C "your_email@example.com" Generating public/private ed25519 key pair. Enter file in which to save the key (/Users/<User名>/.ssh/id_ed25519): /Users/<User名>/.sshid_ed25519.github.com ※ GitHub 用とわかりやすくするためにファイルを変更してます。 Enter passphrase (empty for no passphrase): ※パスフレーズを入力 Enter same passphrase again: ※パスフレーズを再入力
GitHub への SSH 公開鍵登録
続いて、作成した SSH 公開鍵を GitHub アカウントに登録します。
下記コマンドで SSH 公開鍵をクリップボードにコピーします。
$ pbcopy < ~/.ssh/id_ed25519.pub.github.com
GitHub 画面右上部のアイコン → Settings → SSH and GPG keys に飛んだあと、* New SSH key * をクリックしてから Key 欄に SSH 公開鍵をペーストします。
GitHub Docs にはスクリーンショット付きの手順があるのでわかりやすいです。
Adding a new SSH key to your GitHub account
~/.ssh/config の修正
接続先が GitHub の場合にのみ今回作成した SSH 鍵を使うよう、~/.ssh/config
に下記の設定を追記します。
Host github.com AddKeysToAgent yes UseKeychain yes IdentityFile ~/.ssh/id_ed25519.github.com
動作確認
下記のコマンドを入力し GitHub への SSH 接続 を試します。
% ssh -T git@github.com Enter passphrase for key '/Users/<User名>/.ssh/id_ed25519.github.com': ※ SSH 鍵生成時に設定したパスフレーズを入力 Hi xiyegen! You've successfully authenticated, but GitHub does not provide shell access.
作成済みのリポジトリの git clone も試してみます。
$ git clone git@github.com:xiyegen/git-lesson.git Cloning into 'git-lesson'... remote: Enumerating objects: 4, done. remote: Counting objects: 100% (4/4), done. remote: Compressing objects: 100% (3/3), done. remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 0 Receiving objects: 100% (4/4), done.
ちゃんと動いたようです。