AWS CDKでAmazon FSx for NetApp ONTAPの構築をしてみた

Amazon FSx for NetApp ONTAPの構築はAWS CDKでもできらぁ!
2022.05.30

一撃でAmazon FSx for NetApp ONTAPを構築したいな

こんにちは、のんピ(@non____97)です。

皆さんはAmazon FSx for NetApp ONTAP(以降、FSx for ONTAP)を一撃で構築したいと思ったことはありますか? 私はあります。

今までFSx for ONTAPを構築する際は、AWSマネージメントコンソールやAWS CLIで行ってきました。

AWS CLIならまだしも、AWSマネージメントコンソールから構築するのは入力項目も多く結構大変です。

ということで、AWS CDKでFSx for ONTAPを構築してみます。

といっても、AWS CDKの2022/5/30時点最新バージョンの2.25.0ではFSx for ONTAPはL1 Constructしかありません。

そのため、ほぼCloudFormationのような感じですが、それもまた良いでしょう。

準備したコードは以下リポジトリに格納してあります。

やってみた

ドメイン情報をSecrets Managerに保存

FSx for ONTAPの構築の事前準備として、ドメイン情報をSecrets Managerに保存します。SVMがドメイン参加する際にこちらのシークレットを使います。

$ service_account_password='xxxx'
$ secret_json=$(cat <<EOM
{
  "domainName": "fsx-dev.classmethod.jp",
  "fileSystemAdministratorsGroup": "FSxAdminGroup",
  "organizationalUnitDistinguishedName": "OU=FSxForNetAppONTAP,DC=fsx-dev,DC=classmethod,DC=jp",
  "userName": "FSxServiceAccount",
  "password": "$service_account_password"
}
EOM
)

$ aws secretsmanager create-secret \
    --name "/fsx-dev.classmethod.jp/FSxForNetAppONTAP/ServiceAccount" \
    --secret-string "$secret_json"

AWS CDKでFSx for ONTAPのリソースをデプロイ

下準備が終わったらAWS CDKでFSx for ONTAPのリソースをデプロイします。

AWS CDKのディレクトリ構成は以下の通りです。

> tree
.
├── .gitignore
├── .npmignore
├── README.md
├── bin
│   └── fsx-for-ontap.ts
├── cdk.context.json
├── cdk.json
├── jest.config.js
├── lib
│   └── fsx-for-ontap-stack.ts
├── package-lock.json
├── package.json
├── test
│   └── fsx-for-ontap.test.ts
└── tsconfig.json

3 directories, 12 files

cdk.jsonでデプロイ先のVPCのIDや、DNSサーバーのIPアドレス、SVMのドメイン参加に必要な情報を保存されているシークレット名を入力しています。

./cdk.json

{
  "app": "npx ts-node --prefer-ts-exts bin/fsx-for-ontap.ts",
  "watch": {
    "include": [
      "**"
    ],
    "exclude": [
      "README.md",
      "cdk*.json",
      "**/*.d.ts",
      "**/*.js",
      "tsconfig.json",
      "package*.json",
      "yarn.lock",
      "node_modules",
      "test"
    ]
  },
  "context": {
    "vpcID": "vpc-0bdab140380e5888e",
    "dnsIPs": [
      "10.0.0.138"
    ],
    "serviceAccountSecretName": "/fsx-dev.classmethod.jp/FSxForNetAppONTAP/ServiceAccount",
    "@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": true,
    "@aws-cdk/core:stackRelativeExports": true,
    "@aws-cdk/aws-rds:lowercaseDbIdentifier": true,
    "@aws-cdk/aws-lambda:recognizeVersionProps": true,
    "@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": true,
    "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
    "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
    "@aws-cdk/core:checkSecretUsage": true,
    "@aws-cdk/aws-iam:minimizePolicies": true,
    "@aws-cdk/core:target-partitions": [
      "aws",
      "aws-cn"
    ]
  }
}

スタックは以下のように定義しました。セキュリティグループのルールはAWS公式ドキュメントを参考に、必要なポートを絞っています。

./lib/fsx-for-ontap-stack.ts

import {
  Stack,
  StackProps,
  CfnDynamicReference,
  CfnDynamicReferenceService,
  aws_ec2 as ec2,
  aws_secretsmanager as secretsmanager,
  aws_fsx as fsx,
} from "aws-cdk-lib";
import { Construct } from "constructs";

