【Reusableシリーズ】AWS KMSを使用したS3の設定方法：Management ConsoleとCloudFormationでの手順解説

# 初めに
今回は、AWS 構築において最も汎用的な S3 バケットの作成と KMS を活用した暗号化手法を、マネジメントコンソール操作と再利用可能な CloudFormation テンプレートの作成方法について皆さんに紹介します。

# AWS KMSとCloudformationを利用した設定の比較

AWS Key Management Service (KMS) を使用して、S3オブジェクトを暗号化するためのカスタマーマスターキー (CMK) を作成します。AWS KMS を使用すると、暗号化キーへのアクセス制御を管理、キーをローテーション、キーの使用状況を監査できます。

## AWS KMSでCMKを作成する手順

1. AWS マネジメント コンソールにログインし、AWS KMS ダッシュボードに移動します。
2. [キーの作成] をクリックし、[対称] キー タイプを選択します。
3. CMK のエイリアスと説明を選択します。
4. IAM ユーザーとロールを選択して、キーの管理権限とキーの使用権限を定義します。
5. キー ポリシーを確認し、CMK の作成を完了します。
:::note info
AWS KMS と統合された AWS のサービスは、データの暗号化に対称暗号化 KMS キーのみを使用します。
:::

## S3 バケットで CMK を使用する手順

1. AWS マネジメント コンソールの S3 ダッシュボードに移動し、オブジェクトを暗号化するバケットを選択します。
2. [プロパティ] タブに移動し、[デフォルトの暗号化] の下にある [編集] をクリックします。
3. 暗号化方法として「AWS-KMS」を選択し、リストから前に作成した CMK を選択するか、その Amazon リソースネーム (ARN) を指定します。
4. 変更を保存します。

## KMS暗号化キーへの安全なアクセス

1. **アクセス制御の管理**: IAM ポリシーを定義して、CMK を管理または使用できるユーザーまたはロールを制御します。 これにより、許可された担当者のみにアクセスを制限できます。
2. **キー ローテーション**: AWS KMS で自動キー ローテーションを有効にして、CMK の新しいバッキング キーを毎年作成します。 これにより、長期にわたってセキュリティを維持できます。
3. **キーの使用状況を監査する**: AWS CloudTrail を使用して、CMK のすべての使用状況を追跡および監査し、誰がどのような目的でキーを使用しているかを把握します。

暗号化キー管理に AWS KMS を活用することで、安全なファイルストレージと共有プラットフォームのセキュリティとアクセス制御を強化し、データを常に保護することができます。

## CloudFormationを利用した設定

AWS CloudFormationを使用すると、インフラストラクチャの設定をコードとして記述し、自動化されたプロセスを通じてリソースをプロビジョニングおよび管理できます。これにより、環境間での一貫性が向上し、ヒューマンエラーが減少します。

### CloudFormationを使用してCMKを作成する手順

1. AWS CloudFormationテンプレートファイル（YAMLまたはJSON形式）を作成し、`AWS::KMS::Key`リソースタイプを使用してCMKを定義します。
2. キーのエイリアス、説明、キーポリシー、キーローテーション設定など、必要なプロパティを指定します。
3. AWSマネジメントコンソール、AWS CLI、またはSDKを使用して、CloudFormationテンプレートをデプロイし、スタックを作成します。
4. スタックが正常に作成されると、CMKがプロビジョニングされます。

### CloudFormationを使用してS3バケットでCMKを使用する手順

1. 作成したCMKのAmazonリソースネーム（ARN）を取得します。
2. AWS CloudFormationテンプレートファイルに、`AWS::S3::Bucket`リソースタイプを使用してS3バケットを定義します。
3. BucketEncryptionプロパティを設定し、KMS暗号化を有効にし、取得したCMKのARNを指定します。
4. テンプレートをデプロイし、スタックを更新または作成します。

AWS CloudFormationを使用する利点は、インフラストラクチャの設定をコードとして管理できるため、バージョン管理と変更の追跡が容易になり、開発、テスト、本番環境間での一貫性が向上します。また、リソースのプロビジョニングと構成の自動化により、ヒューマンエラーが減少し、効率が向上します。

結果として、AWS KMSとCloudFormationを組み合わせることで、セキュアなファイルストレージと共有プラットフォームを効果的に構築および管理でき、データ保護におけるセキュリティとアクセス制御を強化できます。

# 再利用できるS3バケットをCMKで暗号化したAWS CloudFormation テンプレート

このテンプレートは、AWS CloudFormation を使用して、セキュアなファイルストレージと共有プラットフォームを作成するためのリソースを定義します。テンプレートには、S3バケット、KMSキー、S3バケットポリシーが含まれています。

