![[AWS Organizations] SCP(サービスコントロールポリシー)を使ってインフラリソースを保護してみる](https://devio2023-media.developers.io/wp-content/uploads/2019/04/aws-organizations.png)
[AWS Organizations] SCP(サービスコントロールポリシー)を使ってインフラリソースを保護してみる
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
AWS Organizations 環境において、 各メンバーアカウントへ構築したネットワークやITサービスなどのインフラサービスを 保護する方法を SCP(サービスコントロールポリシー) で実現してみます。 リソースタグを活用します。
SCPは AWS Organizations の 組織単位(OU)やアカウントに指定することができるポリシーです。 OUに SCPをアタッチすることで、複数アカウントの一括アクセス制御が可能になります。
設計内容
特定タグ/値が付与されたインフラリソースの削除を禁止(Deny)する ことを目標とします。
後続の実装のために、もう少し細かい設計をしていきます。
対象の リソース(Resource)は何か
今回は Amazon EC2で定義されるリソース を対象とします。
代表的なリソースとして、EC2インスタンスや VPC、サブネット、セキュリティグループ、 Transit Gateway などがあります。
これらリソースのARNは arn:aws:ec2:* で表せます( * はワイルドカード)。
対象の アクション(Action)は何か
Amazon EC2 で定義されるアクション において、大半のリソースの削除は Delete* といった
アクションで定義されています( * はワイルドカード)。
しかし、例えば EC2インスタンスの削除(終了) は TerminateInstances だったりします。
このように保護したいリソースのそれぞれについて、 削除するアクションが何か把握しておく必要があります。
今回はEC2リソースの以下アクションを対象とします。
Delete*Terminate*
どの条件(Condition)下で禁止するか
今回は Protection/enabled のタグ/値が付けられたリソースがあったときに 、削除を禁止するようにします。
この条件を厳密に書くと以下のようになります。
- 「Protectionタグが存在する」
 - かつ 「Protectionタグの値が "enabled" である」
 
SCP 実装
設計を基に以下のような SCPを書いてみました。
   
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Resource": "arn:aws:ec2:*",
      "Action": [
        "ec2:Delete*",
        "ec2:Terminate*"
      ],
      "Condition": {
        "Null": {
          "aws:ResourceTag/Protection": false
        },
        "StringEquals": {
          "aws:ResourceTag/Protection": "enabled"
        }
      }
    }
  ]
}
Effect, Resource, Action の部分は設計から分かると思います。
Condition 部分の解説をしていきます。
Condition "Null" 部分の説明
    
"Null": {
  "aws:ResourceTag/Protection": false
},
「Protectionタグが存在する」 を表しています。
Null は 条件演算子の1つです。条件キー(今回は aws:ResourceTag/Protection)
がリクエスト情報に含まれているかチェックをします。
含まれていない場合 は true 、 含まれている場合は false を返します。
aws:ResourceTag/tag-key は条件キーの1つで、 リソースにアタッチされたタグの値を使った比較を行うことができます。
つまり "Null": { "aws:ResourceTag/Protection": false } は
「リソースに Protectionタグが 含まれている場合 」に 真となります。
今回実現したい 「Protectionタグが存在する」 にマッチする条件です。
Condition "StringEquals" 部分の説明
    
"StringEquals": {
  "aws:ResourceTag/Protection": "enabled"
}
「Protectionタグの値が "enabled" である」 を表しています。
StringEquals は文字列条件演算子の 1つです。
条件キー(今回は aws:ResourceTag/Protection)の値が
指定文字列(今回は "enabled") に完全一致するかチェックします。
つまり "StringEquals": { "aws:ResourceTag/Protection": "enabled"} は
「リソースの Protectionタグ値が "enabled" と完全一致する場合 」 に真となります。
今回実現したい 「Protectionタグの値が "enabled" である」 にマッチする条件です。
検証(実際の運用の流れ)
以下のように各AWSアカウントに管理者/開発者がいる環境を想定します。

この SCPを使ったインフラリソースの保護の運用においては、 「Protectionタグを編集できる人/できない人」 を明確に分けておく必要があります。
例えば開発者には Protection タグを編集できないようにするために、以下のような
ポリシーを追加しておきます。
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Resource": "arn:aws:ec2:*",
      "Action": [
        "ec2:DeleteTags",
        "ec2:CreateTags"
      ],
      "Condition": {
        "Null": {
          "aws:RequestTag/Protection": false
        }
      }
    }
  ]
}
検証環境
以下のようなシンプルな環境で検証しました。

検証1: Protection/enabled タグ/値が付与されたリソースの削除ができないこと
管理者から VPCに以下タグを付けます。

これを削除しようとすると以下のような画面が出ます。SCPにより削除が拒否されました。

検証2: Protection/(enabled以外) タグ/値が付与されたリソースの削除ができること
管理者から VPCの Protection タグ値を enabled以外 に変更します。

Protection タグ値が enabled以外 なのでこのVPCは削除ができるようになります。
以下のように削除が許可されました。

おわりに/補足
SCPを使ったタグベースの制御による AWSリソースの保護を試してみました。
「他のAWSリソースも保護したい」 や 「削除だけでなく変更処理のアクションも禁止したい」 といったケースも もちろん出てくると思います。 そういった場合も今回の [設計内容] で進めたような以下のようなプロセスでしっかりと設計していきましょう。
- 対象のリソース(Resource)は何か
 - 対象のアクション(Action)は何か
 
また今回は説明を省きましたが、そもそも サービスがタグベース制御に対応しているか を事前に調査しておく必要があります。 これは IAM と連携する AWS のサービス のページから確認できます。

– 画像: IAM と連携する AWS のサービス #コンピューティングサービス