export class FsxForOntapStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    // Context
    const vpcId = this.node.tryGetContext("vpcID");
    const dnsIps = this.node.tryGetContext("dnsIPs");
    const serviceAccountSecretName = this.node.tryGetContext(
      "serviceAccountSecretName"
    );

    // VPC
    const vpc = ec2.Vpc.fromLookup(this, "VPC", {
      vpcId,
    });

    // ID of the isolated subnet where the FSx for ONTAP file system is to be deployed
    const isolatedSubnetIds = vpc.selectSubnets({
      subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
    }).subnetIds;
    if (isolatedSubnetIds.length < 2) return;

    // ID of Route Table used in VPC
    const routeTableIds = [
      ...new Set(
        [
          ...vpc.publicSubnets,
          ...vpc.privateSubnets,
          ...vpc.isolatedSubnets,
        ].map((subnet) => {
          return subnet.routeTable.routeTableId;
        })
      ),
    ];

    // Security Group used by FSx for ONTAP file system
    const fileSystemSecurityGroup = new ec2.SecurityGroup(
      this,
      "Security Group of FSx for ONTAP file system",
      {
        vpc,
      }
    );

    // Ref : https://docs.aws.amazon.com/fsx/latest/ONTAPGuide/limit-access-security-groups.html
    fileSystemSecurityGroup.addIngressRule(
      ec2.Peer.ipv4(vpc.vpcCidrBlock),
      ec2.Port.icmpPing(),
      "Pinging the instance"
    );
    fileSystemSecurityGroup.addIngressRule(
      ec2.Peer.ipv4(vpc.vpcCidrBlock),
      ec2.Port.tcp(22),
      "SSH access to the IP address of the cluster management LIF or a node management LIF"
    );
    fileSystemSecurityGroup.addIngressRule(
      ec2.Peer.ipv4(vpc.vpcCidrBlock),
      ec2.Port.tcp(111),
      "Remote procedure call for NFS"
    );
    fileSystemSecurityGroup.addIngressRule(
      ec2.Peer.ipv4(vpc.vpcCidrBlock),
      ec2.Port.tcp(135),
      "Remote procedure call for CIFS"
    );
    fileSystemSecurityGroup.addIngressRule(
      ec2.Peer.ipv4(vpc.vpcCidrBlock),
      ec2.Port.tcp(139),
      "NetBIOS service session for CIFS"
    );
    fileSystemSecurityGroup.addIngressRule(
      ec2.Peer.ipv4(vpc.vpcCidrBlock),
      ec2.Port.tcpRange(161, 162),
      "Simple network management protocol (SNMP)"
    );
    fileSystemSecurityGroup.addIngressRule(
      ec2.Peer.ipv4(vpc.vpcCidrBlock),
      ec2.Port.tcp(443),
      "ONTAP REST API access to the IP address of the cluster management LIF or an SVM management LIF"
    );
    fileSystemSecurityGroup.addIngressRule(
      ec2.Peer.ipv4(vpc.vpcCidrBlock),
      ec2.Port.tcp(445),
      "Microsoft SMB/CIFS over TCP with NetBIOS framing"
    );
    fileSystemSecurityGroup.addIngressRule(
      ec2.Peer.ipv4(vpc.vpcCidrBlock),
      ec2.Port.tcp(635),
      "NFS mount"
    );
    fileSystemSecurityGroup.addIngressRule(
      ec2.Peer.ipv4(vpc.vpcCidrBlock),
      ec2.Port.tcp(749),
      "Kerberos"
    );
    fileSystemSecurityGroup.addIngressRule(
      ec2.Peer.ipv4(vpc.vpcCidrBlock),
      ec2.Port.tcp(2049),
      "NFS server daemon"
    );
    fileSystemSecurityGroup.addIngressRule(
      ec2.Peer.ipv4(vpc.vpcCidrBlock),
      ec2.Port.tcp(3260),
      "iSCSI access through the iSCSI data LIF"
    );
    fileSystemSecurityGroup.addIngressRule(
      ec2.Peer.ipv4(vpc.vpcCidrBlock),
      ec2.Port.tcp(4045),
      "NFS lock daemon"
    );
    fileSystemSecurityGroup.addIngressRule(
      ec2.Peer.ipv4(vpc.vpcCidrBlock),
      ec2.Port.tcp(4046),
      "Network status monitor for NFS"
    );
    fileSystemSecurityGroup.addIngressRule(
      ec2.Peer.ipv4(vpc.vpcCidrBlock),
      ec2.Port.tcp(10000),
      "Network data management protocol (NDMP) and NetApp SnapMirror intercluster communication"
    );
    fileSystemSecurityGroup.addIngressRule(
      ec2.Peer.ipv4(vpc.vpcCidrBlock),
      ec2.Port.tcp(11104),
      "Management of NetApp SnapMirror intercluster communication"
    );
    fileSystemSecurityGroup.addIngressRule(
      ec2.Peer.ipv4(vpc.vpcCidrBlock),
      ec2.Port.tcp(11105),
      "SnapMirror data transfer using intercluster LIFs"
    );
    fileSystemSecurityGroup.addIngressRule(
      ec2.Peer.ipv4(vpc.vpcCidrBlock),
      ec2.Port.udp(111),
      "Remote procedure call for NFS"
    );
    fileSystemSecurityGroup.addIngressRule(
      ec2.Peer.ipv4(vpc.vpcCidrBlock),
      ec2.Port.udp(135),
      "Remote procedure call for CIFS"
    );
    fileSystemSecurityGroup.addIngressRule(
      ec2.Peer.ipv4(vpc.vpcCidrBlock),
      ec2.Port.udp(137),
      "NetBIOS name resolution for CIFS"
    );
    fileSystemSecurityGroup.addIngressRule(
      ec2.Peer.ipv4(vpc.vpcCidrBlock),
      ec2.Port.udp(139),
      "NetBIOS service session for CIFS"
    );
    fileSystemSecurityGroup.addIngressRule(
      ec2.Peer.ipv4(vpc.vpcCidrBlock),
      ec2.Port.udpRange(161, 162),
      "Simple network management protocol (SNMP)"
    );
    fileSystemSecurityGroup.addIngressRule(
      ec2.Peer.ipv4(vpc.vpcCidrBlock),
      ec2.Port.udp(635),
      "NFS mount"
    );
    fileSystemSecurityGroup.addIngressRule(
      ec2.Peer.ipv4(vpc.vpcCidrBlock),
      ec2.Port.udp(2049),
      "NFS server daemon"
    );
    fileSystemSecurityGroup.addIngressRule(
      ec2.Peer.ipv4(vpc.vpcCidrBlock),
      ec2.Port.udp(4045),
      "NFS lock daemon"
    );
    fileSystemSecurityGroup.addIngressRule(
      ec2.Peer.ipv4(vpc.vpcCidrBlock),
      ec2.Port.udp(4046),
      "Network status monitor for NFS"
    );
    fileSystemSecurityGroup.addIngressRule(
      ec2.Peer.ipv4(vpc.vpcCidrBlock),
      ec2.Port.udp(4049),
      "NFS quota protocol"
    );

    // Secret of FSx for ONTAP file system
    const fileSystemSecret = new secretsmanager.Secret(
      this,
      "Secret of FSx for ONTAP file system",
      {
        secretName: "/fsx-for-ontap/file-system",
        generateSecretString: {
          generateStringKey: "password",
          passwordLength: 32,
          requireEachIncludedType: true,
          secretStringTemplate: '{"userName": "fsxadmin"}',
        },
      }
    );

    // Secret of FSx for ONTAP SVM
    const svmSecret = new secretsmanager.Secret(
      this,
      "Secret of FSx for ONTAP SVM",
      {
        secretName: "/fsx-for-ontap/svm",
        generateSecretString: {
          generateStringKey: "password",
          passwordLength: 32,
          requireEachIncludedType: true,
          secretStringTemplate: '{"userName": "vsadmin"}',
        },
      }
    );

    // FSx for ONTAP file system
    const fsxForOntapFileSystem = new fsx.CfnFileSystem(
      this,
      "FSx for ONTAP file system",
      {
        fileSystemType: "ONTAP",
        subnetIds: isolatedSubnetIds,
        ontapConfiguration: {
          deploymentType: "MULTI_AZ_1",
          automaticBackupRetentionDays: 7,
          dailyAutomaticBackupStartTime: "16:00",
          diskIopsConfiguration: {
            mode: "AUTOMATIC",
          },
          endpointIpAddressRange: "172.31.255.0/24",
          fsxAdminPassword: new CfnDynamicReference(
            CfnDynamicReferenceService.SECRETS_MANAGER,
            `${fileSystemSecret.secretArn}:SecretString:password`
          ).toString(),
          preferredSubnetId: isolatedSubnetIds[0],
          routeTableIds: routeTableIds,
          throughputCapacity: 128,
          weeklyMaintenanceStartTime: "6:17:00",
        },
        securityGroupIds: [fileSystemSecurityGroup.securityGroupId],
        storageCapacity: 1024,
        storageType: "SSD",
        tags: [
          {
            key: "Name",
            value: "fsx-for-ontap-file-system-multi-az",
          },
        ],
      }
    );

    // FSx for ONTAP SVM
    const svmName = "fsx-for-ontap-svm-001";
    const svm = new fsx.CfnStorageVirtualMachine(this, "SVM", {
      fileSystemId: fsxForOntapFileSystem.ref,
      name: svmName,
      activeDirectoryConfiguration: {
        netBiosName: "SVM-001",
        selfManagedActiveDirectoryConfiguration: {
          dnsIps,
          domainName: new CfnDynamicReference(
            CfnDynamicReferenceService.SECRETS_MANAGER,
            `${serviceAccountSecretName}:SecretString:domainName`
          ).toString(),
          fileSystemAdministratorsGroup: new CfnDynamicReference(
            CfnDynamicReferenceService.SECRETS_MANAGER,
            `${serviceAccountSecretName}:SecretString:fileSystemAdministratorsGroup`
          ).toString(),
          organizationalUnitDistinguishedName: new CfnDynamicReference(
            CfnDynamicReferenceService.SECRETS_MANAGER,
            `${serviceAccountSecretName}:SecretString:organizationalUnitDistinguishedName`
          ).toString(),
          userName: new CfnDynamicReference(
            CfnDynamicReferenceService.SECRETS_MANAGER,
            `${serviceAccountSecretName}:SecretString:userName`
          ).toString(),
          password: new CfnDynamicReference(
            CfnDynamicReferenceService.SECRETS_MANAGER,
            `${serviceAccountSecretName}:SecretString:password`
          ).toString(),
        },
      },
      rootVolumeSecurityStyle: "MIXED",
      svmAdminPassword: new CfnDynamicReference(
        CfnDynamicReferenceService.SECRETS_MANAGER,
        `${svmSecret.secretArn}:SecretString:password`
      ).toString(),
      tags: [
        {
          key: "Name",
          value: svmName,
        },
      ],
    });

    // FSX for ONTAP volume
    const volumePrefix = "fsx_for_ontap_volume_";
    new fsx.CfnVolume(this, "NFS Volume", {
      name: `${volumePrefix}nfs`,
      ontapConfiguration: {
        junctionPath: "/nfs",
        sizeInMegabytes: "1024",
        storageEfficiencyEnabled: "true",
        storageVirtualMachineId: svm.ref,
        securityStyle: "UNIX",
        tieringPolicy: {
          coolingPeriod: 31,
          name: "AUTO",
        },
      },
      tags: [
        {
          key: "Name",
          value: `${volumePrefix}nfs`,
        },
      ],
      volumeType: "ONTAP",
    });

    new fsx.CfnVolume(this, "SMB Volume", {
      name: `${volumePrefix}smb`,
      ontapConfiguration: {
        junctionPath: "/smb",
        sizeInMegabytes: "1024",
        storageEfficiencyEnabled: "true",
        storageVirtualMachineId: svm.ref,
        securityStyle: "NTFS",
        tieringPolicy: {
          coolingPeriod: 31,
          name: "AUTO",
        },
      },
      tags: [
        {
          key: "Name",
          value: `${volumePrefix}smb`,
        },
      ],
      volumeType: "ONTAP",
    });

    new fsx.CfnVolume(this, "LUN Volume", {
      name: `${volumePrefix}lun`,
      ontapConfiguration: {
        junctionPath: "/lun",
        sizeInMegabytes: "1024",
        storageEfficiencyEnabled: "true",
        storageVirtualMachineId: svm.ref,
        securityStyle: "MIXED",
        tieringPolicy: {
          coolingPeriod: 31,
          name: "AUTO",
        },
      },
      tags: [
        {
          key: "Name",
          value: `${volumePrefix}lun`,
        },
      ],
      volumeType: "ONTAP",
    });
  }
}

注意すべきポイントはendpointIpAddressRangeの値です。VPC内に同じエンドポイントIPアドレス範囲を指定したFSx for ONTAPファイルシステムが存在している場合、以下のように作成に失敗します。

❌  FsxForOntapStack failed: Error: The stack named FsxForOntapStack failed creation, it may need to be manually deleted from the AWS console: ROLLBACK_COMPLETE: The EndpointIpAddressRange provided cannot overlap with the EndpointIpAddressRange of another file system that's associated with the same VPC route tables. (Service: AmazonFSx; Status Code: 400; Error Code: BadRequest; Request ID: 59c81279-fd8a-40c6-80e3-cd05ef0f969f; Proxy: null)
    at prepareAndExecuteChangeSet (/<ディレクトリパス>/node_modules/aws-cdk/lib/api/deploy-stack.ts:385:13)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
    at CdkToolkit.deploy (/<ディレクトリパス>/node_modules/aws-cdk/lib/cdk-toolkit.ts:209:24)
    at initCommandLine (/<ディレクトリパス>/node_modules/aws-cdk/lib/cli.ts:341:12)

