[小ネタ]Lambda-backed custom resourcesでEBSデフォルト暗号化のアカウント設定を有効にする

新しいAWSアカウントを作成するタイミングでEBSデフォルト暗号化のアカウント設定を有効にしたい方向け
2022.02.23

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、おんづか(@onzuka_muscle)です!

こちらのブログを参考にアカウントが特定OUに所属したタイミングでLambdaを実行し、EBSデフォルト暗号化のアカウント設定を有効にしてみました。

EBSデフォルト暗号化のアカウント設定」はEC2ダッシュボードから確認することができます。

デフォルトでは無効になっています。

注意点

  • Lambdaが実行された後もLambda , IAMロール , CloudWatch Logsといったリソースは残ります
    • 必要に応じて削除してください
  • あくまでサンプルコードです
    • エラーハンドリング・ロギングについてはそこそこなので必要に応じてカスタマイズください

テンプレート

AWSTemplateFormatVersion: "2010-09-09"
# ------------------------------------------------------------#
#  EBS デフォルト暗号化を有効にする Lambda-backed custom resources
# ------------------------------------------------------------#
Parameters:
  RoleName:
    Type: String
  FunctionName:
    Type: String

Resources:
  # ------------------------------------------------------------#
  #  Lambda-backed custom resources
  # ------------------------------------------------------------#
  EnableEBSDefaultEncryption:
    Type: Custom::EnableEBSDefaultEncryption
    Properties:
      ServiceToken: !GetAtt "LambdaFunction.Arn"

  # ------------------------------------------------------------#
  #  Lambda 関数
  # ------------------------------------------------------------#
  LambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: !Ref FunctionName
      Description: Lambda for enable EBS default encryption
      Role: !GetAtt "LambdaExecutionRole.Arn"
      Runtime: "python3.8"
      Handler: index.lambda_handler
      Timeout: 60
      Code:
        ZipFile: |
          import boto3
          import cfnresponse
          from logging import getLogger, INFO
          from botocore.exceptions import ClientError

          logger = getLogger()
          logger.setLevel(INFO)


          def enable_encryption_ebs(event, context):
            logger.info('[START] enable_encryption_ebs')
            logger.info("boto3 version:{}".format(boto3.__version__))

            regions = boto3.Session().get_available_regions('ec2')

            for region in regions:
              try:
                client = boto3.client("ec2", region_name=region)
                status = client.get_ebs_encryption_by_default()
              except ClientError as e:
                logger.info(region + ":ec2 is not enabled")
              else:
                logger.info(region + " START")
                try:
                  response = client.enable_ebs_encryption_by_default()
                  if response['ResponseMetadata']['HTTPStatusCode'] == 200:
                      logger.info("  enable success")
                  else:
                      logger.info("  enable failed")
                  logger.info('[END] enable_encryption_ebs')
                except Exception as e:
                    logger.error(e)
                    cfnresponse.send(event, context, cfnresponse.FAILED,{'Response': 'Failure'})
                    exit()


          def lambda_handler(event, context):
            if event['RequestType'] == 'Create':
                # Create時に実行したい処理 --> EBS デフォルト暗号化を有効にする
                enable_encryption_ebs(event, context)
                cfnresponse.send(event, context, cfnresponse.SUCCESS,{'Response': 'Success'})
            if event['RequestType'] == 'Delete':
                # Delete時に実行したい処理 --> 無し
                cfnresponse.send(event, context, cfnresponse.SUCCESS,{'Response': 'Success'})
            if event['RequestType'] == 'Update':
                # Update時に実行したい処理 --> 無し
                cfnresponse.send(event, context, cfnresponse.SUCCESS,{'Response': 'Success'})

  # ------------------------------------------------------------#
  #  Lambda 関数用の IAM ロール
  # ------------------------------------------------------------#
  LambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Ref RoleName
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: "lambda.amazonaws.com"
            Action: "sts:AssumeRole"
      ManagedPolicyArns:
        - "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
      Policies:
        - PolicyName: EbsEncryptionByDefaultPolicy
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - "ec2:GetEbsEncryptionByDefault"
                  - "ec2:EnableEbsEncryptionByDefault"
                  - "ec2:DescribeRegions"
                Resource: "*"

動作確認

全リージョンで設定が有効になっていました。

おわり

サンプルコードになりますが需要あるかなと思いブログにしました。

こちらのブログのようにCloudFormation StackSetsと組み合わせることで新しく作成したアカウントの「EBSデフォルト暗号化を有効」にする作業を効率化できます。

誰かのお役に立てば嬉しいです。