コンテンツにスキップ

AWS CLI@AWS

はじめに

本サイトにつきまして、以下をご認識のほど宜しくお願いいたします。


01. AWS CLIのセットアップ

configure

▼ configure

認証情報を設定する。

OSによって、認証情報ファイルが配置される場所が異なる。

$ aws configure

▼ --profile

プロファイルを新しく作成する。

$ aws configure --profile <プロファイル名>

AWS Access Key ID [None]: <アクセスキーID>
AWS Secret Access Key [None]: <シークレットアクセスキー>
Default region name [None]: <リージョン名>
Default output format [None]: <アウトプット形式>


list

▼ listとは

現在設定されている認証情報を取得する。

$ aws configure list


set

▼ setとは

認証情報の特定の項目を設定する。

$ aws configure set <認証情報の項目>

アクセスキーIDを設定する。

$ aws configure set aws_access_key_id "<アクセスキーID>"

シークレットアクセスキーを設定する。

$ aws configure set aws_secret_access_key "<シークレットアクセスキー>"

リージョンを設定する。

aws_region』ではなく『aws_default_region』であることに注意する。

$ aws configure set aws_default_region "<リージョン名>"


01-02. 設定ファイル

~/.aws/confidentialsファイル

~/.aws/confidentialsファイルとは

認証情報を設定する。

LinuxやUnixの場合は、$HOME/.aws/<認証情報ファイル名>に配置される。

また、Windowsの場合は、%USERPROFILE%\.aws\<認証情報ファイル名>に配置される。

▼ aws_access_key_id

AWS CLIを実行するアカウントのアクセスキーIDを設定する。

configファイルに設定することもできるが、confidentialsファイルへの設定が推奨である。

[default]
aws_access_key_id = *****

▼ aws_secret_access_key

AWS CLIを実行するアカウントのシークレットアクセスキーIDを設定する。

configファイルに設定することもできるが、confidentialsファイルへの設定が推奨である。

[default]
aws_secret_access_key = *****

▼ aws_session_token

認証で補助的に使用するセッショントークン値を設定する。

configファイルに設定することもできるが、confidentialsファイルへの設定が推奨である。

[default]
aws_session_token = *****


~/.aws/configファイル

▼ output

AWS CLIの返却値のデータ形式を設定する。

[default]
output = json

▼ region

AWS CLIで操作するAWSリソースのリージョンを設定する。

[default]
region = ap-northeast-1

▼ role_arn

AWS CLIの実行で、IAMユーザーに委譲するIAMロールを設定する。

[profile foo]
role_arn = arn:aws:iam::<AWSアカウントID>:role/foo-role

▼ role_session_name

IAMロールの委譲後のIAMユーザーの一時的な名前を設定する。

[profile foo]
role_session_name = hiroki.hasegawa

▼ source_profile

IAMロールの委譲先のIAMユーザーのプロファイル名を設定する。

[profile foo]
source_profile = default


01-03. 環境変数

AWS_ACCESS_KEY_ID

現在のターミナルで使用するアクセスキーIDを設定する。

$ export AWS_ACCESS_KEY_ID=<アクセスキーID>


AWS_DEFAULT_PROFILE

現在のターミナルで使用するプロファイルを設定する。

AWS_PROFILE変数よりも優先される。

$ export AWS_DEFAULT_PROFILE=default


AWS_DEFAULT_REGION

現在のターミナルで使用するリージョンを設定する。

AWS_REGION』ではなく『AWS_DEFAULT_REGION』であることに注意する。

$ export AWS_DEFAULT_REGION=ap-northeast-1


AWS_PROFILE

現在のターミナルで使用するプロファイルを設定する。

$ export AWS_PROFILE=foo-profile


AWS_SECRET_ACCESS_KEY

現在のターミナルで使用するシークレットアクセスキーを設定する。

$ export AWS_SECRET_ACCESS_KEY=<シークレットアクセスキー>


AWS_SESSION_TOKEN

現在のターミナルで使用するセッショントークンを設定する。

AWS STSで発行された一時的な認証情報に含まれ、この認証情報を使用する時に、アクセスキーIDとシークレットアクセスキーと合わせて必要になる。

$ export AWS_SESSION_TOKEN=<セッショントークン>


02. 返却データの出力方法の制御

形式系

▼ 形式系とは

返却されるデータの形式を設定できる。

▼ json

.json形式で取得する。

$ aws iam list-users --output json > data.json

