FSxW + EC2(Win,Linux)構築ハンズオン


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

はじめに

FSxを久しぶりにハンズオンで構築しようとしたら、すっかり細かい設定を忘れていたので、こういったものこそCFnしておかなければなと思い立ったのでハンズオン。
いろいろハマりました。


構成図


ハンズオン

構築のながれ

1.Amazon FSx環境作成 


1.Amazon FSx環境作成 

1.1.主な作成リソース一覧

サービス名 CIDR 用途
VPC 192.168.0.0/16
PublicSubnetA 192.168.10.0/24 EC2(Windows)用
PublicSubnetB 192.168.20.0/24 EC2(Linux)用
PrivateSubnetA 192.168.30.0/24 MicrosoftAD用
PrivateSubnetB 192.168.40.0/24 MicrosoftAD用
PrivateSubnetC 192.168.50.0/24 FSx用
PrivateSubnetD 192.168.60.0/24 FSx用
PublicRouteTable Public ルートテーブル
PrivateRouteTable Private ルートテーブル
MicrosoftAD 192.168.${30,40}.XX FSx構築の際必須リソース
EC2 SecurityGroup EC2用セキュリティグループ
EC2(Windows) 192.168.10.YY FSxマウント用EC2
EC2(AmazonLinux) 192.168.20.ZZ FSxマウント用EC2
FSx SecurityGroup FSx用セキュリティグループ
FSx 192.168.${50,60}.AA FSx

1.2.テンプレート

・全てのリソースが構築されるには30分程度かかります。
・個人的にハマったMicrosoftADEC2(Windows)は別途記載あり。

AWSTemplateFormatVersion: "2010-09-09"
Description: FSx Create
# ------------------------------------------------------------#
#  Metadata
# ------------------------------------------------------------#
Metadata:
  "AWS::CloudFormation::Interface":
    ParameterGroups:
      - Label:
          default: "NetWork Configuration"
        Parameters:
          - VpcCidrPrefix
      - Label:
          default: "MicrosoftAD Configuration"
        Parameters:
          - MicrosoftAdDomainName
          - MicrosoftPassword
      - Label:
          default: "EC2 Configuration"
        Parameters:
          - Ec2Image-amazonlinuxId
          - EC2Image-WindowsID
          - MyIP
          - KeyName
      - Label:
          default: "Tags"
        Parameters:
          - UserName

# ------------------------------------------------------------#
#  InputParameters
# ------------------------------------------------------------#
Parameters:
  VpcCidrPrefix:
    Type: String
    Description: '(Example: 10.22)'
    Default: 【CIDRプレフィックス】

  MicrosoftAdDomainName:
    Type: String
    Description: '(Example: inamura.local)'
    Default: 【ドメイン名】

  MicrosoftAdPassword:
    Type: String
    NoEcho: True

  Ec2ImageAmazonlinuxId:
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2

  EC2ImageWindowsID:
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: /aws/service/ami-windows-latest/Windows_Server-2016-Japanese-Full-Base

  MyIP:
    Type: String
    Description: 'MyIP'
    Default: 【利用しているIPを記入】

  KeyName:
    Type: AWS::EC2::KeyPair::KeyName
    Default: 【利用しているKeyPairを記入】

  UserName:
    Type: String
    Description: 'TagsName'
    Default: 【タグを利用の場合】

# ------------------------------------------------------------#
#  Resources
# ------------------------------------------------------------#
Resources:
# ------------------------------------------------------------#
#  VPC
# ------------------------------------------------------------#
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Sub '${VpcCidrPrefix}.0.0/16'
      EnableDnsHostnames: true
      EnableDnsSupport: true
      InstanceTenancy: default
      Tags:
        - Key: Name
          Value: !Sub '${AWS::StackName}-vpc'
        - Key: UserName
          Value: !Ref UserName
# ------------------------------------------------------------#
#  IGW
# ------------------------------------------------------------#
  IGW:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: !Sub '${AWS::StackName}-igw'

  VPCGW:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref IGW
