LoginSignup
0
0

[AWS] CDKネタ - Transfer family サーバのプライベートIPアドレスを取得する

Posted at

お題

ヤクの毛を狩るまでのお話です。

  • Network Load Balancer のターゲットとして、Transfer Family で作成した FTPS サーバを指定したい
  • 指定するにはIPアドレスが必要
  • 残念ながら CDK 標準では、取得できない
  • CDK カスタムリソースを利用して AWS SDK を呼び出し、IPアドレスを取得すべし! :bulb:

コードの断片

CDK スタックまるごとは長すぎるので、関連部分のみです。

FTPS サーバの定義

Transfer family は CDK L1 で作らなくてはいけません。

vpc 変数には、ec2.IVpc な値が入っていると思ってください。

import * as cdk from "aws-cdk-lib";
import * as cr from "aws-cdk-lib/custom-resources";

// (略)

    // FTPサーバ
    const server = new cdk.aws_transfer.CfnServer(this, "FtpServer", {
      endpointType: "VPC",
      endpointDetails: {
        // NLB ターゲットにする都合上 subnet ひとつだけ
        subnetIds: [vpc.privateSubnets[0].subnetId],
        // (略)
      },
      // (略)
    });

プライベートIPアドレスを取得するカスタムリソース

Transfer DescribeServer → EC2 DescribeVpcEndpoints → EC2 DescribeNetworkInterfaces と順番に呼び出し、プライベートIPアドレスを取得しています。

  /**
   * サーバのIPアドレスを取得
   * @param server
   */
  private retrieveIpAddressOf(
    server: cdk.aws_transfer.CfnServer,
    id: string
  ): string {
    // describeServer API を呼び出し
    const describeServer = {
      service: "Transfer",
      action: "describeServer",
      parameters: { ServerId: server.attrServerId },
      outputPaths: ["Server.EndpointDetails.VpcEndpointId"],
      physicalResourceId: cr.PhysicalResourceId.of(id),
    };
    const serverCr = new cr.AwsCustomResource(this, "DescribeServer", {
      onCreate: describeServer,
      onUpdate: describeServer,
      policy: cr.AwsCustomResourcePolicy.fromSdkCalls({
        resources: cr.AwsCustomResourcePolicy.ANY_RESOURCE,
      }),
    });

    const vpcEndpointId = serverCr.getResponseField(
      "Server.EndpointDetails.VpcEndpointId"
    );

    // describeVpcEndpoints API を呼び出し
    const desribeVpcEndpoints = {
      service: "EC2",
      action: "describeVpcEndpoints",
      parameters: { VpcEndpointIds: [vpcEndpointId] },
      outputPaths: ["VpcEndpoints.0.NetworkInterfaceIds.0"],
      physicalResourceId: cr.PhysicalResourceId.of(id),
    };
    const vpcEndpointCr = new cr.AwsCustomResource(
      this,
      "DescribeVpcEndpoints",
      {
        onCreate: desribeVpcEndpoints,
        onUpdate: desribeVpcEndpoints,
        policy: cr.AwsCustomResourcePolicy.fromSdkCalls({
          resources: cr.AwsCustomResourcePolicy.ANY_RESOURCE,
        }),
      }
    );

    const networkInterfaceId = vpcEndpointCr.getResponseField(
      "VpcEndpoints.0.NetworkInterfaceIds.0"
    );

    // describeNetworkInterfaces を呼び出し
    const describeNetworkInterfaces = {
      service: "EC2",
      action: "describeNetworkInterfaces",
      parameters: { NetworkInterfaceIds: [networkInterfaceId] },
      outputPaths: ["NetworkInterfaces.0.PrivateIpAddress"],
      physicalResourceId: cr.PhysicalResourceId.of(id),
    };
    const networkInterfaceCr = new cr.AwsCustomResource(
      this,
      "DescribeNetworkInterfaces",
      {
        onCreate: describeNetworkInterfaces,
        onUpdate: describeNetworkInterfaces,
        policy: cr.AwsCustomResourcePolicy.fromSdkCalls({
          resources: cr.AwsCustomResourcePolicy.ANY_RESOURCE,
        }),
      }
    );

    return networkInterfaceCr.getResponseField(
      "NetworkInterfaces.0.PrivateIpAddress"
    );
  }

参考リンク

使用するAPIの情報はこちらから拝借しました。感謝!

それぞれAPIの詳細はこちらです。

CDK カスタムリソースのコンストラクタです。

クラスメソッドの記事です。いつもお世話になってます。 ペコリ

ひとりごと

ところで、なんでわざわざ NLB を使うかといいますと、各種サーバ(FTP、WWW)に同じ名前で接続したいからなんだってさー。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0