▼ yaml

yaml形式で取得する。

$ aws iam list-users --output yaml > data.yaml

▼ text

タブ切り形式で取得する。

表計算ソフトで扱いやすい。

$ aws iam list-users --output text > data.tsv


ページ分割系

▼ ページ分割系とは

返却されるデータのページングを設定できる。

▼ --max-items

取得する項目の最大数を設定する。

$ aws iam list-users --max-items 100

▼ --no-paginate

ページングを無効化する。

$ aws iam list-users --no-paginate

▼ --page-size

ページ当たりで取得する項目数を設定する。

$ aws iam list-users --page-size 10


API側のフィルタリング系

▼ API側のフィルタリング系とは

AWSリソースのAPI側でフィルタリングし、実際に取得するデータを制御できる。

AWSリソースごとに専用のオプションがある。

代わりとして、jqコマンドのselect関数を使用しても良い。

▼ --filter

SES、Cost Explorer、など

▼ --filters

EC2、AutoScaling、RDS、など

# 特定のタグ値のデータのみを取得する。『tag:』のつけ忘れに注意する。
$ aws ec2 describe-instances --filters "Name=tag:<タグ名>,Values=<タグ値>"

▼ filterの文字を含む独自のオプション

DynamoDB、など

▼ --include

ACM、など


コマンド実行側のフィルタリング系

▼ コマンド実行側のフィルタリング系とは

コマンド実行側でフィルタリングし、取得するキーや値を制御できる。

代わりとして、jqコマンドのパスを使用しても良い。

▼ --query

# 全てのキーと値を取得する。
$ aws ec2 describe-instances --query "Reservations[*]"
# 最初のインデックスキーのみを取得する。
$ aws ec2 describe-instances --query "Reservations[0]"
# 特定のタグ値のデータのみを取得し、そのデータのインスタンスIDのみを取得する。
$ aws ec2 describe-instances \
    --filters "Name=tag:<タグ名>,Values=<タグ値>" \
    --query "Reservations[*].Instances[*].InstanceId"

# 特定のタグ値のデータのみを取得し、そのデータのセキュリティグループのIDのみを取得する。
$ aws ec2 describe-instances \
    --filters "Name=tag:<タグ名>,Values=<タグ値>" \
    --query "SecurityGroups[*].GroupId"


03. AWSリソース別のプラクティス

グローバルオプション

▼ --region

リージョンを指定して、コマンドを実行する。

認証情報ファイルや環境変数を変更する手間が省ける。


CloudWatch

▼ set-alarm-state

*例*

CloudWatchアラームの状態を変更する。

$ aws cloudwatch set-alarm-state \
    --alarm-name "prd-foo-alarm" \
    --state-value ALARM \
    --state-reason "アラート!!"
$ aws cloudwatch set-alarm-state \
    --alarm-name "prd-foo-alarm" \
    --state-value OK \
    --state-reason "大丈夫です!!"

▼ get-metric-statistics

*例*

全てのロググループに対して、一日当たりの収集サイズをstart-timeからend-timeの間で取得する。

--dimensionsオプションを使用して、特定のディメンション (ロググループ) に対して集計を実行もできる (ただし、やってみたけどうまくいかず) 。

$ aws cloudwatch get-metric-statistics \
    --namespace AWS/Logs \
    --metric-name IncomingBy*** \
    --start-time "2021-08-01T00:00:00" \
    --end-time "2021-08-31T23:59:59" \
    --period 86400 \
    --statistics Sum \
      | jq -r ".Datapoints[] | [.Timestamp, .Sum] | @csv" | sort


CodeDeploy

▼ register-on-premises-instance

オンプレミスのサーバーをCodeDeployのデプロイ先として設定する。

$ aws deploy register-on-premises-instance \
    --region ap-northeast-1 \
    --instance-name foo-on-premises-instance \
    --iam_session_arn <IAM Session ARN>


ECR

▼ get-login-password

一時的に有効なパスワード取得する。

aws ecr get-login --no-include-emailコマンドを使用することは非推奨である。

$ aws ecr get-login-password --region ap-northeast-1


EKS

▼ update-addon

コンフリクトでEKSアドオンの設定を更新できない場合に、変更できるようにする。

$ aws eks update-addon --cluster-name foo-cluster \
    --addon-name <アドオン名> \
    --addon-version v1.14.1-eksbuild.1 \
    --resolve-conflicts PRESERVE


IAM

▼ update-user