# ------------------------------------------------------------#
#  Public Subnet
# ------------------------------------------------------------#
  PublicSubnetA: 
    Type: "AWS::EC2::Subnet"
    Properties: 
      AvailabilityZone: !Select
        - 0
        - Fn::GetAZs: !Ref 'AWS::Region'
      CidrBlock: !Sub '${VpcCidrPrefix}.10.0/24'
      VpcId: !Ref VPC 
      Tags: 
        - Key: Name
          Value: !Sub "${AWS::StackName}-public-a"
        - Key: User
          Value: !Ref UserName

  PublicSubnetB: 
    Type: "AWS::EC2::Subnet"
    Properties: 
      AvailabilityZone: !Select
        - 1
        - Fn::GetAZs: !Ref 'AWS::Region'
      CidrBlock: !Sub '${VpcCidrPrefix}.20.0/24'
      VpcId: !Ref VPC 
      Tags: 
        - Key: Name
          Value: !Sub "${AWS::StackName}-public-b"
        - Key: User
          Value: !Ref UserName

# ------------------------------------------------------------#
#  Private Subnet
# ------------------------------------------------------------#
  PrivateSubnetA: 
    Type: "AWS::EC2::Subnet"
    Properties: 
      AvailabilityZone: !Select
        - 0
        - Fn::GetAZs: !Ref 'AWS::Region'
      CidrBlock: !Sub '${VpcCidrPrefix}.30.0/24'
      VpcId: !Ref VPC 
      Tags: 
        - Key: Name
          Value: !Sub "${AWS::StackName}-private-a"
        - Key: User
          Value: !Ref UserName

  PrivateSubnetB: 
    Type: "AWS::EC2::Subnet"
    Properties: 
      AvailabilityZone: !Select
        - 1
        - Fn::GetAZs: !Ref 'AWS::Region'
      CidrBlock: !Sub '${VpcCidrPrefix}.40.0/24'
      VpcId: !Ref VPC 
      Tags: 
        - Key: Name
          Value: !Sub "${AWS::StackName}-private-b"
        - Key: User
          Value: !Ref UserName

  PrivateSubnetC: 
    Type: "AWS::EC2::Subnet"
    Properties: 
      AvailabilityZone: !Select
        - 0
        - Fn::GetAZs: !Ref 'AWS::Region'
      CidrBlock: !Sub '${VpcCidrPrefix}.50.0/24'
      VpcId: !Ref VPC 
      Tags: 
        - Key: Name
          Value: !Sub "${AWS::StackName}-private-c"
        - Key: User
          Value: !Ref UserName

  PrivateSubnetD: 
    Type: "AWS::EC2::Subnet"
    Properties: 
      AvailabilityZone: !Select
        - 1
        - Fn::GetAZs: !Ref 'AWS::Region'
      CidrBlock: !Sub '${VpcCidrPrefix}.60.0/24'
      VpcId: !Ref VPC 
      Tags: 
        - Key: Name
          Value: !Sub "${AWS::StackName}-private-d"
        - Key: User
          Value: !Ref UserName
# ------------------------------------------------------------#
#  Public RouteTable
# ------------------------------------------------------------#
  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub '${AWS::StackName}-public-routetable'
        - Key: User
          Value: !Ref UserName

# ------------------------------------------------------------#
# Routing
# ------------------------------------------------------------#
  PublicRoute: 
    Type: "AWS::EC2::Route"
    Properties: 
      RouteTableId: !Ref PublicRouteTable 
      DestinationCidrBlock: "0.0.0.0/0"
      GatewayId: !Ref IGW

  VpcPublicSubnetARouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnetA
      RouteTableId: !Ref PublicRouteTable

  VpcPublicSubnetBRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnetB
      RouteTableId: !Ref PublicRouteTable
# ------------------------------------------------------------#
#  Private RouteTable
# ------------------------------------------------------------#
  PrivateRouteTable: 
    Type: "AWS::EC2::RouteTable"
    Properties: 
      VpcId: !Ref VPC 
      Tags: 
        - Key: Name
          Value: !Sub '${AWS::StackName}-private-routetable'
        - Key: User
          Value: !Ref UserName

  PrivateSubnetARouteTableAssociation: 
    Type: "AWS::EC2::SubnetRouteTableAssociation"
    Properties: 
      SubnetId: !Ref PrivateSubnetA
      RouteTableId: !Ref PrivateRouteTable

  PrivateSubnetBRouteTableAssociation: 
    Type: "AWS::EC2::SubnetRouteTableAssociation"
    Properties: 
      SubnetId: !Ref PrivateSubnetB
      RouteTableId: !Ref PrivateRouteTable

  PrivateSubnetCRouteTableAssociation: 
    Type: "AWS::EC2::SubnetRouteTableAssociation"
    Properties: 
      SubnetId: !Ref PrivateSubnetC
      RouteTableId: !Ref PrivateRouteTable

  PrivateSubnetDRouteTableAssociation: 
    Type: "AWS::EC2::SubnetRouteTableAssociation"
    Properties: 
      SubnetId: !Ref PrivateSubnetD
      RouteTableId: !Ref PrivateRouteTable