The stack named FsxForOntapStack failed creation, it may need to be manually deleted from the AWS console: ROLLBACK_COMPLETE: The EndpointIpAddressRange provided cannot overlap with the EndpointIpAddressRange of another file system that's associated with the same VPC route tables. (Service: AmazonFSx; Status Code: 400; Error Code: BadRequest; Request ID: 59c81279-fd8a-40c6-80e3-cd05ef0f969f; Proxy: null)

後はnpx cdk deployでデプロイするだけです。

デプロイは40分程度で完了しました。

> npx cdk deploy
✨  Synthesis time: 46s

This deployment will make potentially sensitive changes according to your current security approval level (--require-approval broadening).
Please confirm you intend to make the following modifications:

Security Group Changes
┌───┬────────────────────────────────────────────────────────┬─────┬─────────────┬─────────────────┐
│   │ Group                                                  │ Dir │ Protocol    │ Peer            │
├───┼────────────────────────────────────────────────────────┼─────┼─────────────┼─────────────────┤
│ + │ ${Security Group of FSx for ONTAP file system.GroupId} │ In  │ ICMP 8--1   │ 10.0.0.0/16     │
│ + │ ${Security Group of FSx for ONTAP file system.GroupId} │ In  │ TCP 22      │ 10.0.0.0/16     │
│ + │ ${Security Group of FSx for ONTAP file system.GroupId} │ In  │ TCP 111     │ 10.0.0.0/16     │
│ + │ ${Security Group of FSx for ONTAP file system.GroupId} │ In  │ TCP 135     │ 10.0.0.0/16     │
│ + │ ${Security Group of FSx for ONTAP file system.GroupId} │ In  │ TCP 139     │ 10.0.0.0/16     │
│ + │ ${Security Group of FSx for ONTAP file system.GroupId} │ In  │ TCP 161-162 │ 10.0.0.0/16     │
│ + │ ${Security Group of FSx for ONTAP file system.GroupId} │ In  │ TCP 443     │ 10.0.0.0/16     │
│ + │ ${Security Group of FSx for ONTAP file system.GroupId} │ In  │ TCP 445     │ 10.0.0.0/16     │
│ + │ ${Security Group of FSx for ONTAP file system.GroupId} │ In  │ TCP 635     │ 10.0.0.0/16     │
│ + │ ${Security Group of FSx for ONTAP file system.GroupId} │ In  │ TCP 749     │ 10.0.0.0/16     │
│ + │ ${Security Group of FSx for ONTAP file system.GroupId} │ In  │ TCP 2049    │ 10.0.0.0/16     │
│ + │ ${Security Group of FSx for ONTAP file system.GroupId} │ In  │ TCP 3260    │ 10.0.0.0/16     │
│ + │ ${Security Group of FSx for ONTAP file system.GroupId} │ In  │ TCP 4045    │ 10.0.0.0/16     │
│ + │ ${Security Group of FSx for ONTAP file system.GroupId} │ In  │ TCP 4046    │ 10.0.0.0/16     │
│ + │ ${Security Group of FSx for ONTAP file system.GroupId} │ In  │ TCP 10000   │ 10.0.0.0/16     │
│ + │ ${Security Group of FSx for ONTAP file system.GroupId} │ In  │ TCP 11104   │ 10.0.0.0/16     │
│ + │ ${Security Group of FSx for ONTAP file system.GroupId} │ In  │ TCP 11105   │ 10.0.0.0/16     │
│ + │ ${Security Group of FSx for ONTAP file system.GroupId} │ In  │ UDP 111     │ 10.0.0.0/16     │
│ + │ ${Security Group of FSx for ONTAP file system.GroupId} │ In  │ UDP 135     │ 10.0.0.0/16     │
│ + │ ${Security Group of FSx for ONTAP file system.GroupId} │ In  │ UDP 137     │ 10.0.0.0/16     │
│ + │ ${Security Group of FSx for ONTAP file system.GroupId} │ In  │ UDP 139     │ 10.0.0.0/16     │
│ + │ ${Security Group of FSx for ONTAP file system.GroupId} │ In  │ UDP 161-162 │ 10.0.0.0/16     │
│ + │ ${Security Group of FSx for ONTAP file system.GroupId} │ In  │ UDP 635     │ 10.0.0.0/16     │
│ + │ ${Security Group of FSx for ONTAP file system.GroupId} │ In  │ UDP 2049    │ 10.0.0.0/16     │
│ + │ ${Security Group of FSx for ONTAP file system.GroupId} │ In  │ UDP 4045    │ 10.0.0.0/16     │
│ + │ ${Security Group of FSx for ONTAP file system.GroupId} │ In  │ UDP 4046    │ 10.0.0.0/16     │
│ + │ ${Security Group of FSx for ONTAP file system.GroupId} │ In  │ UDP 4049    │ 10.0.0.0/16     │
│ + │ ${Security Group of FSx for ONTAP file system.GroupId} │ Out │ Everything  │ Everyone (IPv4) │
└───┴────────────────────────────────────────────────────────┴─────┴─────────────┴─────────────────┘
(NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299)

Do you wish to deploy these changes (y/n)? y
FsxForOntapStack: deploying...
[0%] start: Publishing a2ee58e754aea9b8af7b0738a1e80528cb248dfad2f76f4fb662b1e22d6090e2:<AWSアカウントID>-ap-northeast-1
[100%] success: Published a2ee58e754aea9b8af7b0738a1e80528cb248dfad2f76f4fb662b1e22d6090e2:<AWSアカウントID>-ap-northeast-1
FsxForOntapStack: creating CloudFormation changeset...

 ✅  FsxForOntapStack

✨  Deployment time: 2432.95s

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:<AWSアカウントID>:stack/FsxForOntapStack/515270c0-dffd-11ec-9a7f-06d700fe3cbb

✨  Total time: 2478.95s

動作確認

SMB

デプロイが完了したら動作確認です。

まずはSMBでマウントできるか確認します。

# 現在のドライブ一覧を表示
> Get-PSDrive

Name           Used (GB)     Free (GB) Provider      Root                                               CurrentLocation
----           ---------     --------- --------      ----                                               ---------------
Alias                                  Alias
C                  14.44         15.56 FileSystem    C:\                                               Windows\system32
Cert                                   Certificate   \
D                   0.03          8.99 FileSystem    D:\
E                   0.03          8.99 FileSystem    E:\
Env                                    Environment
Function                               Function
HKCU                                   Registry      HKEY_CURRENT_USER
HKLM                                   Registry      HKEY_LOCAL_MACHINE
Variable                               Variable
WSMan                                  WSMan

# ZドライブにFSx for ONTAPのボリュームを割り当て
> net use Z: \\SVM-001.fsx-dev.classmethod.jp\C$\smb
'SVM-001.fsx-dev.classmethod.jp' のユーザー名を入力してください: fsx-dev.classmethod.jp\FSxAdmin
SVM-001.fsx-dev.classmethod.jp のパスワードを入力してください:
コマンドは正常に終了しました。

# Zドライブに割り当てられたことを確認
> Get-PSDrive

Name           Used (GB)     Free (GB) Provider      Root                                               CurrentLocation
----           ---------     --------- --------      ----                                               ---------------
Alias                                  Alias
C                  14.44         15.56 FileSystem    C:\                                               Windows\system32
Cert                                   Certificate   \
D                   0.03          8.99 FileSystem    D:\
E                   0.03          8.99 FileSystem    E:\
Env                                    Environment
Function                               Function
HKCU                                   Registry      HKEY_CURRENT_USER
HKLM                                   Registry      HKEY_LOCAL_MACHINE
Variable                               Variable
WSMan                                  WSMan
Z                   0.00          0.95 FileSystem    \\SVM-001.fsx-dev.classmethod.jp...

# Zドライブに任意のフォルダを作成できることを確認
> New-Item z:\smb-test -type directory


    ディレクトリ: Z:\


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----        2022/05/30      7:01                smb-test

できらぁ! ですね。

NFS

次に、NFSでマウントできるか確認します。

# 現在のディスクサイズ一覧を表示
$ df -h
Filesystem                                       Size  Used Avail Use% Mounted on
devtmpfs                                         462M     0  462M   0% /dev
tmpfs                                            470M     0  470M   0% /dev/shm
tmpfs                                            470M  456K  470M   1% /run
tmpfs                                            470M     0  470M   0% /sys/fs/cgroup
/dev/nvme0n1p1                                   8.0G  1.7G  6.4G  21% /
/dev/mapper/3600a09806c574231752b53784865462f1   2.0G  6.1M  1.8G   1% /lun/part1
/dev/mapper/3600a09806c574231752b537848654672p2  2.9G  9.1M  2.8G   1% /lun/part2

# マウントポイントがあることを確認
$ ls -ld /nfs
drwxr-xr-x 2 root root 6 May 25 00:26 /nfs

# マウント
$ sudo mount -t nfs svm-00af2acfe7a6961ce.fs-0d90252b98af4d11a.fsx.ap-northeast-1.amazonaws.com:/nfs /nfs

