🌐

AWSは全てWeb APIである。それが分かるとAWSもIAMも分かる

に公開

「AWSは全てWeb APIである」と気づいたとき、自分のAWSの理解が一気に進んだ記憶があります。これからAWSを学ぶ初学者の方々のために、そこらへんを言語化していこうと思います。

イメージ重視のため正確さを欠く可能性がありますが、その点はご容赦ください。致命的な間違いがあった場合は、コメントで 優しく 教えてください。いいですか、 優しく ですよ。

まずは、AWSがWeb APIであることを見てみよう

例えば、VPCを作ることを考えてみましょう。

  • AWSマネジメントコンソール(以下「マネコン」)でVPCのページを開いて、CIDRや名前を指定して[VPCを作成]ボタンをクリックする
  • AWS CLIで aws ec2 create-vpc --cidr-block ... を実行する

などの方法がありますね。

この背後で何が起こっているのでしょうか?AWS CLIで--debugオプションを付けると、それを見ることができます。

次のコマンドを実行すると、VPCを作成する際の詳細なログが出力されます。

VPC作成コマンド
aws ec2 create-vpc \
--cidr-block "10.10.0.0/16" \
--tag-specifications "ResourceType=vpc,Tags=[{Key=Name,Value=sample-vpc}]" \
--debug

ログを追っていくと、HTTPリクエストをhttps://ec2.ap-northeast-1.amazonaws.com/にPOSTリクエストを送信していることが分かります。

リクエストの送信
2025-10-xx xx:35:14,060 - MainThread - botocore.auth - DEBUG - CanonicalRequest:
POST
/

content-type:application/x-www-form-urlencoded; charset=utf-8
host:ec2.ap-northeast-1.amazonaws.com
...

もう少し追うと、レスポンスが返ってきている様子が分かります。(見やすいよう改行を入れています)

レスポンスヘッダーがあり、レスポンスボディはXMLであることが分かりますね。

