[アップデート]Route TableとNetwork ACL作成の冪等性がサポートされました

2024.01.29

こんにちは、岩城です。

先週、タイトルのアップデートがありましたので紹介します。

忙しい人向けまとめ

  • create-route-tablecreate-network-aclAPIにclient-tokenパラメータが追加
  • クライアントトークンを利用する冪等性がサポート
  • これまで実行した分だけリソースが作成され、当然リソースIDなどの成功が変わり全く別の実行結果が返ってきてた
  • クライアントトークンおよび設定値が同じリクエストであれば、何度実行しても同じ実行結果が返ってくる
  • クライアントトークンが同一、設定値が違う場合IdempotentParameterMismatchエラーにより実行できない
  • client-tokenには最大64個・大小区別されるASCII文字列を指定可能

やってみた

AWS CLIv2を利用して試します。古いバージョンではclient-tokenパラメータがサポートされていないので、最新バージョンを利用します。

$ aws --version
aws-cli/2.15.15 Python/3.11.6 Linux/6.1.66-91.160.amzn2023.x86_64 exec-env/CloudShell exe/x86_64.amzn.2023 prompt/off

まずはclient-tokenパラメータを使わずにcreate-route-tablecreate-network-aclを複数回実行してみます。

#ルートテーブル作成
aws ec2 create-route-table --vpc-id vpc-0d92a005e4a04c6a1 --tag-specifications ResourceType=route-table,Tags=[{'Key=Name,Value=devio-route-table'}]

#ネットワーク ACL作成
aws ec2 create-network-acl --vpc-id vpc-0d92a005e4a04c6a1 --tag-specifications ResourceType=network-acl,Tags=[{'Key=Name,Value=devio-network-acl'}]

実行した分だけ以下のように各リソースが作成されてしまいます。

#ルートテーブル
$ aws ec2 describe-route-tables --filters 'Name=tag:Name,Values=devio-route-table' --query 'RouteTables[*].{ID:RouteTableId,Name:Tags[?Value==`devio-route-table`].Value|[0]}' --output table
------------------------------------------------
|              DescribeRouteTables             |
+------------------------+---------------------+
|           ID           |        Name         |
+------------------------+---------------------+
|  rtb-061ead30052335fd1 |  devio-route-table  |
|  rtb-0890dacb4995191b1 |  devio-route-table  |
|  rtb-09be6997dc2f7a55b |  devio-route-table  |
+------------------------+---------------------+

#ネットワークACL
$ aws ec2 describe-network-acls --filters 'Name=tag:Name,Values=devio-network-acl' --query 'NetworkAcls[*].{ID:NetworkAclId,Name:Tags[?Value==`devio-network-acl`].Value|[0]}' --output table
------------------------------------------------
|              DescribeNetworkAcls             |
+------------------------+---------------------+
|           ID           |        Name         |
+------------------------+---------------------+
|  acl-0e8d29e9be9dd6712 |  devio-network-acl  |
|  acl-019464c82365d3798 |  devio-network-acl  |
|  acl-0872a3bc9078bd056 |  devio-network-acl  |
+------------------------+---------------------+

意図せず実行してしまった場合、不要なリソースは削除しないといけないので手間ですよね。

そこでclient-tokenを利用します。同じクライアントトークン、同じ設定値であれば何度実行しても同じ実行結果を返します。

何度実行しても同じ結果となるので冪等性があります。何度実行してもエラーにはならないが、異なるリソースがその分作成されるのは冪等性があるとは言えません。

リソース名の末尾に2client-tokenパラメータを付与して複数回実行してみます。

#ルートテーブル
$ aws ec2 create-route-table --vpc-id vpc-0d92a005e4a04c6a1 --tag-specifications ResourceType=route-table,Tags=[{'Key=Name,Value=devio-route-table2'}] --client-token 550e8400-e29b-41d4-a716-446655440000
{
    "RouteTable": {
        "Associations": [],
        "PropagatingVgws": [],
        "RouteTableId": "rtb-08d275e61da9646ab",
        "Routes": [
            {
                "DestinationCidrBlock": "10.0.0.0/16",
                "GatewayId": "local",
                "Origin": "CreateRouteTable",
                "State": "active"
            }
        ],
        "Tags": [
            {
                "Key": "Name",
                "Value": "devio-route-table2"
            }
        ],
        "VpcId": "vpc-0d92a005e4a04c6a1",
        "OwnerId": "992031286038"
    },
    "ClientToken": "550e8400-e29b-41d4-a716-446655440000"
}