# マウントされたことを確認
$ df -hT
Filesystem                                                                       Type      Size  Used Avail Use% Mounted on
devtmpfs                                                                         devtmpfs  462M     0  462M   0% /dev
tmpfs                                                                            tmpfs     470M     0  470M   0% /dev/shm
tmpfs                                                                            tmpfs     470M  456K  470M   1% /run
tmpfs                                                                            tmpfs     470M     0  470M   0% /sys/fs/cgroup
/dev/nvme0n1p1                                                                   xfs       8.0G  1.7G  6.4G  21% /
/dev/mapper/3600a09806c574231752b53784865462f1                                   ext4      2.0G  6.1M  1.8G   1% /lun/part1
/dev/mapper/3600a09806c574231752b537848654672p2                                  ext4      2.9G  9.1M  2.8G   1% /lun/part2
svm-00af2acfe7a6961ce.fs-0d90252b98af4d11a.fsx.ap-northeast-1.amazonaws.com:/nfs nfs4      973M  256K  973M   1% /nfs

# 任意のファイルを作成できることを確認
$ sudo touch /nfs/nfs-test

$ ls -l /nfs
total 0
-rw-r--r-- 1 root root 0 May 30 07:05 nfs-test

こちらも できらぁ! ですね。

iSCSI LUN

最後にiSCSI LUNの動作確認です。

iSCSI LUNの詳細なマウント手順は以下記事をご覧ください。

上述の記事で検証したEC2インスタンスを再利用しているのでiscsidmultipathdは既に起動した状態です。

# ブロックデバイス一覧を確認
$ lsblk
NAME                                    MAJ:MIN RM SIZE RO TYPE  MOUNTPOINT
sda                                       8:0    0  10G  0 disk
└─3600a09806c574231752b53784865462f     253:1    0  10G  0 mpath
  ├─3600a09806c574231752b53784865462f1  253:2    0   2G  0 part  /lun/part1
  └─3600a09806c574231752b53784865462f2  253:4    0   3G  0 part
sdb                                       8:16   0  10G  0 disk
└─3600a09806c574231752b537848654672     253:0    0  10G  0 mpath
  ├─3600a09806c574231752b537848654672p1 253:3    0   2G  0 part
  └─3600a09806c574231752b537848654672p2 253:5    0   3G  0 part  /lun/part2
sdc                                       8:32   0  10G  0 disk
└─3600a09806c574231752b53784865462f     253:1    0  10G  0 mpath
  ├─3600a09806c574231752b53784865462f1  253:2    0   2G  0 part  /lun/part1
  └─3600a09806c574231752b53784865462f2  253:4    0   3G  0 part
sdd                                       8:48   0  10G  0 disk
└─3600a09806c574231752b53784865462f     253:1    0  10G  0 mpath
  ├─3600a09806c574231752b53784865462f1  253:2    0   2G  0 part  /lun/part1
  └─3600a09806c574231752b53784865462f2  253:4    0   3G  0 part
sde                                       8:64   0  10G  0 disk
└─3600a09806c574231752b537848654672     253:0    0  10G  0 mpath
  ├─3600a09806c574231752b537848654672p1 253:3    0   2G  0 part
  └─3600a09806c574231752b537848654672p2 253:5    0   3G  0 part  /lun/part2
sdf                                       8:80   0  10G  0 disk
└─3600a09806c574231752b537848654672     253:0    0  10G  0 mpath
  ├─3600a09806c574231752b537848654672p1 253:3    0   2G  0 part
  └─3600a09806c574231752b537848654672p2 253:5    0   3G  0 part  /lun/part2
sdg                                       8:96   0  10G  0 disk
└─3600a09806c574231752b53784865462f     253:1    0  10G  0 mpath
  ├─3600a09806c574231752b53784865462f1  253:2    0   2G  0 part  /lun/part1
  └─3600a09806c574231752b53784865462f2  253:4    0   3G  0 part
sdh                                       8:112  0  10G  0 disk
└─3600a09806c574231752b537848654672     253:0    0  10G  0 mpath
  ├─3600a09806c574231752b537848654672p1 253:3    0   2G  0 part
  └─3600a09806c574231752b537848654672p2 253:5    0   3G  0 part  /lun/part2
sdi                                       8:128  0  10G  0 disk
└─3600a09806c574231752b53784865462f     253:1    0  10G  0 mpath
  ├─3600a09806c574231752b53784865462f1  253:2    0   2G  0 part  /lun/part1
  └─3600a09806c574231752b53784865462f2  253:4    0   3G  0 part
sdj                                       8:144  0  10G  0 disk
└─3600a09806c574231752b537848654672     253:0    0  10G  0 mpath
  ├─3600a09806c574231752b537848654672p1 253:3    0   2G  0 part
  └─3600a09806c574231752b537848654672p2 253:5    0   3G  0 part  /lun/part2
sdk                                       8:160  0  10G  0 disk
└─3600a09806c574231752b53784865462f     253:1    0  10G  0 mpath
  ├─3600a09806c574231752b53784865462f1  253:2    0   2G  0 part  /lun/part1
  └─3600a09806c574231752b53784865462f2  253:4    0   3G  0 part
sdl                                       8:176  0  10G  0 disk
└─3600a09806c574231752b53784865462f     253:1    0  10G  0 mpath
  ├─3600a09806c574231752b53784865462f1  253:2    0   2G  0 part  /lun/part1
  └─3600a09806c574231752b53784865462f2  253:4    0   3G  0 part
sdm                                       8:192  0  10G  0 disk
└─3600a09806c574231752b53784865462f     253:1    0  10G  0 mpath
  ├─3600a09806c574231752b53784865462f1  253:2    0   2G  0 part  /lun/part1
  └─3600a09806c574231752b53784865462f2  253:4    0   3G  0 part
sdn                                       8:208  0  10G  0 disk
└─3600a09806c574231752b537848654672     253:0    0  10G  0 mpath
  ├─3600a09806c574231752b537848654672p1 253:3    0   2G  0 part
  └─3600a09806c574231752b537848654672p2 253:5    0   3G  0 part  /lun/part2
sdo                                       8:224  0  10G  0 disk
└─3600a09806c574231752b537848654672     253:0    0  10G  0 mpath
  ├─3600a09806c574231752b537848654672p1 253:3    0   2G  0 part
  └─3600a09806c574231752b537848654672p2 253:5    0   3G  0 part  /lun/part2
sdp                                       8:240  0  10G  0 disk
└─3600a09806c574231752b537848654672     253:0    0  10G  0 mpath
  ├─3600a09806c574231752b537848654672p1 253:3    0   2G  0 part
  └─3600a09806c574231752b537848654672p2 253:5    0   3G  0 part  /lun/part2
nvme0n1                                 259:0    0   8G  0 disk
├─nvme0n1p1                             259:1    0   8G  0 part  /
└─nvme0n1p128                           259:2    0   1M  0 part

# イニシエーター名を確認
$ sudo cat /etc/iscsi/initiatorname.iscsi
InitiatorName=iqn.1994-05.com.redhat:2cc274f1146

# FSx for ONTAPファイルシステムにSSH
$ ssh fsxadmin@management.fs-0d90252b98af4d11a.fsx.ap-northeast-1.amazonaws.com
Password:

This is your first recorded login.

# LUNが存在しないことを確認
::> lun show
This table is currently empty.

# LUNの作成
::> lun create -path /vol/fsx_for_ontap_volume_lun/linux_lun -size 500M -ostype linux -space-allocation enabled

Created a LUN of size 500m (524288000)

# LUNが作成されたことを確認
::> lun show
Vserver   Path                            State   Mapped   Type        Size
--------- ------------------------------- ------- -------- -------- --------
fsx-for-ontap-svm-001
          /vol/fsx_for_ontap_volume_lun/linux_lun
                                          online  unmapped linux       500MB

# イニシエーターグループが存在しないことを確認
::> lun igroup show
This table is currently empty.

# イニシエーターグループを作成
::> lun igroup create -igroup igroup_linux -initiator iqn.1994-05.com.redhat:2cc274f1146 -protocol iscsi -ostype linux

# イニシエーターグループが作成されたことを確認
::> lun igroup show
Vserver   Igroup       Protocol OS Type  Initiators
--------- ------------ -------- -------- ------------------------------------
fsx-for-ontap-svm-001
          igroup_linux iscsi    linux    iqn.1994-05.com.redhat:2cc274f1146

# LUNとイニシエターグループをマッピング
::> lun mapping create -path /vol/fsx_for_ontap_volume_lun/linux_lun -igroup igroup_linux -lun-id 001

# LUNとイニシエーターグループがマッピングされたことを確認
::> lun mapping show
Vserver    Path                                      Igroup   LUN ID  Protocol
---------- ----------------------------------------  -------  ------  --------
fsx-for-ontap-svm-001
           /vol/fsx_for_ontap_volume_lun/linux_lun   igroup_linux  1  iscsi


# iSCSIのIPアドレス確認
::> network interface show
            Logical    Status     Network            Current       Current Is
