AWSWindows

EC2上にSQL Server Always On 可用性グループを構築!【AWS CloudFormation編】

はじめに

SQL Server on EC2を用いて、Always On 可用性グループを構築する方法を調べましたが1つの媒体にまとまってるのを見つけられなかったため記事を執筆することにしました!
今回は、AWS CloudFormation編に該当します。VPC関連とEC2とAWS Managed Microsoft ADのリソースを構築していきます。
また、構築順序は下記の通り参照してください。
AWS CloudFormation編 > OS設定編 > WSFC設定編 > Always On 可用性グループ設定編

前提

・対象OS:Windows Server 2022
・対象SQL Serverエディション:SQL Server 2022 Standard Edition
・AWSアカウントが既にあること
・東京リージョンを使用

構築リソース情報

下記表の値を用いて、構築する

項目
1号機(ホスト名:PublicInstance1)のプライマリIP10.0.1.100
1号機(ホスト名:PublicInstance1)のセカンダリIP(クラスタコアリソース用)10.0.1.101
1号機(ホスト名:PublicInstance1)のセカンダリIP(サービス用)10.0.1.102
2号機(ホスト名:PublicInstance2)のプライマリIP10.0.2.100
2号機(ホスト名:PublicInstance2)のセカンダリIP(クラスタコアリソース用)10.0.2.101
2号機(ホスト名:PublicInstance2)のセカンダリIP(サービス用)10.0.2.102
Managed Microsoft ADのDNS 1a側のIP10.0.3.204
※リソース作成後に自動採番されるため、左記と違う可能性あり
Managed Microsoft ADのDNS 1c側のIP10.0.4.112
※リソース作成後に自動採番されるため、左記と違う可能性あり
WSFCのクラスタ名poc-cluster
可用性グループ名poc-sqlserver

概要図

CloudFormationの事前準備

コード編集&保存

下記コードをローカルにYAMLファイルとして保存(例:Poc.yml)
(もしリソース名、キーペア、IP等を変えた場合、適宜コードを編集してください)

AWSTemplateFormatVersion: '2010-09-09'
Description: Create a VPC with 2 Public and 2 Private Subnets in Tokyo Region, and EC2 instances in Public Subnets, and AWS Managed Microsoft AD

Parameters:
  VPCName:
    Type: String
    Default: PoCVPC
    Description: Name of the VPC

  PublicSubnet1CIDR:
    Type: String
    Default: 10.0.1.0/24
    Description: CIDR block for the first public subnet

  PublicSubnet2CIDR:
    Type: String
    Default: 10.0.2.0/24
    Description: CIDR block for the second public subnet

  PrivateSubnet1CIDR:
    Type: String
    Default: 10.0.3.0/24
    Description: CIDR block for the first private subnet

  PrivateSubnet2CIDR:
    Type: String
    Default: 10.0.4.0/24
    Description: CIDR block for the second private subnet

  WindowsServer2022AMI:
    Type: String
    Description: The AMI ID for Windows Server 2022
    Default: ami-086acc6b2cb62480c  # SQL Server 2022 Standardが含まれたWindows Server 2022 Japanese

  InstanceType:
    Type: String
    Default: m7i.large
    Description: EC2 instance type

  KeyName:
    Type: String
    Default: PoC
    Description: Key pair # 事前にキーペアを作成する

  DirectoryName:
    Type: String
    Default: poc.com
    Description: The fully qualified domain name for the AWS Managed Microsoft AD

  DirectoryPassword:
    Type: String
    NoEcho: true
    Description: The password for the directory admin user

  Edition:
    Type: String
    Default: Standard
    AllowedValues:
      - Standard
      - Enterprise
    Description: The Edition of the AWS Managed Microsoft AD directory