#ネットワークACL
$ aws ec2 create-network-acl --vpc-id vpc-0d92a005e4a04c6a1 --tag-specifications ResourceType=network-acl,Tags=[{'Key=Name,Value=devio-network-acl2'}] --client-token 550e8400-e29b-41d4-a716-446655440000
{
    "NetworkAcl": {
        "Associations": [],
        "Entries": [
            {
                "CidrBlock": "0.0.0.0/0",
                "Egress": true,
                "IcmpTypeCode": {},
                "PortRange": {},
                "Protocol": "-1",
                "RuleAction": "deny",
                "RuleNumber": 32767
            },
            {
                "CidrBlock": "0.0.0.0/0",
                "Egress": false,
                "IcmpTypeCode": {},
                "PortRange": {},
                "Protocol": "-1",
                "RuleAction": "deny",
                "RuleNumber": 32767
            }
        ],
        "IsDefault": false,
        "NetworkAclId": "acl-069a45219f569818e",
        "Tags": [
            {
                "Key": "Name",
                "Value": "devio-network-acl2"
            }
        ],
        "VpcId": "vpc-0d92a005e4a04c6a1",
        "OwnerId": "992031286038"
    },
    "ClientToken": "550e8400-e29b-41d4-a716-446655440000"
}

何度実行しても上のような同じ実行結果が返ってきます。当然作成されるリソースは一つだけです。

#ルートテーブル
aws ec2 describe-route-tables --filters 'Name=tag:Name,Values=devio-route-table2' --query 'RouteTables[*].{ID:RouteTableId,Name:Tags[?Value==`devio-route-table2`].Value|[0]}' --output table
-------------------------------------------------
|              DescribeRouteTables              |
+------------------------+----------------------+
|           ID           |        Name          |
+------------------------+----------------------+
|  rtb-08d275e61da9646ab |  devio-route-table2  |
+------------------------+----------------------+

#ネットワークACL
$ aws ec2 describe-network-acls --filters 'Name=tag:Name,Values=devio-network-acl2' --query 'NetworkAcls[*].{ID:NetworkAclId,Name:Tags[?Value==`devio-network-acl2`].Value|[0]}' --output table
-------------------------------------------------
|              DescribeNetworkAcls              |
+------------------------+----------------------+
|           ID           |        Name          |
+------------------------+----------------------+
|  acl-069a45219f569818e |  devio-network-acl2  |
+------------------------+----------------------+

同じクライアントトークンで別名リソースを作成するとIdempotentParameterMismatchが出力し作成できませんでした。

$ aws ec2 create-network-acl --vpc-id vpc-0d92a005e4a04c6a1 --tag-specifications ResourceType=network-acl,Tags=[{'Key=Name,Value=devio-network-acl3'}] --client-token 550e8400-e29b-41d4-a716-446655440000

An error occurred (IdempotentParameterMismatch) when calling the CreateNetworkAcl operation: Wrong arguments for request with token 550e8400-e29b-41d4-a716-446655440000

また、クライアントトークンを使用して作成したリソースを削除した直後に同じクライアントトークンで作成しようとしても、削除されたリソースに関連しているためエラーとなりました。

少し時間を空ければ作成できるようになることを確認しています。

$ aws ec2 create-route-table --vpc-id vpc-0d92a005e4a04c6a1 --tag-specifications ResourceType=route-table,Tags=[{'Key=Name,Value=devio-route-table'}] --client-token 550e8400-e29b-41d4-a716-446655440000

An error occurred (IdempotentParameterMismatch) when calling the CreateRouteTable operation: An error occurred (IdempotentParameterMismatch) when calling this operation: The client token and arguments used in this request were used in a prior request that was associated with a resource which is now deleted.

おわりに

本エントリを執筆するうえで一番苦労したのは、CLIの結果を表形式に出力するところでした。

毎度フィルターパターン、クエリの書き方を忘れてしまうのでなんとかしたいです。

本エントリがどなたかのお役に立てれば幸いです。