[AWS]指定するタグの有無によってEC2 起動を制限したい

EC2 起動時に、指定するタグの有無によって起動を制限するためのIAMポリシーについての記事です。
2021.06.19

困っていた内容

EC2 起動時に、指定するタグの要件に従って起動を制限したいのですが、どのように IAMポリシーを指定すればよいでしょうか。

具体的な要件は以下です。

起動許可

1 期待するタグがある (Name:instance1, Environment:ABC

2 上記に加え、任意のタグがある(Name:instance1, Environment:ABC, myTag:hoge

起動制限

3 タグなし

4 期待するタグがすべてない(myTag:hoge

5 期待するタグが一部無い(Name:instance1

6 期待するタグの値が未入力(Name:, Environment:ABC

AWS ナレッジセンターを確認したのですがうまくいきませんでした。

IAM ポリシータグを使用して EC2 インスタンスまたは EBS ボリュームの作成方法を制限するにはどうすればよいですか?

どう対応すればいいの?

本要件は、AWSのナレッジセンターに存在しない要件のため、Condition を新たに検討する必要があります。

まず、要件をまとめると以下の2つになります。

  • 期待するタグが存在するかをチェック
    • 1 期待するタグがある (Name:instance1, Environment:ABC
    • 2 上記に加え、任意のタグがある(Name:instance1, Environment:ABC, myTag:hoge
    • 3 タグなし
    • 4 期待するタグがすべてない(myTag:hoge
    • 5 期待するタグが一部無い(Name:instance1
  • 期待するタグの文字列が空の場合かをチェック
    • 6 期待するタグの値が未入力(Name:, Environment:ABC

期待するタグが存在するかを確認するには、NULLを利用します。NULLでは、APIリクエス内にキーが存在するかをチェックします。今回のケースでは、期待するタグが指定されているかをチェックします。

            "Condition": {
                "Null": {
                    "aws:RequestTag/Name": false,
                    "aws:RequestTag/Environment": false
                }
            }

また、期待するタグの文字列が空の場合かをチェックは、 StringNotEquals を使用します。実際指定されたタグの値を Condition で確認します。

            "Condition": {
                "StringNotEquals": {
                    "aws:RequestTag/Name": "",
                    "aws:RequestTag/Environment": ""
                }
            }

今回の要件を合わせた Condition です。

            "Condition": {
                "StringNotEquals": {
                    "aws:RequestTag/Name": "",
                    "aws:RequestTag/Environment": ""
                },
                "Null": {
                    "aws:RequestTag/Name": false,
                    "aws:RequestTag/Environment": false
                }
            }

ポリシー全体です。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "ec2:CreateNetworkInterface",
                "ec2:RunInstances",
                "ec2:CreateVolume"
            ],
            "Resource": [
                "arn:aws:ec2:*:*:instance/*",
                "arn:aws:ec2:*:*:volume/*",
                "arn:aws:ec2:*:*:network-interface/*"
            ],
            "Condition": {
                "StringNotEquals": {
                    "aws:RequestTag/Name": "",
                    "aws:RequestTag/Environment": ""
                },
                "Null": {
                    "aws:RequestTag/Name": false,
                    "aws:RequestTag/Environment": false
                }
            }
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": "ec2:CreateTags",
            "Resource": [
                "arn:aws:ec2:*:*:instance/*",
                "arn:aws:ec2:*:*:volume/*",
                "arn:aws:ec2:*:*:network-interface/*"
            ],
            "Condition": {
                "StringEquals": {
                    "ec2:CreateAction": "RunInstances"
                }
            }
        },
        {
            "Sid": "VisualEditor2",
            "Effect": "Allow",
            "Action": "ec2:Describe*",
            "Resource": "*"
        },
        {
            "Sid": "VisualEditor3",
            "Effect": "Allow",
            "Action": "ec2:RunInstances",
            "Resource": [
                "arn:aws:ec2:*:*:subnet/*",
                "arn:aws:ec2:*:*:key-pair/*",
                "arn:aws:ec2:*::snapshot/*",
                "arn:aws:ec2:*:*:security-group/*",
                "arn:aws:ec2:*:*:network-interface/*",
                "arn:aws:ec2:*::image/*"
            ]
        }
    ]
}

参考資料

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_Null