# ------------------------------------------------------------#
#  MicrosoftAD
# ------------------------------------------------------------#        
  MicrosoftAD:
    Type: AWS::DirectoryService::MicrosoftAD
    Properties:
      Name: !Ref MicrosoftAdDomainName
      Password: !Ref MicrosoftAdPassword
      VpcSettings:
        SubnetIds:
          - !Ref PrivateSubnetA
          - !Ref PrivateSubnetB
        VpcId: !Ref VPC
      Edition: Standard

  DHCPOptions:
    Type: AWS::EC2::DHCPOptions
    Properties:
      DomainName: !Ref MicrosoftAdDomainName
      DomainNameServers: !GetAtt MicrosoftAD.DnsIpAddresses
      Tags:
        - Key: Name
          Value: !Sub '${AWS::StackName}-dhcp-options'

  VPCDHCPOptionsAssociation:
    Type: AWS::EC2::VPCDHCPOptionsAssociation
    Properties:
      DhcpOptionsId: !Ref DHCPOptions
      VpcId: !Ref VPC

# ------------------------------------------------------------#
#  SG EC2 Windows&Linux
# ------------------------------------------------------------#
  Ec2SecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: !Sub '${AWS::StackName}-ec2-sg'
      GroupName: !Sub '${AWS::StackName}-ec2-sg'
      SecurityGroupEgress:
        - CidrIp: 0.0.0.0/0
          Description: Allow all outbound traffic by default
          IpProtocol: "-1"
      SecurityGroupIngress:
        - CidrIp: !GetAtt VPC.CidrBlock
          Description: allow all access from vpc
          IpProtocol: "-1"
          FromPort: "-1"
          ToPort: "-1"
        - CidrIp: !Sub '${MyIP}/32'
          Description: allow all access from MyIP
          IpProtocol: "-1"
          FromPort: "-1"
          ToPort: "-1"
      VpcId: !Ref VPC
      Tags: 
        - Key: UserName
          Value: !Ref UserName
# ------------------------------------------------------------#
#  IAM EC2 Windows&Linux
# ------------------------------------------------------------#
  Ec2IamRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              Service: ec2.amazonaws.com
        Version: "2012-10-17"
      ManagedPolicyArns:
        - 'arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore'
        - 'arn:aws:iam::aws:policy/AmazonSSMDirectoryServiceAccess'
      RoleName: !Sub '${AWS::StackName}-iamrole'

  Ec2InstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Roles:
        - !Ref Ec2IamRole
# ------------------------------------------------------------#
#  EC2 Windows
# ------------------------------------------------------------#
  EC2Windows:
    DependsOn: FSx
    Type: AWS::EC2::Instance
    Properties:
      AvailabilityZone: !Select
        - 0
        - Fn::GetAZs: !Ref 'AWS::Region'
      ImageId: !Ref EC2ImageWindowsID
      IamInstanceProfile: !Ref Ec2InstanceProfile
      InstanceInitiatedShutdownBehavior: stop
      InstanceType: t2.micro
      KeyName: !Ref KeyName
      NetworkInterfaces:
        - AssociatePublicIpAddress: "true"
          DeviceIndex: "0"
          SubnetId: !Ref PublicSubnetA
          GroupSet:
            - !Ref Ec2SecurityGroup
      SsmAssociations:
        - AssociationParameters:
            - Key: directoryId
              Value:
                - !Ref MicrosoftAD
            - Key: directoryName
              Value:
                - !Ref MicrosoftAdDomainName
          DocumentName: AWS-JoinDirectoryServiceDomain
      Tags:
        - Key: Name
          Value: !Sub '${AWS::StackName}-windows'
        - Key: UserName
          Value: !Ref UserName
