AWS CLI と SDK のセットアップ
aws cli v2 のインストールと aws configure、プロファイルと認証情報ファイル、boto3 / aws-sdk-js のような SDK の用途、そして認証情報チェーンが流れる順序まで — コンソールの外で AWS と働くセットアップを整理します。
第2章 IAM で作ったユーザーのアクセスキー、そして 第3章 コスト管理 でオンにした決済アラートが準備できました。いよいよコンソールの外で AWS と働く番です。
コンソールは学習や一回限りの作業に良いですが、反復 / 自動化 / 精密な作業には限界が来ます。そのとき2つが登場します。一つは AWS CLI で、ターミナルで aws s3 cp ... のようなコマンドで AWS を操る道具です。もう一つは SDK で、コードの中から AWS を呼ぶライブラリ(Python の boto3、JS の aws-sdk など)です。
本章はその2つのセットアップと、その裏で認証情報が流れる順序(credential chain)を整理します。ここで押さえる認証情報チェーンは 第5章 CloudShell と SSO の SSO ログインまでそのままつながります。
AWS CLI v2 のインストール #
CLI は v1 と v2 があります。v2 が標準です。v1 はもう使いません。v2 の違いは次のとおりです。
- 単一の実行ファイル(Python 環境への依存なし)
- IAM Identity Center (SSO) のネイティブサポート(第5章 CloudShell と SSO)
- より速い出力とより豊かな自動補完
aws configure importのような新しいコマンド
macOS #
brew install awscliまたは公式 pkg でインストールします。
curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "AWSCLIV2.pkg"
sudo installer -pkg AWSCLIV2.pkg -target /Linux #
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/installWindows #
winget または MSI インストーラーを使います。
winget install -e --id Amazon.AWSCLIインストールの確認 #
aws --version
# aws-cli/2.x.x Python/3.x.x ...2.x.x が見えなければ which aws で v1 の残骸を確認した後に削除します。
aws configure — 認証情報の登録 #
CLI がインストールされたら、第2章 IAM のユーザーのアクセスキーを登録します。
aws configure
# AWS Access Key ID [None]: AKIA...
# AWS Secret Access Key [None]: wJal...
# Default region name [None]: ap-northeast-2
# Default output format [None]: jsonこの4つの値が2つのファイルに分かれて保存されます。
~/.aws/credentials # キー (機密)
~/.aws/config # region / output / role / など~/.aws/credentials の形
#
[default]
aws_access_key_id = AKIA...
aws_secret_access_key = wJal...~/.aws/config の形
#
[default]
region = ap-northeast-2
output = jsonプロファイル — 複数の認証情報を同時に #
複数のアカウント / 環境 / ロールを扱うと、default 一つでは足りません。プロファイルで複数の認証情報を分離します。
プロファイルの追加 #
aws configure --profile dev
aws configure --profile prod[default]
aws_access_key_id = AKIA...
[dev]
aws_access_key_id = AKIA-DEV-...
aws_secret_access_key = ...
[prod]
aws_access_key_id = AKIA-PROD-...
aws_secret_access_key = ...プロファイルの使用 #
3つの方法があります。
aws s3 ls --profile prodexport AWS_PROFILE=prod
aws s3 lsfunction awsenv() {
export AWS_PROFILE=$1
echo "AWS_PROFILE=$AWS_PROFILE"
}
# 使用: awsenv prod運用では環境変数とともに、シェルプロンプトに現在のプロファイルを表示するパターンがよくあります。
シェルプロンプトに現在のプロファイルを表示する #
AWS_PROFILE をプロンプトに出すと事故が減ります。
PROMPT='%n@%m %1~ ${AWS_PROFILE:+[aws:$AWS_PROFILE]} %# '運用用のターミナルの色を変えるパターンもよくあります。prod プロファイルのときは赤、dev のときは緑のようにするやり方です。
Role の使用 — assume-role の流れ #
第2章 IAM で扱ったロール(Role)を CLI で借りる流れです。マルチアカウントのセットアップの標準パターンです。
[profile prod]
role_arn = arn:aws:iam::222222222222:role/AdminRole
source_profile = default
mfa_serial = arn:aws:iam::111111111111:mfa/curtis
region = ap-northeast-2このプロファイルを使うと、次の順序で作動します。
defaultプロファイルの認証情報で STS AssumeRole を呼び出します。- MFA コードを尋ねます(
mfa_serialがあれば)。 - 一時認証情報を受け取ってコマンドに使います。
- 1時間キャッシュして再利用します。
aws s3 ls --profile prod
# Enter MFA code for arn:aws:iam::111111111111:mfa/curtis: 123456
# (以後1時間キャッシュ)CI 環境では 第5章 CloudShell と SSO の IAM Identity Center (SSO)の方が滑らかです。
環境変数 — CI とコンテナの認証情報 #
~/.aws/credentials がない環境(CI、コンテナ、一時シェル)では環境変数を使います。
| 変数 | 何か |
|---|---|
AWS_ACCESS_KEY_ID | アクセスキー |
AWS_SECRET_ACCESS_KEY | シークレットキー |
AWS_SESSION_TOKEN | 一時認証情報のとき一緒に (STS / SSO) |
AWS_REGION または AWS_DEFAULT_REGION | リージョン |
AWS_PROFILE | プロファイル名 |
export AWS_ACCESS_KEY_ID=AKIA...
export AWS_SECRET_ACCESS_KEY=...
export AWS_REGION=ap-northeast-2
aws s3 ls認証情報チェーン — どこで認証情報を探すか #
CLI と SDK が認証情報を探す順序が決まっています。これを知らないと「なぜこのキーで動いているのか」というデバッグに時間を無駄にします。
1. コマンドラインオプション (--profile, --region など)
2. 環境変数 (AWS_ACCESS_KEY_ID など)
3. アシスタントファイル (CLI Web Identity Token, Container Credentials)
4. ~/.aws/credentials の default または指定プロファイル
5. ~/.aws/config のプロファイル (role_arn, sso_session など)
6. EC2 / ECS / Lambda のインスタンス / コンテナの認証情報EC2 の中で aws s3 ls が認証情報なしで作動する理由は、6段階のインスタンスメタデータが捕まえてくれるからです(第2章 IAM のインスタンスプロファイル)。
どの認証情報が使われているかの確認 #
aws sts get-caller-identity
# {
# "UserId": "AIDA...",
# "Account": "111111111111",
# "Arn": "arn:aws:iam::111111111111:user/curtis"
# }この一行がデバッグの最初の段階です。どのユーザー / どのアカウントで動いているかが出ます。
よく使う CLI コマンド #
出力フォーマット #
aws ec2 describe-instances --output json # デフォルト
aws ec2 describe-instances --output table # 人向け
aws ec2 describe-instances --output text # grep / awk 用
aws ec2 describe-instances --output yaml # YAML–query — JMESPath で選び出す #
JSON 出力が長くて grep では限界が来ます。--query で必要な部分だけ選び出します。
aws ec2 describe-instances \
--query 'Reservations[].Instances[?State.Name==`running`].[InstanceId,InstanceType]' \
--output tableJMESPath の文法は最初は難しいですが、よく使うパターン5 ~ 10個だけ覚えれば日常作業が速くなります。
| パターン | 意味 |
|---|---|
[] | 配列の平坦化 |
[?key==\value`]` | フィルター |
[].field | フィールドの取り出し |
[].[a,b,c] | 複数のフィールドを新しい配列に |
length(@) | 長さ |
sort_by(@, &date) | ソート |
よく使うコマンド #
aws sts get-caller-identity
aws configure list
aws configure list-profilesaws s3 ls # すべてのバケット
aws s3 ls s3://my-bucket/ # バケットの中
aws s3 cp file.txt s3://my-bucket/ # アップロード
aws s3 sync ./local s3://my-bucket/ # フォルダ同期
aws s3 rm s3://my-bucket/file.txt # 削除
aws s3 presign s3://my-bucket/file.pdf --expires-in 3600aws ec2 describe-instances
aws ec2 start-instances --instance-ids i-...
aws ec2 stop-instances --instance-ids i-...
aws ec2 describe-regions --query 'Regions[].RegionName'aws iam list-users
aws iam get-user --user-name curtis
aws iam list-attached-user-policies --user-name curtis
aws iam create-access-key --user-name curtisSDK — コードの中の AWS #
CLI がターミナルなら、SDK はコードです。同じ認証情報チェーンを共有します。
Python — boto3 #
pip install boto3import boto3
s3 = boto3.client("s3")
res = s3.list_buckets()
for b in res["Buckets"]:
print(b["Name"])認証情報は自動的に認証情報チェーンから探します — ~/.aws/credentials、環境変数、EC2 インスタンスプロファイルなどです。
明示的なプロファイル / リージョン #
session = boto3.Session(profile_name="prod", region_name="ap-northeast-2")
s3 = session.client("s3")リソース vs クライアント #
boto3 には2つのインターフェースがあります。
s3 = boto3.client("s3")
res = s3.list_objects_v2(Bucket="my-bucket")
for obj in res.get("Contents", []):
print(obj["Key"])s3 = boto3.resource("s3")
for obj in s3.Bucket("my-bucket").objects.all():
print(obj.key)現代の boto3 は client を推奨します。resource は一部のサービスだけをサポートし、新しいサービスはもう追加されません。
Pagination — よく出会う落とし穴 #
list_objects_v2 は1回で取得できるのが最大1000個です。それ以上は paginator で受け取ります。
s3 = boto3.client("s3")
paginator = s3.get_paginator("list_objects_v2")
for page in paginator.paginate(Bucket="my-bucket"):
for obj in page.get("Contents", []):
print(obj["Key"])JavaScript / TypeScript — aws-sdk v3 #
v2 は deprecated です。v3 へ行きます。
npm install @aws-sdk/client-s3import { S3Client, ListBucketsCommand } from "@aws-sdk/client-s3";
const client = new S3Client({ region: "ap-northeast-2" });
const res = await client.send(new ListBucketsCommand({}));
for (const b of res.Buckets ?? []) {
console.log(b.Name);
}v3 の特徴は次のとおりです。
- モジュール式 — 必要なサービスだけ import (バンドルサイズの削減)
- ツリーシェイキングに親和的
- すべての呼び出しが
client.send(new XxxCommand(...))のパターン
Go — aws-sdk-go-v2 #
go get github.com/aws/aws-sdk-go-v2/aws
go get github.com/aws/aws-sdk-go-v2/config
go get github.com/aws/aws-sdk-go-v2/service/s3package main
import (
"context"
"fmt"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/s3"
)
func main() {
ctx := context.Background()
cfg, err := config.LoadDefaultConfig(ctx, config.WithRegion("ap-northeast-2"))
if err != nil {
panic(err)
}
client := s3.NewFromConfig(cfg)
res, err := client.ListBuckets(ctx, &s3.ListBucketsInput{})
if err != nil {
panic(err)
}
for _, b := range res.Buckets {
fmt.Println(*b.Name)
}
}Go トラック のコンベンションどおり context 優先と明示的なエラーに従います。
自動補完をオンにする #
タブ自動補完をオンにすると、CLI がずっと滑らかになります。
autoload bashcompinit && bashcompinit
autoload -Uz compinit && compinit
complete -C "$(which aws_completer)" awscomplete -C "$(which aws_completer)" aws.zshrc や .bashrc に入れて新しいシェルを開きます。これで aws s3 <TAB> をするとコマンドとオプションが見えます。
よく出会う落とし穴 #
~/.aws/credentialsを git にコミット — 最も危険な事故です。必ず.gitignoreに.aws/、またはグローバルの gitignore に入れます。そしてアクセスキーはできる限り環境変数 / SSO に置き、ファイルに置かないのが基本です。- 間違ったプロファイルで運用コマンド —
AWS_PROFILE=devで動かしていたのに、コマンドに--profile prodが別に書かれていて prod バケットが見える場合があります。出処を明示し、aws sts get-caller-identityで先に点検するのが基本です。 - 認証情報チェーンのデバッグ — 「環境変数にキーを入れたのに古いキーで動く」なら、認証情報チェーンの1段階(コマンドライン
--profile)が優先か、シェルが export を受け取れていない可能性です。aws sts get-caller-identityで先に診断します。 - v1 の残骸 —
aws --versionが 1.x なら(特に macOS / Linux のpip install awscliの痕跡)v1 の残骸です。v1 と v2 が同時に PATH にあると意図しない v1 が実行されるので、which awsで確認して削除します。 - ページネーションの抜け —
list_*API はほぼすべてページネーションがあります。最初のページだけ処理して終えると、1000番目以降のデータが抜けます。paginatorまたはNextTokenループを使います。 - SDK の認証情報をコードに入れる — 下のようにコードにキーを入れると git で漏洩して事故につながります。
boto3.client("s3", aws_access_key_id="AKIA...", aws_secret_access_key="...")認証情報は環境 / プロファイル / インスタンスプロファイルから受け取ります。
練習問題 #
- §「認証情報チェーン」の6段階を見ずに順番に書いてみましょう。それから、EC2 の中で
aws s3 lsがキーなしで作動する理由が何番目の段階かを 第2章 IAM のインスタンスプロファイルと結びつけて説明してみましょう。 - §「Role の使用 — assume-role の流れ」の
role_arn+source_profile+mfa_serialプロファイルが、第2章 IAM の Trust Policy と Permission Policy のうちどちらの流れを再現するかを一段落で説明してみましょう。 aws ec2 describe-instancesの出力から、実行中のインスタンスの ID とタイプだけを抜き出す--query式を §「–query」の表を参考に自分で書いてみましょう。
一行まとめ: AWS CLI v2 と SDK は同じ認証情報チェーンを共有し、認証情報はコマンドライン → 環境変数 → ファイル → インスタンスプロファイルの順で探します。
aws configureは認証情報を~/.aws/credentialsと~/.aws/configの2ファイルに分けて保存し、プロファイルで複数のアカウントを分離します。キーをコードや git に入れずaws sts get-caller-identityで先にアイデンティティを確認するのがデバッグと事故予防の基本です。
次の章 #
ローカルのセットアップが終わりました。ところが他人のノートパソコンや会社の一時環境でも同じ CLI が必要なときがあり、マルチアカウントが始まるとログイン自体がより精巧になる必要があります。次の 第5章 CloudShell と SSO では、コンソールの中のブラウザターミナル CloudShell と、マルチアカウントの標準ログインとなった IAM Identity Center (SSO)のセットアップを整理します。