```yaml
AWSTemplateFormatVersion: '2010-09-09'
Description: S3 and KMS

Parameters:
  BucketName:
    Description: Unique S3 bucket name for file storage
    Type: String

  KeyAdminRoleArn:
    Description: IAM role ARN for the key administrator role
    Type: String

  KeyUserRoleArn:
    Description: IAM role ARN for the key user role
    Type: String

Resources:
  SecureFileBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Ref BucketName
      BucketEncryption:
        ServerSideEncryptionConfiguration:
          - ServerSideEncryptionByDefault:
              KMSMasterKeyID: !Ref SecureFileCMK
              SSEAlgorithm: aws:kms

  SecureFileCMK:
    Type: AWS::KMS::Key
    Properties:
      Description: CMK for secure file storage and sharing
      KeyPolicy:
        Version: '2012-10-17'
        Id: key-default
        Statement:
          - Sid: Enable IAM Key Admin Permissions
            Effect: Allow
            Principal:
              AWS: !Ref KeyAdminRoleArn
            Action:
              - kms:Create*
              - kms:Describe*
              - kms:Enable*
              - kms:List*
              - kms:Put*
              - kms:Update*
              - kms:Revoke*
              - kms:Disable*
              - kms:Get*
              - kms:Delete*
              - kms:TagResource
              - kms:UntagResource
              - kms:ScheduleKeyDeletion
              - kms:CancelKeyDeletion
            Resource: '*'
          - Sid: Allow Use of the Key for Key User Role
            Effect: Allow
            Principal:
              AWS: !Ref KeyUserRoleArn
            Action:
              - kms:Encrypt
              - kms:Decrypt
              - kms:ReEncrypt*
              - kms:GenerateDataKey*
              - kms:DescribeKey
            Resource: '*'

  SecureFileBucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref SecureFileBucket
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Sid: DenyIncorrectEncryptionHeader
            Effect: Deny
            Principal: '*'
            Action: s3:PutObject
            Resource: !Sub 'arn:aws:s3:::${SecureFileBucket}/*'
            Condition:
              'Null':
                s3:x-amz-server-side-encryption-aws-kms-key-id: 'true'

          - Sid: DenyIncorrectEncryptionHeader
            Effect: Deny
            Principal: '*'
            Action: s3:PutObject
            Resource: !Sub 'arn:aws:s3:::${SecureFileBucket}/*'
            Condition:
              StringNotEquals:
                's3:x-amz-server-side-encryption': 'aws:kms'

Outputs:
  SecureFileBucketName:
    Description: Name of the S3 bucket for secure file storage
    Value: !Ref SecureFileBucket
    Export:
      Name: SecureFileBucketName

  SecureFileCMKArn:
    Description: ARN of the Customer Master Key (CMK) for file encryption
    Value: !GetAtt SecureFileCMK.Arn
    Export:
      Name: SecureFileCMKArn
```


## パラメーター

- **BucketName**: ファイルストレージ用の一意のS3バケット名を指定します。
- **KeyAdminRoleArn**: キー管理者ロールのIAMロールARNを指定します。
- **KeyUserRoleArn**: キーユーザーロールのIAMロールARNを指定します。

## リソース

1. **SecureFileBucket**: AWS::S3::Bucket タイプのリソースです。ファイルの格納場所として使用されるS3バケットを作成します。バケットは、KMSキーによるサーバーサイド暗号化が有効化されています。

2. **SecureFileCMK**: AWS::KMS::Key タイプのリソースです。セキュアファイルストレージと共有用のカスタマーマスターキー（CMK）を作成します。キーのポリシーには、キー管理者およびキーユーザーロールが含まれています。

3. **SecureFileBucketPolicy**: AWS::S3::BucketPolicy タイプのリソースです。SecureFileBucket に適用されるバケットポリシーを作成します。このポリシーにより、適切な暗号化ヘッダーがない場合にオブジェクトのアップロードが拒否されます。

## 出力

- **SecureFileBucketName**: セキュアファイルストレージ用のS3バケット名です。
- **SecureFileCMKArn**: ファイル暗号化用のカスタマーマスターキー（CMK）のARNです。

このテンプレートを使用して CloudFormation スタックを作成することで、セキュアなファイルストレージおよび共有プラットフォームのリソースが簡単にデプロイできます。

# まとめ
基本的な S3 と KMS の構成について説明しました。個人的には、マネジメントコンソール操作よりも、CloudFormation を使用した作成が業務において非常に効率的だと感じます。ただし、各セクションの意味や構成を誤ると、セキュリティ上の問題が発生する可能性があるため、正確な理解を持って作成することが重要です。適切なテンプレートを一度作成しておくことで、インフラ環境の構築時間が短縮され、迅速な展開が可能になるため、大変便利なサービスだと思います。