CloudFormationでさくっとEFSを作成して、AWS Backupする Templateを作成してみた

AWS事業本部 梶原@福岡オフィスです。

既存のEC2に対して、EFSファイルシステムを作成しマウント、ファイル共有をする構成を作成する際に CloudFormation Templateで作成したので公開します。 勢いで先日東京リージョンにGAされたAWS Backupも設定していますので、CloudFormationで構築する際に役に立つと幸いです。

今回作成したAmazon EFSファイルシステムは2つのサブネットに配置されたEC2からアクセスされることを想定しています。 また、AWS Backpuは1日1回取得する設定にしています。バックアップ保持日数等はパラメータ化していますが、構築要件に合わせてご自由にカスタマイズください。

構成図

前提条件

  • VPC
  • サブネット(2つ)
  • EC2 (Amazon Linux2)
    • OSは特に制限はありませんが、EFSファイルシステムのマウントコマンド等はAmazon Linux2を想定しています。
  • EC2へのSecurityGroupの割り当て
    • EFSへの接続をEC2へ割り当てたSecurityGroupで作成しています。

CloudFormationテンプレート

入力パラメータ

ネットワーク設定

  • Vpc
    • EFSを作成するVPCを選択してください
  • Subnets
    • エンドポイントを作成するサブネットを2つ選択してください
  • EC2SecurityGroup
    • アクセス元となるセキュリティグループを選択してください
    • EFSに割り当てるセキュリティグループはCloudFormationの中で作成します。

※2つのサブネットからアクセスされることを想定しています。1つのサブネットもしくは3つのサブネットからのアクセスが必要な場合はテンプレートの編集を行ってください。

EFS設定

  • Encrypted
    • 暗号化の有無
  • PerformanceMode
    • generalPurpose:汎用,MaxIO:最大パフォーマンス その他の設定は基本的にデフォルト設定としています。

AWS Backup設定

  • UseAWSBackup (false)
    • AWS Backupを使用する場合はtrueを選択してください(デフォルトはfalseにしています)
  • BackupHour (5)
    • Backup開始時刻をUTCで指定します(実際のバックアップ開始までは1時間のタイムラグがあります)
  • DeleteAfterDays (40)
    • バックアップを削除するに日数を指定します その他の設定は基本的にデフォルト設定としています。

CloudFormationテンプレートの実行

テンプレートはS3に置いてますので、ログイン後に以下ボタンをポチっとしてください。 ※IAMの権限(AWS Backup用のIAM Roleを作成します)の確認がありますので、AWS CloudFormation によって IAM リソースが作成される場合があることを承認します。にチェックをして進めてください。

パラメータ

CloudFormation実行後作成後のリソース状況

EFS

コンソール https://ap-northeast-1.console.aws.amazon.com/efs/home?region=ap-northeast-1#/filesystems

  • 指定したVPCまた、サブネットに作成されているか確認をお願いします。

AWS Backup

コンソール https://ap-northeast-1.console.aws.amazon.com/backup/home?region=ap-northeast-1#dashboard

  • 指定した時刻また、作成したEFSリソースが指定されているか確認をお願いします。

EFSのマウント

CloudFormationのテンプレートのOutputにマウント用のコマンドが出力されますので参考にしてEC2よりEFSをマウントして使用して下さい。

$ sudo yum install -y amazon-efs-utils;
$ sudo mkdir -p /mnt/efs; sudo mount -t efs fs-xxxxxx:/ /mnt/efs;

※マウント先のエンドポイントは作成毎に代わりますので、ご確認ください。

AWS Backupの実行確認

指定した時間(UTC)(1時間のバックアップ開始時間の猶予があります)にバックアップが実行されていることを確認してください。

まとめ

EFSのCloudFormationテンプレートを作成していたのですが、丁度いいタイミングでAWS Backupが東京でGAされたのでCloudFormationで作ってみました あまりテンプレートのサンプルも見当たらなかったので、どなたかのお役に立てると幸いです。

テンプレート

AWSTemplateFormatVersion: '2010-09-09'
Metadata: 
  AWS::CloudFormation::Interface: 
    ParameterGroups: 
      - Label: 
          default: "Network Settings"
        Parameters:
          - Vpc
          - Subnets
          - EC2SecurityGroup
      - Label: 
          default: "EFS Settings"
        Parameters:
          - Encrypted
          - PerformanceMode
      - Label: 
          default: "AWS Backup Settings"
        Parameters:
          - UseAWSBackup
          - BackupHour
          - DeleteAfterDays
 