レスポンスの受信
2025-10-xx xx:35:14,814 - MainThread - botocore.parsers - DEBUG - Response headers: {'x-amzn-RequestId': 'xxxxxxxx', 'Cache-Control': 'no-cache, no-store', 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains', 'Content-Type': 'text/xml;charset=UTF-8', 'Content-Length': '764', ...}
2025-10-xx xx:35:14,814 - MainThread - botocore.parsers - DEBUG - Response body:
b'<?xml version="1.0" encoding="UTF-8"?>\n
<CreateVpcResponse xmlns="http://ec2.amazonaws.com/doc/2016-11-15/">
    ...
    <vpc>
        <vpcId>vpc-xxxxxxxxxx</vpcId>
        ...
        <cidrBlock>10.10.0.0/16</cidrBlock>
        ...
        <tagSet>
            <item>
                <key>Name</key>
                <value>sample-vpc</value>
            </item>
        </tagSet>
        ...
    </vpc>
</CreateVpcResponse>'

つまり aws ec2 create-vpc コマンドを実行すると、AWSのサーバーにHTTPリクエストを送信し、それを受信したAWSのサーバーがVPCを作成し、レスポンスを返すということです。

マネコンでも同じです。マネコンで[VPCを作成]ボタンをクリックすると、AWSのサーバーにHTTPリクエストを送信し、それを受信したAWSのサーバーがVPCを作成し、レスポンスを返します。

ここまでで、AWSで何かを作成するということは、AWSのWeb APIにリクエストを送信することであると分かりました。

AWSのWeb API仕様

さて、ではもう少し詳しく見てみましょう。先ほど使ったVPC作成のWeb APIは、どんな仕様になっているのでしょうか?

実はAWSのWeb APIは全て仕様が公開されています。EC2のドキュメント一覧を見てみると、[API Reference]というものがあります(歴史的背景から、VPCはEC2に含まれています)。これがWeb APIの仕様書です。

(我々が普段よく読むのは[User Guide]ですね)

これを開き、画面左側の[Actions]からCreateVpcを探します。これが、先ほどCLIから利用したVPCを作成するWeb APIです。

URLは👇️

https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/APIReference/API_CreateVpc.html

EC2にはたくさんのアクション(=Web API)が用意されています。主要なものを紹介しますので、[Actions]の中から探してみてください。

  • CreateVpc: VPCの作成
  • DeleteVpc: VPCの削除
  • DescribeVpcs: VPCを一覧
  • CreateSecurityGroup: セキュリティグループの作成
  • DeleteSecurityGroup: セキュリティグループの削除
  • DescribeSecurityGroups: セキュリティグループを一覧
  • StartInstances: EC2インスタンスの起動
  • TerminateInstances: EC2インスタンスの削除
  • DescribeInstances: EC2インスタンスを一覧

リクエスト・レスポンスのサンプルも紹介されています。

CLIとSDKの正体

AWSがWeb APIだと言うことは、curlコマンドでもVPCが作成できたりします。やろうと思えばできます。しかし、実際には認証のためのリクエストヘッダーを作成したりする必要があります。それに、毎回curlコマンドを使うのはなかなか大変です。

そこで、このWeb APIをラップして使いやすくしたツールがあります。それがCLIとSDKです。

先ほど見た通り、CLIを実行するとAWSのWeb APIへのリクエストが送信されます。加えて、XML形式のレスポンスを、見やすいようにJSONなどに変換してくれます。認証のためのリクエストヘッダーも作成してくれます(デバッグログを詳細に見ると分かります)。

SDKも同様です。AWS SDKはJava・Pythonなど様々な言語のものが提供されています。ちなみにAWS CLIは、Python版のAWS SDKであるbotoというライブラリを内部で使っています。

例えばAWS SDK for Java v2では、以下のコードでVPCが作成できます。内部では先ほどの CreateVpc のWeb APIにリクエストを送信します。メソッド名などは、CLIとほとんど一緒ですね(キャメルケースとハイフン区切りの違いはありますが)。

SDKでVPC作成
Ec2Client ec2Client = Ec2Client.create();
CreateVpcResponse createVpcResponse = ec2Client.createVpc(builder -> builder
        .cidrBlock("10.10.0.0/16")
        .tagSpecifications(s -> s
                .resourceType(ResourceType.VPC)
                .tags(t -> t
                        .key("Name")
                        .value("sample-vpc")
                )
        )
);
CLIでVPC作成(再掲)
aws ec2 create-vpc \
--cidr-block "10.10.0.0/16" \
--tag-specifications "ResourceType=vpc,Tags=[{Key=Name,Value=sample-vpc}]"

繰り返しになりますが、CLIとSDKは、AWSのWeb APIのラッパーであることを覚えておいてください。

IAMポリシー

さて、ここからはIAMの説明になります。苦手な方も多いとは思いますが、「AWSはWeb APIである」の原則を理解すると、IAMの理解も進みます。

先ほど説明した通り、AWSのWeb APIには多くの「アクション」があります。

EC2(VPC含む)だとこんなのがありましたね。

  • CreateVpc: VPCの作成
  • DeleteVpc: VPCの削除
  • DescribeVpcs: VPCを一覧
  • ...

他にも、よく使うであろうS3にはこんなアクションがあります。

  • CreateBucket: バケットの作成
  • DeleteBucket: バケットの削除
  • PutObject: バケットにオブジェクトをアップロードする
  • GetObject: バケットからオブジェクトをダウンロードする
  • DeleteObject: バケットからオブジェクトを削除する

https://docs.aws.amazon.com/AmazonS3/latest/API/Welcome.html

EC2・ECS・Lambdaなど動くアプリケーションや我々ユーザーが、これらのアクションそれぞれについて許可/拒否されるかどうかの設定がIAMポリシーです。

例えば次のように記述すると、S3バケットsample-bucketへのオブジェクトのアップロード・ダウンロードが可能になります。

IAMポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "s3:PutObject",
                "s3:GetObject"
            ],
            "Effect": "Allow",
            "Resource": "arn:aws:s3::アカウントID:sample-bucket/*"
        }
    ]
}

IAMポリシーには、我々が作成するものと、AWSが最初から用意してくれているものがあります。例えば、Lambda関数によく使うAWSLambdaBasicExecutionRole(IAMポリシーなのにRoleという名前なのがややこしい)は、AWSが用意してくれているものです。詳細を見てみると、IAMポリシーのJSONが書かれていることが分かります(CloudWatch Logsでのロググループの作成・ログストリームの作成・ログストリームへのログの出力、というアクションが許可されています)。

IAMロール

作成したIAMポリシーは、IAMロールに紐づけます(1つのIAMロールには複数のIAMポリシーを紐づけ可能)。そしてIAMロールを、EC2インスタンス・ECSタスク・Lambda関数・IAMユーザーなどと紐づけます。

IAMロールを作成する際は、紐づけるIAMポリシーの指定に加えて、信頼関係を設定する必要があります。信頼関係とは、このIAMロールを誰に紐づけられるのか、という設定です。「誰」というのは、

  • EC2インスタンス・ECSタスク・Lambda関数などのAWSサービス
  • IAMユーザー

などを指します。

例えば、IAMロールをLambda関数に紐づけたい場合は、信頼関係を次のように記述します。"Service": "lambda.amazonaws.com"の部分がポイントです。

信頼関係
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "lambda.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

まとめ

AWSは全てWeb APIであり、IAMポリシーは1つ1つのWeb APIに対する許可/拒否を設定するものです。

これが腑に落ちたとき、AWSの理解が一気に進みます。

Discussion