AWS CLIとCredentialの話
4月 12日 @ 21:00 ~ 21:30 主催者:TatchNicolas
資料
インフラ勉強会のwiki、主催者:TatchNicolasのユーザ記事内にあります。
https://wiki.infra-workshop.tech/user/TatchNicolas/20180412-aws-cli-credentials#edit-form
この勉強会ログはなるべくチャット内容を追ってます。
映像
https://youtu.be/JYN3zrcoHOs
音声
https://recordings.mee6.xyz/394100660083359754/1523536227-Oi6pLY.mp3
講演
AWS CLIを使ってみよう
-
そもそもAWS CLIとは
- いろんなプログラミング言語から利用できる
- 自動化もできる
- それがCLI
- マネジメントコンソールとCLIは大差ない。(S3のチューニングについてはCLIのほうが有利)
-
CLIのメリット
- 繰返しが容易
- 自動化もできる
- オプション、細かいパラメタを明示的に書くことができる
-
CLIのセットアップ
- IAM Userに対して AccessKeyを発行
-
基本的な使い方
元の資料ページの記載を参照
https://wiki.infra-workshop.tech/user/TatchNicolas/20180412-aws-cli-credentials
$ aws configure --profile hoge AWS Access Key ID [None]: AWS Secret Access Key [None]: Default region name [None]: Default output format [None]:
-
IAM
- 権限は IAM Policyで設定する
- ポリシーは user/group/role に付与可能
- role:帽子(ヘルメット)のイメージ。被ると権限が変わる。
- AWSアカウント:実際に入って操作をするアカウントとは別と思ったほうがよい。
→AWS内で使われる「アカウント」とはIAMを指している場合が多い。AWSアカウントは「契約者」と捉えるとよい。
-
AWSの権限周りの基本的な考え方
- デフォルトはALL拒否(Deny)
- 明示的に許可(拒否)された操作のみ実行可能
- 最小権限を付与する
- 不要な認証情報を削除
- 認証情報を共有するのではなく、ロールを使って委託する
詳しくは公式のベストプラクティス を参照。
Access Keyをソースコードに直書きするのはやめましょう!
-
Access Keyは漏れると本当に大変
- モノの数分でハックされてびっくりするような金額請求される
-
複数アカウント/復数ユーザを使うときに面倒
- 管理すべきAccess Keyが増えるのも嬉しくない
- クラウドに疎い人が上にいちゃうと、「注意を徹底する」とか言ってしまう対応策をやってしまって、いつまでもセキュリティ問題を抱えることになるので注意。
-
個人的に実践していること
- ルートアカウントは使わないで大切にしまっておく
- AssumeRole以外何もできないユーザを用意する
- MFA:多要素認証(6桁の番号)を設定できる
- SAML/LDAP連携などとの連携も可能のようだ・・・
- 操作したい範囲の権限を持ったRoleを作る
- できるだけ、プリセット(AWS Managed)のポリシーから選んで使う
- Conditionsで「MFAが有効である」を条件に追加
- 案件ごとに作業フォルダを用意してdirenvを使ってprofileを切り替え
ひとつのIAM Userで復数のAWSアカウントを操作できる Access KeyをMFAで保護することができる
-
direnvで.envrcの設定
- いつも
aws --profile adminrole iam list-users
とコマンドを打つのは面倒くさい - そこでdirenv。
.envrc
を作って、そのディレクトリの中でロールを変えると楽。
- いつも
-
Roleを使わなくても可能だが、結構面倒
aws sts get-session-token --token-code 123456
- 帰ってきた、とてつもなく長い一時認証情報を環境変数または
~/.aws/configure
に保存
-
--profile
なし、direnv+環境変数で操作対象を切り替えると今どの環境を触っているのか意識しにくい- 作業ディレクトリを決めるのが一番だが…
- IAM Userは
aws sts get-caller-identity
で自分が誰なのかわかる
-
Assume Roleで利用する一時認証情報の期限は自分で設定できる
- あんまり長いと守りとして弱い、短いと頻繁にMFAコードを求められてストレス
- たとえば複数のプロファイルがあった場合、
~/development/.envrc ~/staging/.envrc ~/production/yatteiki/.envrc
とか分けるのかやってます。
参加者の声
(Discord 上の発言を取り上げています)
- CLI、fish shellとちょっとだけ相性悪いことがある。
たまにちゃんと環境変数読んでくれないんすよね。
なんでかわかんない。 - CloudFormation、マネ-ジドコンソールでポチポチして、再実行するのめっちゃ面倒でハゲそうになりました。
- 基本的な例はこんな感じ
aws ec2 describe-instances \ --query 'Reservations[].Instances[].{ID:InstanceId,TYPE:InstanceType,OS:Platform,PRIVATE_IP:PrivateIpAddress,NAME:Tags[?Key==Name].Value|[0]}' \ --output table
- みんなCLIはデフォルトリージョンが、バージニアだから気をつけろよ!!
- Profile作るときにリージョン指定もできるよ!
- MFA:多要素認証ですが、Chrome連携してくれるのでAuthy使ってます。
https://authy.com/ - OneTimePasswordとして、IIJ SmartKeyだと機種変更も楽です
- mac勢はenvchainも便利
https://github.com/sorah/envchain - 検証環境だったら、Organizationでプロジェクト毎とかでAWSアカウント作るのがいいですね
- 自動化の話であればcodenize-toolのmiamも便利です。rubyのコードでIAM定義を書けるツールです
https://github.com/codenize-tools/miam - AWSのアカウント管理の仕方は一つ前といわれることがあるような。AzureやGCPではできるに、AWSは古いからかできないとか。
やっぱり後続の方がそこは強い…
Q & A
-
Q. IAMアカウントと、GCPの組織と、MSのDynamic365の組織が似たような感じですか?
- A.Dynamic365がわからない…GCPもちょっと…(チャット参加者もお手上げ)
-
Q. 起動できるインスタンスを制限とかってできないのですかね?
- A.デフォルトできるインスタンス数の制限はあります。
でもリージョンごとなので全部のリージョンで上限までインスタンス建てられて死にます。
- A.デフォルトできるインスタンス数の制限はあります。
-
Q. AssumeRole について質問です。 例えば、以下はAWSServiceRoleForECS(AWS側が提供しているIAMロール)の AssumeRoleの設定で、
マネジメントコンソール上で信頼関係タブに当たる箇所(下のコード)ですが、これは具体的に何をやってる設定になりますか?
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ecs.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
- A.Principal(原理的な)ですか。 そのロールを、ecsが被っていいよ~と指定してます。
- Q. アプリケーションに設定して常時使うようなAccesssKeyとかも裸のIAMユーザを作って帽子をかぶせる、という運用で考えておられるでしょうか。
- A. アプリケーションに設定するだと、アプリケーションが動くサービス(ec2だったりLamdaだったり)にRoleを付けるのがやり方です。裸のIAMユーザにつけないですね。
- Q. LambdaとかEC2みたいなサービスそのものにIAM権限を付与できるんでしょうか
- A.はい、その通りです。
- Q. 帽子をかぶるときってどんなコマンドになるのですか?
- A.以下の形です。profileでhogeを指定して…
$ aws --profile hoge cloudformation describe-stacks Enter MFA code for arn:aws:iam::123456789012:mfa/foo:
他にも
aws sts assume-role --role-arn arn:aws:iam::xxxxx:role/assume-role-test --role-session-name zzzzz(任意)