Parameters:
  Vpc:
    Type: AWS::EC2::VPC::Id
    Description: Vpc Name.
  EC2SecurityGroup:
    Type: AWS::EC2::SecurityGroup::Id
    Description: Environment Name.
  Subnets:
    Type: 'List<AWS::EC2::Subnet::Id>'
    Description: The list of SubnetIds in your Virtual Private Cloud (VPC)
    ConstraintDescription: >-
      must be a list of at least two existing subnets associated with at least
      two different availability zones. They should be residing in the selected
      Virtual Private Cloud.
  Encrypted:
    Type: String
    Default: false
    AllowedValues: [false, true]
    Description: A Boolean value that, if true, creates an encrypted file system. 
  PerformanceMode:
    Type: String
    Default: generalPurpose
    AllowedValues: [generalPurpose, maxIO]
    Description: The performance mode of the file system. 
  UseAWSBackup:
    Type: String
    Default: no
    AllowedValues: [yes, no]
  BackupHour:
    Type: Number
    Default: 5
    Description: specifying the hour when AWS Backup initiates a backup job.(UTC)
  DeleteAfterDays:
    Type: Number
    Default: 40
    Description: Specifies the number of days after creation that a recovery point is deleted
    
Conditions:
  UseAWSBackup: !Equals [ !Ref UseAWSBackup, yes ]
Resources:
  EfsSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: EFS Allowed Ports
      VpcId: !Ref Vpc
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 2049
          ToPort: 2049
          SourceSecurityGroupId: !Ref EC2SecurityGroup
      Tags: 
        - Key: Name
          Value: EfsSecurityGroup

  FileSystem:
    Type: AWS::EFS::FileSystem
    Properties: 
      Encrypted: !Ref Encrypted
      PerformanceMode: !Ref PerformanceMode

  MountTarget1:
    Type: AWS::EFS::MountTarget
    Properties:
      FileSystemId: !Ref FileSystem
      SubnetId: !Select [ 0, !Ref Subnets ]
      SecurityGroups: 
        - !Ref EfsSecurityGroup

  MountTarget2:
    Type: AWS::EFS::MountTarget
    Properties:
      FileSystemId: !Ref FileSystem
      SubnetId: !Select [ 1, !Ref Subnets ]
      SecurityGroups: 
        - !Ref EfsSecurityGroup

  BackupPlan:
    Condition: UseAWSBackup
    Type: AWS::Backup::BackupPlan
    Properties: 
      BackupPlan: 
        BackupPlanName: "EfsDailyBackupPlan"
        BackupPlanRule: 
          - RuleName: "EfsDailyBackupPlanRule"
            TargetBackupVault: !Ref BackupVault
            ScheduleExpression: !Sub "cron(0 ${BackupHour} ? * * *)"
            StartWindowMinutes: 60
            # CompletionWindowMinutes: 10080
            Lifecycle:
              DeleteAfterDays: !Ref DeleteAfterDays

  BackupSelection:
    Condition: UseAWSBackup
    Type: AWS::Backup::BackupSelection
    Properties:
      BackupPlanId: !Ref BackupPlan
      BackupSelection:
        SelectionName: "EfsBackupResouce"
        IamRoleArn: !GetAtt AWSBackupServiceRole.Arn
        Resources:
          - !Sub "arn:aws:elasticfilesystem:${AWS::Region}:${AWS::AccountId}:file-system/${FileSystem}"

  BackupVault:
    Condition: UseAWSBackup
    Type: AWS::Backup::BackupVault
    Properties: 
      BackupVaultName: EfsBackupVault

  AWSBackupServiceRole:
    Condition: UseAWSBackup
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
        - Action: "sts:AssumeRole"
          Effect: "Allow"
          Principal:
            Service: backup.amazonaws.com
      Path: "/service-role/"
      ManagedPolicyArns:
        - "arn:aws:iam::aws:policy/service-role/AWSBackupServiceRolePolicyForBackup"
        - "arn:aws:iam::aws:policy/service-role/AWSBackupServiceRolePolicyForRestores"

Outputs:
  MountCommand1:
    Value: sudo yum install -y amazon-efs-utils;
  MountCommand2:
    Value: !Sub sudo mkdir -p /mnt/efs; sudo mount -t efs ${FileSystem}:/ /mnt/efs;