# ------------------------------------------------------------#
#  EC2 Linux
# ------------------------------------------------------------#
  EC2Linux:
    DependsOn: EC2Windows
    Type: AWS::EC2::Instance
    Properties:
      AvailabilityZone: !Select
        - 1
        - Fn::GetAZs: !Ref 'AWS::Region'
      ImageId: !Ref Ec2ImageAmazonlinuxId
      IamInstanceProfile: !Ref Ec2InstanceProfile
      InstanceInitiatedShutdownBehavior: stop
      InstanceType: t2.micro
      KeyName: !Ref KeyName
      NetworkInterfaces:
        - AssociatePublicIpAddress: "true"
          DeviceIndex: "0"
          SubnetId: !Ref PublicSubnetB
          GroupSet:
            - !Ref Ec2SecurityGroup
      Tags:
        - Key: Name
          Value: !Sub '${AWS::StackName}-linux'
        - Key: UserName
          Value: !Ref UserName

# ------------------------------------------------------------#
#  SG FSx
# ------------------------------------------------------------#
  FSXSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: !Sub '${AWS::StackName}-fsx-sg'
      GroupName: !Sub '${AWS::StackName}-fsx-sg'
      SecurityGroupEgress:
        - CidrIp: 0.0.0.0/0
          Description: Allow all outbound traffic by default
          IpProtocol: "-1"
      SecurityGroupIngress:
        - CidrIp: !GetAtt VPC.CidrBlock
          Description: allow all access from vpc
          IpProtocol: "-1"
      VpcId: !Ref VPC

# ------------------------------------------------------------#
#  FSx
# ------------------------------------------------------------#
  FSx:
    Type: AWS::FSx::FileSystem
    Properties:
      FileSystemType: WINDOWS
      SubnetIds:
        - !Ref PrivateSubnetC
        - !Ref PrivateSubnetD
      SecurityGroupIds:
        - !GetAtt FSXSecurityGroup.GroupId
      StorageCapacity: 32
      StorageType: SSD
      WindowsConfiguration:
        ActiveDirectoryId: !Ref MicrosoftAD
        AutomaticBackupRetentionDays: 0
        DeploymentType: MULTI_AZ_1
        PreferredSubnetId: !Ref PrivateSubnetC
        ThroughputCapacity: 8
      Tags:        
        - Key: UserName
          Value: !Ref UserName

1.3.テンプレート解説

1.3.1.MicrosoftAD

・DHCPオプションを作成して、ADを含むVPCにDHCPオプション設定を割り当てる。これによりVPC内のインスタンスで、指定のドメイン及びDNSサーバを参照してドメイン名を解決できるようになる。
参考:DHCP オプションセットの作成

# ------------------------------------------------------------#
#  MicrosoftAD
# ------------------------------------------------------------#        
  MicrosoftAD:
    Type: AWS::DirectoryService::MicrosoftAD
    Properties:
      Name: !Ref MicrosoftAdDomainName
      Password: !Ref MicrosoftAdPassword
      VpcSettings:
        SubnetIds:
          - !Ref PrivateSubnetA
          - !Ref PrivateSubnetB
        VpcId: !Ref VPC
      Edition: Standard

  DHCPOptions:
    Type: AWS::EC2::DHCPOptions
    Properties:
      DomainName: !Ref MicrosoftAdDomainName
      DomainNameServers: !GetAtt MicrosoftAD.DnsIpAddresses
      Tags:
        - Key: Name
          Value: !Sub '${AWS::StackName}-dhcp-options'

  VPCDHCPOptionsAssociation:
    Type: AWS::EC2::VPCDHCPOptionsAssociation
    Properties:
      DhcpOptionsId: !Ref DHCPOptions
      VpcId: !Ref VPC
1.3.2.EC2(Windows)

・EC2のロールにAmazonSSMManagedInstanceCore,AmazonSSMDirectoryServiceAccessを付与する。こちらのロールにより、EC2Windowsの項目にあるSsmAssociationsが実行できる。
SsmAssociationsにより、EC2インスタンス構築時にAWS Managed MicorsoftADに参加させることができる。
参考:Windows Server 用の EC2 インスタンスとドメインとのシームレス結合をテストする
※EC2はパブリックに配置しているので、InternetGatewayを経由してSSMへ通信を行う
・EC2のDependsOn: FSxは、構築直後AWS Managed MicorsoftADのステータスが「Impaired」の状態のため、順番を制御してステータスが変わるのを待つために記載する。