Vserver     Interface  Admin/Oper Address/Mask       Node          Port    Home
----------- ---------- ---------- ------------------ ------------- ------- ----
FsxId0d90252b98af4d11a
            fsxadmin     up/up    172.31.255.189/24  FsxId0d90252b98af4d11a-01
                                                                   e0e     true
            inter_1      up/up    10.0.10.6/24       FsxId0d90252b98af4d11a-01
                                                                   e0e     true
            inter_2      up/up    10.0.11.36/24      FsxId0d90252b98af4d11a-02
                                                                   e0e     true
fsx-for-ontap-svm-001
            iscsi_1      up/up    10.0.10.71/24      FsxId0d90252b98af4d11a-01
                                                                   e0e     true
            iscsi_2      up/up    10.0.11.80/24      FsxId0d90252b98af4d11a-02
                                                                   e0e     true
            nfs_smb_management_1
                         up/up    172.31.255.89/24   FsxId0d90252b98af4d11a-01
                                                                   e0e     true
6 entries were displayed.

# FSx for ONTAPファイルシステムからログアウト
::> exit
Goodbye


Connection to management.fs-0d90252b98af4d11a.fsx.ap-northeast-1.amazonaws.com closed.

# ターゲットiSCSIノードを検出
$ sudo iscsiadm --mode discovery --op update --type sendtargets --portal 10.0.10.71
10.0.10.71:3260,1030 iqn.1992-08.com.netapp:sn.0c4b075ddfe311ec8ac8ef02e5fc9591:vs.4
10.0.11.80:3260,1028 iqn.1992-08.com.netapp:sn.0c4b075ddfe311ec8ac8ef02e5fc9591:vs.4

# 各AZのONTAPノードごとにイニシエータあたり4つのセッションを確立し、EC2インスタンスが帯域幅制限の5Gb/sを超えて最大20Gb/sでiSCSI LUN接続できるように設定
$ sudo iscsiadm --mode node -T iqn.1992-08.com.netapp:sn.0c4b075ddfe311ec8ac8ef02e5fc9591:vs.4 --op update -n node.session.nr_sessions -v 4

# ターゲットiSCSIノードにログイン
$ sudo iscsiadm --mode node -T iqn.1992-08.com.netapp:sn.0c4b075ddfe311ec8ac8ef02e5fc9591:vs.4 --login
Logging in to [iface: default, target: iqn.1992-08.com.netapp:sn.0c4b075ddfe311ec8ac8ef02e5fc9591:vs.4, portal: 10.0.10.71,3260] (multiple)
Logging in to [iface: default, target: iqn.1992-08.com.netapp:sn.0c4b075ddfe311ec8ac8ef02e5fc9591:vs.4, portal: 10.0.10.71,3260] (multiple)
Logging in to [iface: default, target: iqn.1992-08.com.netapp:sn.0c4b075ddfe311ec8ac8ef02e5fc9591:vs.4, portal: 10.0.10.71,3260] (multiple)
Logging in to [iface: default, target: iqn.1992-08.com.netapp:sn.0c4b075ddfe311ec8ac8ef02e5fc9591:vs.4, portal: 10.0.10.71,3260] (multiple)
Logging in to [iface: default, target: iqn.1992-08.com.netapp:sn.0c4b075ddfe311ec8ac8ef02e5fc9591:vs.4, portal: 10.0.11.80,3260] (multiple)
Logging in to [iface: default, target: iqn.1992-08.com.netapp:sn.0c4b075ddfe311ec8ac8ef02e5fc9591:vs.4, portal: 10.0.11.80,3260] (multiple)
Logging in to [iface: default, target: iqn.1992-08.com.netapp:sn.0c4b075ddfe311ec8ac8ef02e5fc9591:vs.4, portal: 10.0.11.80,3260] (multiple)
Logging in to [iface: default, target: iqn.1992-08.com.netapp:sn.0c4b075ddfe311ec8ac8ef02e5fc9591:vs.4, portal: 10.0.11.80,3260] (multiple)
Login to [iface: default, target: iqn.1992-08.com.netapp:sn.0c4b075ddfe311ec8ac8ef02e5fc9591:vs.4, portal: 10.0.10.71,3260] successful.
Login to [iface: default, target: iqn.1992-08.com.netapp:sn.0c4b075ddfe311ec8ac8ef02e5fc9591:vs.4, portal: 10.0.10.71,3260] successful.
Login to [iface: default, target: iqn.1992-08.com.netapp:sn.0c4b075ddfe311ec8ac8ef02e5fc9591:vs.4, portal: 10.0.10.71,3260] successful.
Login to [iface: default, target: iqn.1992-08.com.netapp:sn.0c4b075ddfe311ec8ac8ef02e5fc9591:vs.4, portal: 10.0.10.71,3260] successful.
Login to [iface: default, target: iqn.1992-08.com.netapp:sn.0c4b075ddfe311ec8ac8ef02e5fc9591:vs.4, portal: 10.0.11.80,3260] successful.
Login to [iface: default, target: iqn.1992-08.com.netapp:sn.0c4b075ddfe311ec8ac8ef02e5fc9591:vs.4, portal: 10.0.11.80,3260] successful.
Login to [iface: default, target: iqn.1992-08.com.netapp:sn.0c4b075ddfe311ec8ac8ef02e5fc9591:vs.4, portal: 10.0.11.80,3260] successful.
Login to [iface: default, target: iqn.1992-08.com.netapp:sn.0c4b075ddfe311ec8ac8ef02e5fc9591:vs.4, portal: 10.0.11.80,3260] successful.

# マルチパスが設定されていることを確認
$ sudo multipath -ll
3600a09806c574231752b53784865462f dm-1 NETAPP  ,LUN C-Mode
size=10G features='4 queue_if_no_path pg_init_retries 50 retain_attached_hw_handle' hwhandler='0' wp=rw
|-+- policy='service-time 0' prio=50 status=active
| |- 1:0:0:1  sdc     8:32   active ready running
| |- 3:0:0:1  sdg     8:96   active ready running
| |- 2:0:0:1  sdd     8:48   active ready running
| `- 0:0:0:1  sda     8:0    active ready running
`-+- policy='service-time 0' prio=10 status=enabled
  |- 4:0:0:1  sdi     8:128  active ready running
  |- 6:0:0:1  sdk     8:160  active ready running
  |- 7:0:0:1  sdm     8:192  active ready running
  `- 5:0:0:1  sdl     8:176  active ready running
3600a09806c574231752b537848654672 dm-0 NETAPP  ,LUN C-Mode
size=10G features='4 queue_if_no_path pg_init_retries 50 retain_attached_hw_handle' hwhandler='0' wp=rw
|-+- policy='service-time 0' prio=50 status=active
| |- 0:0:0:3  sdb     8:16   active ready running
| |- 1:0:0:3  sde     8:64   active ready running
| |- 3:0:0:3  sdh     8:112  active ready running
| `- 2:0:0:3  sdf     8:80   active ready running
`-+- policy='service-time 0' prio=10 status=enabled
  |- 4:0:0:3  sdj     8:144  active ready running
  |- 6:0:0:3  sdn     8:208  active ready running
  |- 7:0:0:3  sdp     8:240  active ready running
  `- 5:0:0:3  sdo     8:224  active ready running
