💬

【AWS】コスト管理奮闘!! リソース作成のタグ付け強制

に公開

こんにちは。EDUCOM 新卒入社3年目のとよだです。
業務でAWSアカウントの横断的なコスト最適化に取り組むことになり、弊社インフラエンジニアが利用する検証環境でのタグ付け強制をやってみたので紹介します。

課題とやりたいこと

これまで運用ルールとして、検証リソースには「Owner」タグの付与を必須としていました。 目的は、Cost Explorerで個人ごとの利用コストを可視化し、Slack通知するためです。
しかし、手動運用では「タグの付け忘れ」が頻発し、所有者不明のリソースが散見される状態に……。

解決策:タグがなければ「作らせない」!

個人に頼るのではなく、IAMポリシーによって「Ownerタグがないリソース作成」を強制的に拒否(Deny) する設定を導入しました。

  • 対象リソース
    • (※)EC2インスタンス / EBSボリューム
    • RDSインスタンス
    • Elastic Load Balancer
    • ElasticIP

※本記事の作成にあたり、こちらの記事【【AWS】IAMポリシーでEC2へタグ付けを強制する】を参考にさせていただきました!

前提知識の整理

権限の評価論理

  • AWS検証アカウントでは、各ユーザーに AdministratorAccess を付与しています。
{
  "Version" : "2012-10-17",
  "Statement" : [
    {
      "Effect" : "Allow",
      "Action" : "*",
      "Resource" : "*"
    }
  ]
}
  • IAMの基本原則: 「明示的な拒否(Deny)」は「許可(Allow)」に優先します。
    • Allow VS Deny ポリシーの優先順位について
      • DenyがAllowより優先

該当するポリシーに Deny ステートメントが含まれている場合、リクエストは明示的に拒否されます。リクエストに適用されるポリシーに Allow ステートメントと Deny ステートメントが含まれている場合は、Deny ステートメントが Allow ステートメントより優先されます。リクエストは明示的に拒否されます。

  • 今回の戦略: Administrator権限で全てを「Allow」しつつ、特定の条件(タグなし)に限って「Deny」を上書きします。

タグ制御の条件キー【aws:RequestTag/${TagKey} 】

リソース作成の「リクエスト時」に、特定のタグが含まれているかを判定するために使用します。

条件キー 説明 タイプ
aws:RequestTag/${TagKey} リクエストで許可されているタグキーと値のペアによってアクセスをフィルタリングします 文字列

https://docs.aws.amazon.com/ja_jp/service-authorization/latest/reference/list_amazonelasticblockstore.html#amazonelasticblockstore-policy-keys

EBSボリュームでの実践

まずは、EBSボリューム作成時に「Owner」タグを強制するポリシーを書いてみます。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DenyCreateVolumeWithoutOwnerTag",
            "Effect": "Deny",
            "Action": "ec2:CreateVolume",
            "Resource": "*",
            "Condition": {
                "Null": {
                    "aws:RequestTag/Owner": "true"
                }
            }
        }
    ]
}

判定の仕組み

Ownerタグの有無 "Null": true の評価 結果(Denyポリシー適用)
タグがない true(Null) 拒否される(Deny)
タグがある false 許可される可能性あり(別のポリシーで決定)

動作確認

実際に設定した状態で、マネジメントコンソールから作成を試してみました。
【Owner】タグをつけて作成


タグがない場合
「You are not authorized to perform this operation...」というエラーが発生し、作成がブロックされました。 (以下エラー内容)
:::

主要リソースを網羅した一括制限ポリシー

検証環境でよく使われるリソースをまとめた最終的なポリシーがこちらです。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DenyRunInstancesWithoutOwnerTagOnInstance",
            "Effect": "Deny",
            "Action": "ec2:RunInstances",
            "Resource": "arn:aws:ec2:*:*:instance/*",
            "Condition": {
                "Null": {
                    "aws:RequestTag/Owner": "true"
                }
            }
        },
        {
            "Sid": "DenyCreateVolumeWithoutOwnerTag",
            "Effect": "Deny",
            "Action": "ec2:CreateVolume",
            "Resource": "*",
            "Condition": {
                "Null": {
                    "aws:RequestTag/Owner": "true"
                }
            }
        },
        {
            "Sid": "DenyCreateRDSWithoutOwnerTag",
            "Effect": "Deny",
            "Action": "rds:CreateDBInstance",
            "Resource": "*",
            "Condition": {
                "Null": {
                    "aws:RequestTag/Owner": "true"
                }
            }
        },
        {
            "Sid": "DenyCreateELBWithoutOwnerTag",
            "Effect": "Deny",
            "Action": "elasticloadbalancing:CreateLoadBalancer",
            "Resource": "*",
            "Condition": {
                "Null": {
                    "aws:RequestTag/Owner": "true"
                }
            }
        },
        {
            "Sid": "DenyAllocateAddressWithoutOwnerTag",
            "Effect": "Deny",
            "Action": "ec2:AllocateAddress",
            "Resource": "*",
            "Condition": {
                "Null": {
                    "aws:RequestTag/Owner": "true"
                }
            }
        }
    ]
}
注意点:EC2インスタンス起動時

EC2作成時(ec2:RunInstances)は、インスタンス本体だけでなく、同時に作成されるボリュームにもタグを強制したい場合があります。その際は、Resource セクションで以下のように複数のARNを指定するか、ワイルドカードを検討してください。

【対応条件】対応するリソースの確認方法

確認方法

Service Authorization Reference> 条件キーテーブル を参照
条件キーの一覧にて「条件キー【aws:RequestTag/${TagKey}】」が存在すればタグの制御可能

ex)ELBにタグ付け強制ができるか

AWS Elastic Load Balancing のアクション、リソース、および条件キー

アクション 説明 アクセスレベル リソースタイプ 条件キー 依存アクション
CreateLoadBalancer ロードバランサーを作成する許可を付与 書き込み loadbalancer elasticloadbalancing:AddTags
CreateLoadBalancer ロードバランサーを作成する許可を付与 書き込み aws:RequestTag/${TagKey}
aws:TagKeys
aws:ResourceTag/${TagKey}
elasticloadbalancing:ResourceTag/${TagKey}
elasticloadbalancing:SecurityGroup
elasticloadbalancing:Subnet
elasticloadbalancing:Scheme
elasticloadbalancing:ListenerProtocol

まとめ

「ルールを守ってください」とお願いし続けるよりも、「システム的にルール外の操作をさせない」 仕組みを作るほうが、管理者・利用者双方にとってストレスが少なくなります。

コスト管理でお悩みの方は、業務上利用するサービスで適用できないか確認し、ぜひ導入してみてください!

EDUCOM Tech Blog

Discussion