ユーザー名は、コンソール画面から変更できず、コマンドで変更する必要がある。

$ aws iam update-user \
    --user-name <現行のユーザー名> \
    --new-user-name <新しいユーザー名>


Resource Groups

▼ get-resources

AWSリソースがリソースグループで管理されている場合、特定のタグを持つAWSリソースを取得する。

$ aws resourcegroupstaggingapi get-resources \
    --tag-filters Key=<タグ名>,Values=<タグ値>

AWSリソースの種類 (ec2、alb、など) を指定して、特定のAWSリソースのみを取得することもできる。

$ aws resourcegroupstaggingapi get-resources \
    --resource-type-filters <AWSリソースの種類> \
    --tag-filters Key=<タグ名>,Values=<タグ値>


S3

▼ ls

*例*

指定したバケット内のファイル名を取得する。

$ aws s3 ls s3://<バケット名>

*例*

指定したバケット内のファイルサイズを合計する。

$ aws s3 ls s3://<バケット名> \
    --summarize \
    --recursive \
    --human-readable

▼ sync

指定したバケット内のファイルを他のバケットにコピーする。

$ aws s3 sync s3://<コピー元S3バケット名>/<ディレクトリ名> s3://<コピー先S3バケット名>/<ディレクトリ名> \
    --acl bucket-owner-full-control

コピーされる側のバケットのバケットポリシーでアクセスを許可すれば、異なるアカウント間でもコピーできる。

{
  "Version": "2012-10-17",
  "Statement":
    [
      {
        "Effect": "Allow",
        "Principal": {"AWS": "<IAMユーザーのARN>"},
        "Action": "s3:PutObject",
        "Resource": "arn:aws:s3:::foo-bucket/*",
        "Condition": {
            # 完全一致
            "StringEquals": {"s3:x-amz-acl": "bucket-owner-full-control"},
          },
      },
      {
        "Effect": "Allow",
        "Principal": {"AWS": "<IAMユーザーのARN>"},
        "Action": "s3:ListBucket",
        "Resource": "arn:aws:s3:::bar-bucket",
      },
    ],
}


SQS

▼ get-queue-url

キューのURLを取得する。

$ aws sqs get-queue-url --queue-name <キュー名>

▼ receive-message

キューに受信リクエストを送信し、メッセージを受信する。

$ SQS_QUEUE_URL=$(aws sqs get-queue-url --queue-name <キュー名>)

$ aws sqs receive-message --queue-url ${SQS_QUEUE_URL}

キューに受信リクエストを送信し、メッセージを受信する。

また、メッセージの内容をファイルに書き出す。

$ SQS_QUEUE_URL=$(aws sqs get-queue-url --queue-name <キュー名>)

$ aws sqs receive-message --queue-url ${SQS_QUEUE_URL} > receiveOutput.json
{
  "Messages":
    [
      {
        "Body": "<メッセージの内容>",
        "ReceiptHandle": "AQEBUo4y+XVuRSe4jMv0QM6Ob1viUnPbZ64WI01+Kmj6erhv192m80m+wgyob+zBgL4OMT+bps4KR/q5WK+W3tnno6cCFuwKGRM4OQGM9omMkK1F+ZwBC49hbl7UlzqAqcSrHfxyDo5x+xEyrEyL+sFK2MxNV6d0mF+7WxXTboyAu7JxIiKLG6cUlkhWfk3W4/Kghagy5erwRhwTaKtmF+7hw3Y99b55JLFTrZjW+/Jrq9awLCedce0kBQ3d2+7pnlpEcoY42+7T1dRI2s7um+nj5TIUpx2oSd9BWBHCjd8UQjmyye645asrWMAl1VCvHZrHRIG/v3vgq776e1mmi9pGxN96IW1aDZCQ1CSeqTFASe4=",
        "MD5OfBody": "6699d5711c044a109a6aff9fc193aada",
        "MessageId": "*****",
      },
    ],
}


Secret Manager

▼ get-secret-value

特定のSecretに格納されている文字列を取得する。

注意点として、出力した文字列はダブルクオーテーションで囲われている。

$ aws secretsmanager get-secret-value \
    --secret-id=<シークレット名> \
    --query=SecretString

# ダブルクオーテーションで囲われている
"..."

もしSecret ManagerにJSONファイルを登録している場合、これを取得するとダブルクオーテーションで囲われてしまっている。

そのため、--outputオプションでtext使用してダブルクオーテーションを削除する必要がある。