3600a09806c5742303424543070506c4c dm-6 NETAPP  ,LUN C-Mode
size=500M features='4 queue_if_no_path pg_init_retries 50 retain_attached_hw_handle' hwhandler='0' wp=rw
|-+- policy='service-time 0' prio=50 status=active
| |- 11:0:0:1 sdt     65:48  active ready running
| |- 8:0:0:1  sdq     65:0   active ready running
| |- 9:0:0:1  sdr     65:16  active ready running
| `- 10:0:0:1 sds     65:32  active ready running
`-+- policy='service-time 0' prio=10 status=enabled
  |- 14:0:0:1 sdu     65:64  active ready running
  |- 13:0:0:1 sdw     65:96  active ready running
  |- 12:0:0:1 sdv     65:80  active ready running
  `- 15:0:0:1 sdx     65:112 active ready running

# ブロックデバイスとして認識されていることを確認
$ lsblk
NAME                                    MAJ:MIN RM  SIZE RO TYPE  MOUNTPOINT
sda                                       8:0    0   10G  0 disk
└─3600a09806c574231752b53784865462f     253:1    0   10G  0 mpath
  ├─3600a09806c574231752b53784865462f1  253:2    0    2G  0 part  /lun/part1
  └─3600a09806c574231752b53784865462f2  253:4    0    3G  0 part
sdb                                       8:16   0   10G  0 disk
└─3600a09806c574231752b537848654672     253:0    0   10G  0 mpath
  ├─3600a09806c574231752b537848654672p1 253:3    0    2G  0 part
  └─3600a09806c574231752b537848654672p2 253:5    0    3G  0 part  /lun/part2
sdc                                       8:32   0   10G  0 disk
└─3600a09806c574231752b53784865462f     253:1    0   10G  0 mpath
  ├─3600a09806c574231752b53784865462f1  253:2    0    2G  0 part  /lun/part1
  └─3600a09806c574231752b53784865462f2  253:4    0    3G  0 part
sdd                                       8:48   0   10G  0 disk
└─3600a09806c574231752b53784865462f     253:1    0   10G  0 mpath
  ├─3600a09806c574231752b53784865462f1  253:2    0    2G  0 part  /lun/part1
  └─3600a09806c574231752b53784865462f2  253:4    0    3G  0 part
sde                                       8:64   0   10G  0 disk
└─3600a09806c574231752b537848654672     253:0    0   10G  0 mpath
  ├─3600a09806c574231752b537848654672p1 253:3    0    2G  0 part
  └─3600a09806c574231752b537848654672p2 253:5    0    3G  0 part  /lun/part2
sdf                                       8:80   0   10G  0 disk
└─3600a09806c574231752b537848654672     253:0    0   10G  0 mpath
  ├─3600a09806c574231752b537848654672p1 253:3    0    2G  0 part
  └─3600a09806c574231752b537848654672p2 253:5    0    3G  0 part  /lun/part2
sdg                                       8:96   0   10G  0 disk
└─3600a09806c574231752b53784865462f     253:1    0   10G  0 mpath
  ├─3600a09806c574231752b53784865462f1  253:2    0    2G  0 part  /lun/part1
  └─3600a09806c574231752b53784865462f2  253:4    0    3G  0 part
sdh                                       8:112  0   10G  0 disk
└─3600a09806c574231752b537848654672     253:0    0   10G  0 mpath
  ├─3600a09806c574231752b537848654672p1 253:3    0    2G  0 part
  └─3600a09806c574231752b537848654672p2 253:5    0    3G  0 part  /lun/part2
sdi                                       8:128  0   10G  0 disk
└─3600a09806c574231752b53784865462f     253:1    0   10G  0 mpath
  ├─3600a09806c574231752b53784865462f1  253:2    0    2G  0 part  /lun/part1
  └─3600a09806c574231752b53784865462f2  253:4    0    3G  0 part
sdj                                       8:144  0   10G  0 disk
└─3600a09806c574231752b537848654672     253:0    0   10G  0 mpath
  ├─3600a09806c574231752b537848654672p1 253:3    0    2G  0 part
  └─3600a09806c574231752b537848654672p2 253:5    0    3G  0 part  /lun/part2
sdk                                       8:160  0   10G  0 disk
└─3600a09806c574231752b53784865462f     253:1    0   10G  0 mpath
  ├─3600a09806c574231752b53784865462f1  253:2    0    2G  0 part  /lun/part1
  └─3600a09806c574231752b53784865462f2  253:4    0    3G  0 part
sdl                                       8:176  0   10G  0 disk
└─3600a09806c574231752b53784865462f     253:1    0   10G  0 mpath
  ├─3600a09806c574231752b53784865462f1  253:2    0    2G  0 part  /lun/part1
  └─3600a09806c574231752b53784865462f2  253:4    0    3G  0 part
sdm                                       8:192  0   10G  0 disk
└─3600a09806c574231752b53784865462f     253:1    0   10G  0 mpath
  ├─3600a09806c574231752b53784865462f1  253:2    0    2G  0 part  /lun/part1
  └─3600a09806c574231752b53784865462f2  253:4    0    3G  0 part
sdn                                       8:208  0   10G  0 disk
└─3600a09806c574231752b537848654672     253:0    0   10G  0 mpath
  ├─3600a09806c574231752b537848654672p1 253:3    0    2G  0 part
  └─3600a09806c574231752b537848654672p2 253:5    0    3G  0 part  /lun/part2
sdo                                       8:224  0   10G  0 disk
└─3600a09806c574231752b537848654672     253:0    0   10G  0 mpath
  ├─3600a09806c574231752b537848654672p1 253:3    0    2G  0 part
  └─3600a09806c574231752b537848654672p2 253:5    0    3G  0 part  /lun/part2
sdp                                       8:240  0   10G  0 disk
└─3600a09806c574231752b537848654672     253:0    0   10G  0 mpath
  ├─3600a09806c574231752b537848654672p1 253:3    0    2G  0 part
  └─3600a09806c574231752b537848654672p2 253:5    0    3G  0 part  /lun/part2
sdq                                      65:0    0  500M  0 disk
└─3600a09806c5742303424543070506c4c     253:6    0  500M  0 mpath
sdr                                      65:16   0  500M  0 disk
└─3600a09806c5742303424543070506c4c     253:6    0  500M  0 mpath
sds                                      65:32   0  500M  0 disk
└─3600a09806c5742303424543070506c4c     253:6    0  500M  0 mpath
sdt                                      65:48   0  500M  0 disk
└─3600a09806c5742303424543070506c4c     253:6    0  500M  0 mpath
sdu                                      65:64   0  500M  0 disk
└─3600a09806c5742303424543070506c4c     253:6    0  500M  0 mpath
sdv                                      65:80   0  500M  0 disk
└─3600a09806c5742303424543070506c4c     253:6    0  500M  0 mpath
sdw                                      65:96   0  500M  0 disk
└─3600a09806c5742303424543070506c4c     253:6    0  500M  0 mpath
sdx                                      65:112  0  500M  0 disk
└─3600a09806c5742303424543070506c4c     253:6    0  500M  0 mpath
nvme0n1                                 259:0    0    8G  0 disk
├─nvme0n1p1                             259:1    0    8G  0 part  /
└─nvme0n1p128                           259:2    0    1M  0 part

# パーティション分割
$ sudo parted /dev/mapper/3600a09806c5742303424543070506c4c
GNU Parted 3.1
Using /dev/mapper/3600a09806c5742303424543070506c4c
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) help
  align-check TYPE N                        check partition N for TYPE(min|opt) alignment
  help [COMMAND]                           print general help, or help on COMMAND
  mklabel,mktable LABEL-TYPE               create a new disklabel (partition table)
  mkpart PART-TYPE [FS-TYPE] START END     make a partition
  name NUMBER NAME                         name partition NUMBER as NAME
  print [devices|free|list,all|NUMBER]     display the partition table, available devices, free space, all found partitions, or a particular partition
  quit                                     exit program
  rescue START END                         rescue a lost partition near START and END

  resizepart NUMBER END                    resize partition NUMBER
  rm NUMBER                                delete partition NUMBER
  select DEVICE                            choose the device to edit
  disk_set FLAG STATE                      change the FLAG on selected device
  disk_toggle [FLAG]                       toggle the state of FLAG on selected device
  set NUMBER FLAG STATE                    change the FLAG on partition NUMBER
  toggle [NUMBER [FLAG]]                   toggle the state of FLAG on partition NUMBER
  unit UNIT                                set the default unit to UNIT
  version                                  display the version number and copyright information of GNU Parted
(parted)
(parted) print
Error: /dev/mapper/3600a09806c5742303424543070506c4c: unrecognised disk label
Model: Linux device-mapper (multipath) (dm)
Disk /dev/mapper/3600a09806c5742303424543070506c4c: 524MB
Sector size (logical/physical): 512B/4096B
Partition Table: unknown
Disk Flags:
(parted)
(parted) mklabel gpt
(parted) mkpart
Partition name?  []? part1
File system type?  [ext2]?
Start? 0%
End? 40%
(parted) print
Model: Linux device-mapper (multipath) (dm)
Disk /dev/mapper/3600a09806c5742303424543070506c4c: 524MB
Sector size (logical/physical): 512B/4096B
Partition Table: gpt
Disk Flags:

Number  Start   End    Size   File system  Name   Flags
 1      1049kB  210MB  209MB               part1

(parted)
(parted) help mkpart
  mkpart PART-TYPE [FS-TYPE] START END     make a partition

	PART-TYPE is one of: primary, logical, extended
        FS-TYPE is one of: btrfs, nilfs2, ext4, ext3, ext2, fat32, fat16, hfsx, hfs+, hfs, jfs, swsusp, linux-swap(v1), linux-swap(v0), ntfs, reiserfs, hp-ufs, sun-ufs, xfs, apfs2, apfs1, asfs, amufs5, amufs4, amufs3,
        amufs2, amufs1, amufs0, amufs, affs7, affs6, affs5, affs4, affs3, affs2, affs1, affs0, linux-swap, linux-swap(new), linux-swap(old)
        START and END are disk locations, such as 4GB or 10%.  Negative values count from the end of the disk.  For example, -1s specifies exactly the last sector.

        'mkpart' makes a partition without creating a new file system on the partition.  FS-TYPE may be specified to set an appropriate partition ID.
(parted)
(parted) mkpart part2 40% 70%
(parted) print
Model: Linux device-mapper (multipath) (dm)
Disk /dev/mapper/3600a09806c5742303424543070506c4c: 524MB
Sector size (logical/physical): 512B/4096B
Partition Table: gpt
Disk Flags:

Number  Start   End    Size   File system  Name   Flags
 1      1049kB  210MB  209MB               part1
 2      210MB   367MB  157MB               part2

(parted) quit
Information: You may need to update /etc/fstab.

# パーティション分割されたことを確認
$ lsblk /dev/mapper/3600a09806c5742303424543070506c4c
NAME                                 MAJ:MIN RM  SIZE RO TYPE  MOUNTPOINT
3600a09806c5742303424543070506c4c    253:6    0  500M  0 mpath
├─3600a09806c5742303424543070506c4c1 253:7    0  199M  0 part
└─3600a09806c5742303424543070506c4c2 253:8    0  150M  0 part

# xfsでファイルシステムを作成
$ sudo mkfs.xfs /dev/mapper/3600a09806c5742303424543070506c4c1
meta-data=/dev/mapper/3600a09806c5742303424543070506c4c1 isize=512    agcount=4, agsize=12736 blks
         =                       sectsz=4096  attr=2, projid32bit=1
         =                       crc=1        finobt=1, sparse=0
data     =                       bsize=4096   blocks=50944, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal log           bsize=4096   blocks=1605, version=2
         =                       sectsz=4096  sunit=1 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0

$ sudo mkfs.xfs /dev/mapper/3600a09806c5742303424543070506c4c2
meta-data=/dev/mapper/3600a09806c5742303424543070506c4c2 isize=512    agcount=4, agsize=9600 blks
         =                       sectsz=4096  attr=2, projid32bit=1
         =                       crc=1        finobt=1, sparse=0
data     =                       bsize=4096   blocks=38400, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal log           bsize=4096   blocks=1605, version=2
         =                       sectsz=4096  sunit=1 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0

# ファイルシステムが "xfs" であることを確認
$ lsblk -fip /dev/mapper/3600a09806c5742303424543070506c4c
NAME                                             FSTYPE LABEL UUID                                 MOUNTPOINT
/dev/mapper/3600a09806c5742303424543070506c4c
|-/dev/mapper/3600a09806c5742303424543070506c4c1 xfs          e17ed9f0-c478-4728-9c00-00efc8326b15
`-/dev/mapper/3600a09806c5742303424543070506c4c2 xfs          09002dde-3f19-4176-9dee-4554edae5478

