LoginSignup
6
1

【AWS】ほぼ全リソースに使える「削除保護タグ」を簡単に作れるって知ってた?

Posted at

TL;DR

DeletionProtectionタグを付けたリソースが削除できなくなるサービスコントロールポリシー(SCP)を作ります。Actionに書いたリソースの操作が対象になります。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DeletionProtectionTag",
            "Effect": "Deny",
            "Action": [
                "logs:DeleteLogGroup",
                "lambda:DeleteFunction"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:ResourceTag/DeletionProtection": "true"
                }
            }
        }
    ]
}

背景

エンジニアにとって最も恐ろしいのは、本番環境のリソースをうっかり削除してしまうことでしょう。

幸い、EC2インスタンスやRDSクラスターなど一部のリソースには「削除保護(終了保護)」の機能があります。

rds.png

また、マネジメントコンソールで削除時にリソース名を入力させる画面が出る場合もあります。

s3.png

問題は、全てのリソースがそうではないということです。

例えばCloudWatchロググループやLambda関数は比較的簡単に削除できてしまいます。

ほぼ全てのリソースにはタグが付けられるので、「削除保護タグ」みたいなものがあればなぁ...

作ってみた

そこで自作してみました。

使うのは AWS Organizationsサービスコントロールポリシー(SCP) です。

SCPを使うことで、Org内のAWSアカウントに対しアクセス許可を設定することができます。ポリシーの書き方はIAM等と同じなので、学習コストも低めです。

「削除保護タグ」は次のように実装できます。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DeletionProtectionTag",
            "Effect": "Deny",
            "Action": [
                "logs:DeleteLogGroup",
                "lambda:DeleteFunction"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:ResourceTag/DeletionProtection": "true"
                }
            }
        }
    ]
}

上記はDeletionProtectionタグがついたリソースについて、記載したActionをDenyするポリシーです。記載していないActionは拒否されません。 今回は例として「CloudWatchロググループの削除」と「Lambda関数の削除」を拒否しています。

また、リソースからDeletionProtectionタグを外すことは拒否していません。今回はあくまで「うっかり削除」の防止が目的であり、本当にリソースを消したいときに面倒くさいからです。

CloudFormationテンプレート

本記事ではOrganizationやSCPの導入方法は割愛します。CloudFormationで作る場合は下記のようになります。

Resources:
  SCPDeletionProtectionTag:
    Type: AWS::Organizations::Policy
    Properties:
      Type: SERVICE_CONTROL_POLICY
      Name: DeletionProtectionTag
      TargetIds:
        - # 下記をアタッチするOrganizational Unit
      Content:
        Version: 2012-10-17
        Statement:
          - Sid: DeletionProtectionTag
            Effect: Deny
            Action:
              - logs:DeleteLogGroup
              - lambda:DeleteFunction
              # ここにActionを追加する
            Resource: '*'
            Condition:
              StringEquals:
                aws:ResourceTag/DeletionProtection: 'true'

削除保護タグの対応リソース

おおまかに、AWS services that work with IAM の「Services that work with IAM」の表でABACが✅Yesになっていれば、だいたい対応しています。ABACはattribute-based access controlの略です。

abac.png

より正確には、Actions, resources, and condition keys for AWS services の子ページを確認し、Resource typesの表にaws:ResourceTag/${TagKey}があれば対応しています。

cw.png

dynamodb.png

また、もし対応していない場合は、ポリシーを作る画面で「このサービスにこのCondition Keyは使えないよ」と警告が出ます。

policy.png

削除保護の挙動

作ったSCPの挙動を確認してみます。

AWS CLIの場合、エラーメッセージの末尾にservice control policyがあり、分かりやすかったです。

$ aws logs delete-log-group --log-group-name example-log-group

An error occurred (AccessDeniedException) when calling the DeleteLogGroup operation: User: arn:aws:iam::XXXXXXXXXXXX:user/tippy is not authorized to perform: logs:DeleteLogGroup on resource: arn:aws:logs:ap-northeast-1:XXXXXXXXXXXX:log-group:example-log-group:log-stream: with an explicit deny in a service control policy

一方マネジメントコンソールの場合、リソースにもよると思いますが、CloudWatchロググループでは特にエラーメッセージが出ませんでした。

cw_2.png

実際に使ってみて

この仕組みを実際に弊社の全アカウントに導入しました。小並感ですが、感想は次のとおりです。

良かった点

  • 導入がとても簡単
  • 複数のAWSアカウントに対して、全ユーザーに対して、一括で設定できる
  • マネジメントコンソールだけでなく、CLIやSDKによる操作にも有効
    • SSOでAdminで入ったときにも有効

だめな点

  • 一部リソースには対応していない
  • Actionを1つ1つ追加するのが大変
  • エラーメッセージが出ないことがある

制約は多いですが、ガードレールの1つとして十分使えると思います。

皆様の参考になれば幸いです。

6
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
1