$ aws secretsmanager get-secret-value \
    --secret-id=<シークレット名> \
    --query=SecretString \
    --output=text

# ダブルクオーテーションを除去
{...}


STS

▼ decode-authorization-message

STSでエンコードされたエラーメッセージをでコードする。

$ aws sts decode-authorization-message --encoded-message zAc3k...

{
    "DecodedMessage": "{...}"
}

▼ get-caller-identity

一時的な認証情報を取得する。

~/.aws/cli/cacheディレクトリ配下に認証情報のキャッシュが作成される。

$ aws sts get-caller-identity --profile foo


Systems Manager (新SSM)

▼ create-activation

サーバー (例:オンプレミスサーバー、エッジデバイス、仮想マシン、など) をSystems Managerで管理するために、IDとコードを発行する。

$ aws ssm create-activation \
    --default-instance-name foo-vm \
    --iam-role foo-vm-role \
    --region ap-northeast-1 \
    --registration-limit 2

発行したIDとコードは、amazon-ssm-agentコマンドの実行時に必要になる。

$ amazon-ssm-agent \
    -register \
    -id "<ID>" \
    -code "<コード>" \
    -region "ap-northeast-1"

▼ get-parameters-by-path

特定のパスで始まる全ての変数をパラメーターストアから取得する。

# パスのないパラメーターの場合
$ aws ssm get-parameters-by-path --path "/"

{
    "Parameters": [
        {
            "Name": "FOO",

            ...
        },
        {
            "Name": "BAR",

            ...
        },
   ]
 }
# 『/FOO』で始まるパラメーターの場合
$ aws ssm get-parameters-by-path --path "/FOO"

{
    "Parameters": [
        {
            "Name": "/FOO",

            ...
        },
        {
            "Name": "/FOO/BAR",

            ...
        },
   ]
 }


Security Group

▼ authorize-security-group-ingress

指定したセキュリティグループで、インバウンドルールをまとめて作成する。

$ aws ec2 authorize-security-group-ingress \
    --group-id sg-***** \
    --security-group-rule-ids sgr-***** sgr-***** sgr-***** sgr-***** \
    --region ap-northeast-1

▼ revoke-security-group-ingress

指定したセキュリティグループで、インバウンドルールをまとめて削除する。

$ aws ec2 revoke-security-group-ingress \
    --group-id sg-***** \
    --security-group-rule-ids sgr-***** sgr-***** sgr-***** sgr-***** \
    --region ap-northeast-1


04. 認証/認可の手法

SSO

▼ saml2aws

AWSにSSOでログインする。

認証フェーズを外部 (Auth0、GitHub、Keycloak、AWS Cognito、Google Cloud Auth、など) に委譲し、AWSでは認可フェーズのみを実施する。

追加でMFAを採用している場合は、ワンタイムコードの入力が要求される。

*実行例*

ここでは、IPプロバイダーにKeycloakを使用している。

$ saml2aws login

Using IdP Account default to access Keycloak https://external.example/api
To use saved password just hit enter.
Username: hiroki.hasegawa
Password: *****

Authenticating as hiroki.hasegawa ...
? Security Token [000000] <MFAワンタイムコード>

Selected role: arn:aws:iam::<AWSアカウントID>:role/foo-role
Requesting AWS credentials using SAML assertion
Saving credentials
Logged in as: arn:aws:sts::<AWSアカウントID>:assumed-role/foo-role/hiroki.hasegawa

Your new access key pair has been stored in the AWS configuration.
Note that it will expire at 2022-01-01 12:00:00 +0900 JST


リクエスト制限

▼ 送信元IPに基づく制限

特定の送信元IPアドレスを制限するポリシーをIAMユーザーに紐付けることにより、そのIAMユーザーがAWS CLIの実行する時に、社外から実行できないように制限をかけられる。

*実装例*

{
  "Version": "2012-10-17",
  "Statement":
    {
      "Effect": "Deny",
      "Action": "*",
      "Resource": "*",
      "Condition": {"NotIpAddress": {"aws:SourceIp": ["*.*.*.*/32"]}},
    },
}

ポリシーのDenyステートメントによってアクセスが拒否された場合、エラーメッセージの最後に『with an explicit deny』という文言がつく。

Error: An error occurred (AccessDeniedException) when calling the <アクション名> operation: <IAMユーザー名> is not authorized to perform: <アクション名> on resource: <リソースARN> with an explicit deny