# マウントポイントを作成
$ sudo mkdir -p /lun/xfs/part1
$ sudo mkdir /lun/xfs/part2

$ ls -l /lun/
total 8
drwxr-xr-x 4 ssm-user ssm-user 4096 May 25 00:35 part1
drwxr-xr-x 3 ssm-user ssm-user 4096 May 20 03:12 part2
drwxr-xr-x 4 root     root       32 May 30 07:44 xfs

# マウントポイントの上位ディレクトリの所有者変更
$ sudo chown ssm-user:ssm-user /lun/xfs

$ ls -l /lun/
total 8
drwxr-xr-x 4 ssm-user ssm-user 4096 May 25 00:35 part1
drwxr-xr-x 3 ssm-user ssm-user 4096 May 20 03:12 part2
drwxr-xr-x 4 ssm-user ssm-user   32 May 30 07:44 xfs

# マウント
$ sudo mount -t xfs /dev/mapper/3600a09806c5742303424543070506c4c1 /lun/xfs/part1
$ sudo mount -t xfs /dev/mapper/3600a09806c5742303424543070506c4c2 /lun/xfs/part2

# マウントできたことを確認
$ df -hT
Filesystem                                                                       Type      Size  Used Avail Use% Mounted on
devtmpfs                                                                         devtmpfs  462M     0  462M   0% /dev
tmpfs                                                                            tmpfs     470M     0  470M   0% /dev/shm
tmpfs                                                                            tmpfs     470M  676K  470M   1% /run
tmpfs                                                                            tmpfs     470M     0  470M   0% /sys/fs/cgroup
/dev/nvme0n1p1                                                                   xfs       8.0G  1.7G  6.4G  21% /
/dev/mapper/3600a09806c574231752b53784865462f1                                   ext4      2.0G  6.1M  1.8G   1% /lun/part1
/dev/mapper/3600a09806c574231752b537848654672p2                                  ext4      2.9G  9.1M  2.8G   1% /lun/part2
svm-00af2acfe7a6961ce.fs-0d90252b98af4d11a.fsx.ap-northeast-1.amazonaws.com:/nfs nfs4      973M  320K  973M   1% /nfs
/dev/mapper/3600a09806c5742303424543070506c4c1                                   xfs       193M   11M  183M   6% /lun/xfs/part1
/dev/mapper/3600a09806c5742303424543070506c4c2                                   xfs       144M  8.0M  136M   6% /lun/xfs/part2

# 任意のファイルを作成できることを確認
$ sudo touch /lun/xfs/part1/lun-test
$ sudo touch /lun/xfs/part2/lun-test

$ ls -lR /lun/xfs
/lun/xfs:
total 0
drwxr-xr-x 2 root root 22 May 30 07:47 part1
drwxr-xr-x 2 root root 22 May 30 07:48 part2

/lun/xfs/part1:
total 0
-rw-r--r-- 1 root root 0 May 30 07:47 lun-test

/lun/xfs/part2:
total 0
-rw-r--r-- 1 root root 0 May 30 07:48 lun-test

こちらも できらぁ! ですね。

できらぁ!

AWS CDKでAmazon FSx for NetApp ONTAPの構築をしてみました。

L1 Constructしかなくてもエディターの補完機能がとてつもなく効くので、CloudFormationのテンプレートファイルをそのまま書くよりストレスなく書くことができました。

この記事が誰かの助けになれば幸いです。

以上、AWS事業本部 コンサルティング部の のんピ(@non____97)でした!

おまけ 「npx cdk synth」の実行結果

おまけでnpx cdk synthの実行結果を以下に記載します。「素のCloudFormationで構築したいんだ!!」という熱き思いを持った方は参考にしてください。