Resources:
  # VPC
  VPC:
    Type: AWS::EC2::VPC
    Properties: 
      CidrBlock: 10.0.0.0/16
      Tags:
        - Key: Name
          Value: !Ref VPCName

  # Public Subnets
  PublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: !Ref PublicSubnet1CIDR
      AvailabilityZone: ap-northeast-1a
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: PublicSubnet1

  PublicSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: !Ref PublicSubnet2CIDR
      AvailabilityZone: ap-northeast-1c
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: PublicSubnet2

  # Private Subnets
  PrivateSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: !Ref PrivateSubnet1CIDR
      AvailabilityZone: ap-northeast-1a
      Tags:
        - Key: Name
          Value: PrivateSubnet1

  PrivateSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: !Ref PrivateSubnet2CIDR
      AvailabilityZone: ap-northeast-1c
      Tags:
        - Key: Name
          Value: PrivateSubnet2

  # Internet Gateway
  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: MyInternetGateway

  AttachGateway:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref InternetGateway

  # Route Table and Routes
  RouteTablePublic:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: PublicRouteTable

  PublicRoute:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref RouteTablePublic
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway

  SubnetRouteTableAssociationPublic1:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet1
      RouteTableId: !Ref RouteTablePublic

  SubnetRouteTableAssociationPublic2:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet2
      RouteTableId: !Ref RouteTablePublic

  # Security Group
  SecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Allow RDP and VPC traffic
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 3389
          ToPort: 3389
          CidrIp: 0.0.0.0/0
        - IpProtocol: -1
          CidrIp: 10.0.0.0/16

  # Elastic Network Interface (ENI) with multiple private IP addresses
  NetworkInterface1:
    Type: AWS::EC2::NetworkInterface
    Properties:
      SubnetId: !Ref PublicSubnet1
      GroupSet:
        - !Ref SecurityGroup
      PrivateIpAddresses:
        - PrivateIpAddress: 10.0.1.100
          Primary: true
        - PrivateIpAddress: 10.0.1.101 # クラスタコアリソース用#1
          Primary: false
        - PrivateIpAddress: 10.0.1.102 # Always On リスナー用#1
          Primary: false
      Tags:
        - Key: Name
          Value: NetworkInterface1

  NetworkInterface2:
    Type: AWS::EC2::NetworkInterface
    Properties:
      SubnetId: !Ref PublicSubnet2
      GroupSet:
        - !Ref SecurityGroup
      PrivateIpAddresses:
        - PrivateIpAddress: 10.0.2.100
          Primary: true
        - PrivateIpAddress: 10.0.2.101 # クラスタコアリソース用#2
          Primary: false
        - PrivateIpAddress: 10.0.2.102 # Always On リスナー用#2
          Primary: false
      Tags:
        - Key: Name
          Value: NetworkInterface2

  # EC2 Instances
  EC2InstancePublic1:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: !Ref InstanceType
      ImageId: !Ref WindowsServer2022AMI
      NetworkInterfaces:
        - NetworkInterfaceId: !Ref NetworkInterface1
          DeviceIndex: 0
      KeyName: !Ref KeyName
      Tags:
        - Key: Name
          Value: PublicInstance1

  EC2InstancePublic2:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: !Ref InstanceType
      ImageId: !Ref WindowsServer2022AMI
      NetworkInterfaces:
        - NetworkInterfaceId: !Ref NetworkInterface2
          DeviceIndex: 0
      KeyName: !Ref KeyName
      Tags:
        - Key: Name
          Value: PublicInstance2
  
  # Managed AD
  ManagedMicrosoftAD:
    Type: AWS::DirectoryService::MicrosoftAD
    Properties:
      Name: !Ref DirectoryName
      Password: !Ref DirectoryPassword
      Edition: !Ref Edition
      VpcSettings:
        VpcId: !Ref VPC
        SubnetIds:
          - !Ref PrivateSubnet1
          - !Ref PrivateSubnet2

キーペアの作成

[EC2コンソール] > [キーペア] > [キーペアを作成]

下記参照し、[キーペアを作成]を選択
(コード編集でキーペア名を変えてる場合、適宜変更してください)

キーペア作成完了!

CloudFormationの実行

[CloudFormationコンソール] > [スタック] > [スタックの作成]

テンプレートの準備:既存のテンプレートを選択
テンプレートソース:テンプレートファイルのアップロード
[ファイルの選択より、ファイルをアップロード] > [次へ]

下記入力後、[次へ]
・スタック名
・DirectoryPassword
(お好み応じて他のパラメータ編集)

スタックオプションの設定は、デフォルトで[次へ]
(図省略)

設定値の確認後、[送信]

Cloudformationのスタックが作成される!
(完了まで、Managed Microsoft AD作成に時間を要し約30~40分ほどかかる)

おまけ

Managed Microsoft ADのDNS IP確認

[Directory Serviceコンソール] > [ディレクトリ] > [該当のディレクトリID]より、詳細開く

EC2に紐づいているセキュリティグループのルール変更(RDP接続のソースを変更)

変更前:

変更後:


最後に

Cloudformation編、問題なく構築することができましたか?
次は、OS初期設定等のOS設定編に入っていきます!

参照

AWS Directory Serviceで「Managed Microsoft AD」を構築した際の「管理用サーバー」の設定方法
【SQL Server on EC2】インスタンス間でAlwaysOnを構成する [1. OS準備編]
(1/4)AWS EC2でWindowsクラスタ検証:共有ストレージ検討編

Kano

社会人5年目のKanoです。tech系を筆頭に投稿します。 資格:AWS13冠、TOEIC 795

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です