# ------------------------------------------------------------#
#  IAM EC2 Windows&Linux
# ------------------------------------------------------------#
  Ec2IamRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              Service: ec2.amazonaws.com
        Version: "2012-10-17"
      ManagedPolicyArns:
        - 'arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore'
        - 'arn:aws:iam::aws:policy/AmazonSSMDirectoryServiceAccess'
      RoleName: !Sub '${AWS::StackName}-iamrole'

  Ec2InstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Roles:
        - !Ref Ec2IamRole
# ------------------------------------------------------------#
#  EC2 Windows
# ------------------------------------------------------------#
  EC2Windows:
    DependsOn: FSx
    Type: AWS::EC2::Instance
    Properties:
      AvailabilityZone: !Select
        - 0
        - Fn::GetAZs: !Ref 'AWS::Region'
      ImageId: !Ref EC2ImageWindowsID
      IamInstanceProfile: !Ref Ec2InstanceProfile
      InstanceInitiatedShutdownBehavior: stop
      InstanceType: t2.micro
      KeyName: !Ref KeyName
      NetworkInterfaces:
        - AssociatePublicIpAddress: "true"
          DeviceIndex: "0"
          SubnetId: !Ref PublicSubnetA
          GroupSet:
            - !Ref Ec2SecurityGroup
      SsmAssociations:
        - AssociationParameters:
            - Key: directoryId
              Value:
                - !Ref MicrosoftAD
            - Key: directoryName
              Value:
                - !Ref MicrosoftAdDomainName
          DocumentName: AWS-JoinDirectoryServiceDomain
      Tags:
        - Key: Name
          Value: !Sub '${AWS::StackName}-windows'
        - Key: UserName
          Value: !Ref UserName

挙動の確認

1.EC2(Windows,Linux)のFSxマウント方法を確認

 1.1.マウント方法確認

FSx > アタッチを押下

 1.2.各種マウント方法確認

各種アタッチしたい方法選択する
今回は赤枠のWindowsの場合と、Linuxの2つを実施する

2.EC2(Windows)をFSxにマウント

2.1.EC2(Windows)のマウント方法確認

1.2.のWindowsのマウント方法を確認する

2.2.EC2(Windows)のマウントコマンド実施

EC2(Windows)にRDPしてコマンドプロンプトを開く
※EC2をパブリックサブネットに配置しているので、SSMを利用してフリートマネージャから実施可能

・ユーザ名:Admin@【ドメイン名】
・パスワード:MicrosoftAdPasswordで入力したパスワード

2.3.EC2(Windows)のマウント成功確認

ブラウザよりマウントされていることを確認できる

3.EC2(Linux)をFSxにマウント

3.1.EC2(Linux)のマウント方法確認

1.2.のLinuxのマウント方法を確認する

3.2.EC2(Linux)のマウントコマンド実施

EC2(Linux)にログインして、記載してあるコマンドを実施していく
※EC2をパブリックサブネットに配置しているので、SSMを利用してフリートマネージャから実施可能
cifs-utilsのインストール
mkdir /FSx を作成して、local_path部分を作成
user@DOMAIN部分は、Windowsと同様に Admin@【ドメイン名】
・パスワード:MicrosoftAdPasswordで入力したパスワード

【入力したコマンド】

sudo su -
sudo yum install cifs-utils
※インストール中に(y/n)は y を選択
mkdir /FSx
sudo mount -t cifs -o vers=3.0,sec=ntlmsspi,user=Adomin@【ドメイン名】 //192.168.50.155/share /FSx
3.3.EC2(linux)のマウント成功確認

dfコマンドで赤枠部分にマウントされていることが確認できる

4.ファイル共有の確認

4.1.EC2(Linux)でファイル作成


4.2.EC2(Windows)でファイルを確認する

EC2(Linux)で作成されたファイルが共有されていることを確認する


さいごに

さっくりできるものかと思っていましたが、EC2インスタンス構築時のMicrosoft ADに参加させる部分が、かなり分かっていなかったので理解が捗りました。
エラーへのアプローチも、記載しているテンプレート全てを実行して失敗を待つと検証するにも15分程度かかってしまうので、ネットワーク部分とEC2部分にテンプレートを分けたりして何がわかっていないのか?を炙り出すことで理解に至りました。

Last modified: 2023-05-07

Author