Resources:
  SecurityGroupofFSxforONTAPfilesystem17D0823E:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: FsxForOntapStack/Security Group of FSx for ONTAP file system
      SecurityGroupEgress:
        - CidrIp: 0.0.0.0/0
          Description: Allow all outbound traffic by default
          IpProtocol: "-1"
      SecurityGroupIngress:
        - CidrIp: 10.0.0.0/16
          Description: Pinging the instance
          FromPort: 8
          IpProtocol: icmp
          ToPort: -1
        - CidrIp: 10.0.0.0/16
          Description: SSH access to the IP address of the cluster management LIF or a node management LIF
          FromPort: 22
          IpProtocol: tcp
          ToPort: 22
        - CidrIp: 10.0.0.0/16
          Description: Remote procedure call for NFS
          FromPort: 111
          IpProtocol: tcp
          ToPort: 111
        - CidrIp: 10.0.0.0/16
          Description: Remote procedure call for CIFS
          FromPort: 135
          IpProtocol: tcp
          ToPort: 135
        - CidrIp: 10.0.0.0/16
          Description: NetBIOS service session for CIFS
          FromPort: 139
          IpProtocol: tcp
          ToPort: 139
        - CidrIp: 10.0.0.0/16
          Description: Simple network management protocol (SNMP)
          FromPort: 161
          IpProtocol: tcp
          ToPort: 162
        - CidrIp: 10.0.0.0/16
          Description: ONTAP REST API access to the IP address of the cluster management LIF or an SVM management LIF
          FromPort: 443
          IpProtocol: tcp
          ToPort: 443
        - CidrIp: 10.0.0.0/16
          Description: Microsoft SMB/CIFS over TCP with NetBIOS framing
          FromPort: 445
          IpProtocol: tcp
          ToPort: 445
        - CidrIp: 10.0.0.0/16
          Description: NFS mount
          FromPort: 635
          IpProtocol: tcp
          ToPort: 635
        - CidrIp: 10.0.0.0/16
          Description: Kerberos
          FromPort: 749
          IpProtocol: tcp
          ToPort: 749
        - CidrIp: 10.0.0.0/16
          Description: NFS server daemon
          FromPort: 2049
          IpProtocol: tcp
          ToPort: 2049
        - CidrIp: 10.0.0.0/16
          Description: iSCSI access through the iSCSI data LIF
          FromPort: 3260
          IpProtocol: tcp
          ToPort: 3260
        - CidrIp: 10.0.0.0/16
          Description: NFS lock daemon
          FromPort: 4045
          IpProtocol: tcp
          ToPort: 4045
        - CidrIp: 10.0.0.0/16
          Description: Network status monitor for NFS
          FromPort: 4046
          IpProtocol: tcp
          ToPort: 4046
        - CidrIp: 10.0.0.0/16
          Description: Network data management protocol (NDMP) and NetApp SnapMirror intercluster communication
          FromPort: 10000
          IpProtocol: tcp
          ToPort: 10000
        - CidrIp: 10.0.0.0/16
          Description: Management of NetApp SnapMirror intercluster communication
          FromPort: 11104
          IpProtocol: tcp
          ToPort: 11104
        - CidrIp: 10.0.0.0/16
          Description: SnapMirror data transfer using intercluster LIFs
          FromPort: 11105
          IpProtocol: tcp
          ToPort: 11105
        - CidrIp: 10.0.0.0/16
          Description: Remote procedure call for NFS
          FromPort: 111
          IpProtocol: udp
          ToPort: 111
        - CidrIp: 10.0.0.0/16
          Description: Remote procedure call for CIFS
          FromPort: 135
          IpProtocol: udp
          ToPort: 135
        - CidrIp: 10.0.0.0/16
          Description: NetBIOS name resolution for CIFS
          FromPort: 137
          IpProtocol: udp
          ToPort: 137
        - CidrIp: 10.0.0.0/16
          Description: NetBIOS service session for CIFS
          FromPort: 139
          IpProtocol: udp
          ToPort: 139
        - CidrIp: 10.0.0.0/16
          Description: Simple network management protocol (SNMP)
          FromPort: 161
          IpProtocol: udp
          ToPort: 162
        - CidrIp: 10.0.0.0/16
          Description: NFS mount
          FromPort: 635
          IpProtocol: udp
          ToPort: 635
        - CidrIp: 10.0.0.0/16
          Description: NFS server daemon
          FromPort: 2049
          IpProtocol: udp
          ToPort: 2049
        - CidrIp: 10.0.0.0/16
          Description: NFS lock daemon
          FromPort: 4045
          IpProtocol: udp
          ToPort: 4045
        - CidrIp: 10.0.0.0/16
          Description: Network status monitor for NFS
          FromPort: 4046
          IpProtocol: udp
          ToPort: 4046
        - CidrIp: 10.0.0.0/16
          Description: NFS quota protocol
          FromPort: 4049
          IpProtocol: udp
          ToPort: 4049
      VpcId: vpc-0bdab140380e5888e
    Metadata:
      aws:cdk:path: FsxForOntapStack/Security Group of FSx for ONTAP file system/Resource
  SecretofFSxforONTAPfilesystemC6A1659C:
    Type: AWS::SecretsManager::Secret
    Properties:
      GenerateSecretString:
        GenerateStringKey: password
        PasswordLength: 32
        RequireEachIncludedType: true
        SecretStringTemplate: '{"userName": "fsxadmin"}'
      Name: /fsx-for-ontap/file-system
    UpdateReplacePolicy: Delete
    DeletionPolicy: Delete
    Metadata:
      aws:cdk:path: FsxForOntapStack/Secret of FSx for ONTAP file system/Resource
  SecretofFSxforONTAPSVMFC117093:
    Type: AWS::SecretsManager::Secret
    Properties:
      GenerateSecretString:
        GenerateStringKey: password
        PasswordLength: 32
        RequireEachIncludedType: true
        SecretStringTemplate: '{"userName": "vsadmin"}'
      Name: /fsx-for-ontap/svm
    UpdateReplacePolicy: Delete
    DeletionPolicy: Delete
    Metadata:
      aws:cdk:path: FsxForOntapStack/Secret of FSx for ONTAP SVM/Resource
  FSxforONTAPfilesystem:
    Type: AWS::FSx::FileSystem
    Properties:
      FileSystemType: ONTAP
      SubnetIds:
        - subnet-0edad58231582149e
        - subnet-02c64a402de04fc57
      OntapConfiguration:
        AutomaticBackupRetentionDays: 7
        DailyAutomaticBackupStartTime: "16:00"
        DeploymentType: MULTI_AZ_1
        DiskIopsConfiguration:
          Mode: AUTOMATIC
        EndpointIpAddressRange: 172.31.255.0/24
        FsxAdminPassword:
          Fn::Join:
            - ""
            - - "{{resolve:secretsmanager:"
              - Ref: SecretofFSxforONTAPfilesystemC6A1659C
              - :SecretString:password}}
        PreferredSubnetId: subnet-0edad58231582149e
        RouteTableIds:
          - rtb-07b39b800293a5e5c
          - rtb-0918d8afb6c3a76dc
        ThroughputCapacity: 128
        WeeklyMaintenanceStartTime: "6:17:00"
      SecurityGroupIds:
        - Fn::GetAtt:
            - SecurityGroupofFSxforONTAPfilesystem17D0823E
            - GroupId
      StorageCapacity: 1024
      StorageType: SSD
      Tags:
        - Key: Name
          Value: fsx-for-ontap-file-system-multi-az
    Metadata:
      aws:cdk:path: FsxForOntapStack/FSx for ONTAP file system
  SVM:
    Type: AWS::FSx::StorageVirtualMachine
    Properties:
      FileSystemId:
        Ref: FSxforONTAPfilesystem
      Name: fsx-for-ontap-svm-001
      ActiveDirectoryConfiguration:
        NetBiosName: SVM-001
        SelfManagedActiveDirectoryConfiguration:
          DnsIps:
            - 10.0.0.138
          DomainName: "{{resolve:secretsmanager:/fsx-dev.classmethod.jp/FSxForNetAppONTAP/ServiceAccount:SecretString:domainName}}"
          FileSystemAdministratorsGroup: "{{resolve:secretsmanager:/fsx-dev.classmethod.jp/FSxForNetAppONTAP/ServiceAccount:SecretString:fileSystemAdministratorsGroup}}"
          OrganizationalUnitDistinguishedName: "{{resolve:secretsmanager:/fsx-dev.classmethod.jp/FSxForNetAppONTAP/ServiceAccount:SecretString:organizationalUnitDistinguishedName}}"
          Password: "{{resolve:secretsmanager:/fsx-dev.classmethod.jp/FSxForNetAppONTAP/ServiceAccount:SecretString:password}}"
          UserName: "{{resolve:secretsmanager:/fsx-dev.classmethod.jp/FSxForNetAppONTAP/ServiceAccount:SecretString:userName}}"
      RootVolumeSecurityStyle: MIXED
      SvmAdminPassword:
        Fn::Join:
          - ""
          - - "{{resolve:secretsmanager:"
            - Ref: SecretofFSxforONTAPSVMFC117093
            - :SecretString:password}}
      Tags:
        - Key: Name
          Value: fsx-for-ontap-svm-001
    Metadata:
      aws:cdk:path: FsxForOntapStack/SVM
  NFSVolume:
    Type: AWS::FSx::Volume
    Properties:
      Name: fsx_for_ontap_volume_nfs
      OntapConfiguration:
        JunctionPath: /nfs
        SecurityStyle: UNIX
        SizeInMegabytes: "1024"
        StorageEfficiencyEnabled: "true"
        StorageVirtualMachineId:
          Ref: SVM
        TieringPolicy:
          CoolingPeriod: 31
          Name: AUTO
      Tags:
        - Key: Name
          Value: fsx_for_ontap_volume_nfs
      VolumeType: ONTAP
    Metadata:
      aws:cdk:path: FsxForOntapStack/NFS Volume
  SMBVolume:
    Type: AWS::FSx::Volume
    Properties:
      Name: fsx_for_ontap_volume_smb
      OntapConfiguration:
        JunctionPath: /smb
        SecurityStyle: NTFS
        SizeInMegabytes: "1024"
        StorageEfficiencyEnabled: "true"
        StorageVirtualMachineId:
          Ref: SVM
        TieringPolicy:
          CoolingPeriod: 31
          Name: AUTO
      Tags:
        - Key: Name
          Value: fsx_for_ontap_volume_smb
      VolumeType: ONTAP
    Metadata:
      aws:cdk:path: FsxForOntapStack/SMB Volume
  LUNVolume:
    Type: AWS::FSx::Volume
    Properties:
      Name: fsx_for_ontap_volume_lun
      OntapConfiguration:
        JunctionPath: /lun
        SecurityStyle: MIXED
        SizeInMegabytes: "1024"
        StorageEfficiencyEnabled: "true"
        StorageVirtualMachineId:
          Ref: SVM
        TieringPolicy:
          CoolingPeriod: 31
          Name: AUTO
      Tags:
        - Key: Name
          Value: fsx_for_ontap_volume_lun
      VolumeType: ONTAP
    Metadata:
      aws:cdk:path: FsxForOntapStack/LUN Volume
  CDKMetadata:
    Type: AWS::CDK::Metadata
    Properties:
      Analytics: v2:deflate64:H4sIAAAAAAAA/1WOsQ7CMAxEv4U9DVDBwIwEE0srdUUhdcFtkyA7Aaoq/05aYGDy3b2zdLnMt3K1UE/OdN1lPV7kWHqlO1EAu0AaRGLnEXSeAOhA6IcjuXAX+8b+BVEwaALPRll1BZr7yX+LSUXR8EuOyR+wh3JgD2am3lH6qJB8UP1J6RtamEDl+mAgxkn/9kRhXQ2y5eVjvZHrXVrfMmJGwXo0IIvPfQP22k0n2QAAAA==
    Metadata:
      aws:cdk:path: FsxForOntapStack/CDKMetadata/Default
Parameters:
  BootstrapVersion:
    Type: AWS::SSM::Parameter::Value<String>
    Default: /cdk-bootstrap/hnb659fds/version
    Description: Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]
Rules:
  CheckBootstrapVersion:
    Assertions:
      - Assert:
          Fn::Not:
            - Fn::Contains:
                - - "1"
                  - "2"
                  - "3"
                  - "4"
                  - "5"
                - Ref: BootstrapVersion
        AssertDescription: CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI.