【AWS】手を動かしながら学ぶAWS AWS CLI

## はじめに

この記事では 手を動かしながらAWSが提供する管理インターフェイス、AWS CLIを学習していく記事です。主な内容としては実践したときのメモを中心に書きます。
（忘れやすいことなど）誤りなどがあれば書き直していく予定です。

## AWSですか？それ、CLIで操作できますよ

簡単に説明するとAWSをターミナルから操作できるツールです。
AWSの公式サイトには下記のように表現されています。

> AWS コマンドラインインターフェイス (AWS CLI) は、AWS のサービスを管理するための統合ツールです。ダウンロードおよび設定用の単一のツールのみを使用して、コマンドラインから AWS の複数のサービスを制御し、スクリプトを使用してこれらを自動化することができます。

[参考](https://aws.amazon.com/jp/cli/)

コマンドラインからAWSを操作するとはどういうことなのでしょうか。

## インストール方法

実際にインストールして操作してみましょう。

インストール方法：[AWS CLI の最新バージョンを使用してインストールまたは更新を行う](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/getting-started-install.html)

AWS CLIにはV1とV2がありますが、V2でインストールします。

実行環境は下記のとおりです。

- MacBook
    - Apple M1
    - 16 GB
    - Sonoma 14.0

## 基本

基本的にAWSから始まります。まずはバージョン確認します。

```bash
aws --version
```

実行結果

```text
aws-cli/2.12.3 Python/3.11.4 Darwin/23.0.0 source/arm64 prompt/off
```

ヘルプを出す場合は下記のコマンドを実行します。

```bash
aws help
```

AWS CLIは特定のAWS環境にアクセスしてリソースを操作する関係上、認証を実行する必要があります。

## AWS CLIを認証

方法は主に2つあります。

- IAMによって発行するアクセスキー
- `aws sso login`による認証

どちらにしてもIAMプロファイルを作成するので環境に合わせた認証ができます。
今回は`aws sso login`による認証でAWSにアクセスします。

```bash
aws sso login --profile {IAMプロファイル名}
```

なお、IAMプロファイル名は下記のコマンドで確認できます。

```bash
cat ./.aws/config
```

もしくは `./.aws/`にある`credentials`に直接書き込むことで対応できます。

```bash
cat ./.aws/credentials
```

## いくつか例を見ていこう

### アカウントIDを取り出す

AWS CLIではAWSのアカウントIDを取り出せます。

```bash
ACCOUNT_ID=`aws sts get-caller-identity --profile {プロファイル名} --query 'Account' --output text` && echo $ACCOUNT_ID
```

### EC2の一覧を取り出す

EC2の一覧を取り出す時は`describe-instances`を利用します。

```bash
aws ec2 describe-instances --profile {プロファイル名}
```

### VPCの一覧を取り出す

VPCの一覧を取り出す時は`describe-vpcs`を利用します。

```bash
aws ec2 describe-vpcs --profile {プロファイル名}
```

### VPCのプレフィックスリストを表示する

```bash
aws ec2 describe-prefix-lists --profile {プロファイル名}
```

### AWS CloudFormationでテンプレートをデプロイする

下記の例はAWS CloudFormationでテンプレートをデプロイする例です。

```bash
aws cloudformation deploy --stack-name codebuild-iam-role --template-file ./codebuild-role.yml --tags Name=cicdhandson --capabilities CAPABILITY_NAMED_IAM --profile {プロファイル名}
```

`codebuild-role.yml`は下記のコードです。

```yaml:codebuild-role.yml
AWSTemplateFormatVersion: 2010-09-09
Description: "CodeBuild IAM Role"
Parameters:
  PjName:
    Type: String
    Default: cicdhandson

Resources:
  CiCdHandsonCodeBuildRole:
    Type: "AWS::IAM::Role"
    Properties:
      RoleName: CiCdHandsonCodeBuildRole
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: "codebuild.amazonaws.com"
            Action: "sts:AssumeRole"
      ManagedPolicyArns:
        - !Ref CiCdHandsonCodeBuildPolicy
      Tags:
        - Key: Name
          Value: !Sub "${PjName}"
  CiCdHandsonCodeBuildPolicy:
    Type: "AWS::IAM::ManagedPolicy"
    Properties:
      ManagedPolicyName: codebuild-role
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Action:
              - "ecr:GetDownloadUrlForLayer"
              - "ecr:BatchGetImage"
              - "ecr:BatchCheckLayerAvailability"
            Resource:
              - !ImportValue CICDHandsonECRImageArn
          - Effect: Allow
            Action:
              - "ecr:CompleteLayerUpload"
              - "ecr:InitiateLayerUpload"
              - "ecr:UploadLayerPart"
              - "ecr:PutImage"
            Resource:
              - !ImportValue CICDHandsonECRImageArn
          - Effect: Allow
            Action:
              - "ecr:GetAuthorizationToken"
            Resource:
              - "*"
          - Effect: Allow
            Action:
              - "logs:CreateLogStream"
              - "logs:PutLogEvents"
              - "logs:CreateLogGroup"
            Resource: "*"
          - Effect: Allow
            Action:
              - "s3:PutObject"
              - "s3:GetObject"
              - "s3:GetObjectVersion"
              - "s3:GetBucketAcl"
              - "s3:GetBucketLocation"
            Resource:
              - !Join
                - ""
                - - !ImportValue CICDHandsonBucketArn
                  - "/*"
              - !ImportValue CICDHandsonBucketArn
Outputs:
  CiCdHandsonCodeBuildRoleName:
    Value: !Ref CiCdHandsonCodeBuildRole
    Export:
      Name: CodeBuildRoleName
```

## いくつかコマンドを見ていきたけど。。。

読み方や書き方のコツを知りたい！！

### コマンドの読み方

`aws help`を実行すると複数のサブコマンドが表示されて圧倒されますが、実は有効なコマンド一つ一つには読み方があります。

下記の例はlambdaの関数リストを出力するコマンドです。

```bash
aws lambda list-functions --profile {IAMプロファイル名}
```

`aws`の次にサービス名、その次に動作名という形でコマンドが続きます。
なお、AWS SDK for Pythonと似ているところが多いです。たとえば、上記の「Lambdaの関数一覧を表示するサブコマンド」はboto3のclientメソッドとして定義されています。

[Lambda list_functions](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/lambda/client/list_functions.html)

AWS CLIにはサービスそれぞれに対してサブコマンドが用意されています。
サービスの数だけサブコマンドがそれぞれ存在します。ではどのようにしてAWS CLIのサブコマンドを覚えていけば良いのでしょうか。

実はコツがあります。一緒に見ていきましょう。

### ココがポイント！英語で読んでいく

各サービスのサブコマンドには命名ルールがあります。それさえ覚えることができれば、あとは慣れの問題です。

具体的にはどんなメソッドも以下のような単語から始まり、だいたいは単語のイメージ通りの動作をします。

- create
    - 作成
- delete
    - 削除
- flush
    - 消去
- update
    - 更新
- describe
    - 表示
- get
    - 抽出
- attach
    - 取り付け
- associate
    - 関連付け

他にもさまざまですが、どのようなメソッドか想像がつかない場合は英単語から想像するとよいでしょう。

## ページングとNextToken

さまざまなコマンドを持つAWS CLIですが、実は万能ではなく一度のリクエストですべてのデータを取れないケースがあります。たとえば、リソースが多い場合においては分割して取得する必要があります。

分割して取得する場合は取得件数の最大値を超えた時にNextTokenが発行されますのでNextTokenを使って再度、リクエストを送信します。

塊毎にちょっとずつデータを取っていく、この操作をページングと言います。150件あって100件までが一度に取得できる上限であれば、2回のリクエストが必要です。

### オプションの読み方

AWS CLIにはいくつかオプションがあるので説明します。

`--stack-name`：CloudFormation独自のオプションです。スタック名を指定します。

`--tags Name=cicdhandson`：リソースのタグを指定します。ここではNameを`cicdhandson`を指定しています。

`--capabilities CAPABILITY_NAMED_IAM`：IAMリソースを作成する時に必要なオプションです。

`--query `:[JMESPath 構文](https://jmespath.org/)で実行結果をフィルタリングします。

[AWS CLI の出力をフィルタリングする](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-usage-filter.html)

## 利用時の注意事項

### AWS上でAWS CLIを使う場合

IAMロールを利用しましょう。アクセスキーでも操作できますが、AWS上でAWS CLIを利用するときはロールを使って認証することがベストプラクティスとなっています。

## まとめ

AWS CLIはAWSのサービスをCLIで操作できるツールです。使い方次第でマネジメントコンソールではできない操作ができます。

認証についてはIAMアクセスキーを利用する方法か`AWS IAM Identity Center`を使ったシングルサインオンの2つがあります。

また、AWS SDK for Python(boto3)のメソッド名がAWS CLIのサブコマンドに対応しているのでboto3でやりたいことを「まずはAWS CLIで試してみる」ということができます。

有効活用してAWS上の開発を効率よくおこないましょう。

## おわり