実践!AWS CDK #11 Elastic IP

題字・息子たち
2021.06.17

はじめに

今回は NAT ゲートウェイ作成の前段として Elastic IP を作成します。

前回の記事はこちら。

AWS 構成図

1

NAT ゲートウェイに関連付けるための Elastic IP を作ります。NAT ゲートウェイの生成には Elastic IPサブネット が必須なためです。

※今回 NAT ゲートウェイは作りません

設計

Elastic IP のプロパティはこちら。

リソース名 ドメイン
devio-stg-eip-ngw-1a vpc
devio-stg-eip-ngw-1c vpc

2 つの Elastic IP を作成します。
リソース名のほか、ドメインvpc としています。このプロパティはリージョンによってデフォルト値が異なるため、明示的に指定することにします。

実装

Elastic IP に関する処理を行うクラスはこちら。

lib/resource/elasticIp.ts

import * as cdk from '@aws-cdk/core';
import { CfnEIP } from '@aws-cdk/aws-ec2';
import { Resource } from './abstract/resource';

interface ResourceInfo {
    readonly id: string;
    readonly resourceName: string;
    readonly assign: (elasticIp: CfnEIP) => void;
}

export class ElasticIp extends Resource {
    public ngw1a: CfnEIP;
    public ngw1c: CfnEIP;

    private readonly resourcesInfo: ResourceInfo[] = [
        {
            id: 'ElasticIpNgw1a',
            resourceName: 'eip-ngw-1a',
            assign: elasticIp => this.ngw1a = elasticIp
        },
        {
            id: 'ElasticIpNgw1c',
            resourceName: 'eip-ngw-1c',
            assign: elasticIp => this.ngw1c = elasticIp
        }
    ];

    constructor() {
        super();
    }

    createResources(scope: cdk.Construct) {
        for (const resourceInfo of this.resourcesInfo) {
            const elasticIp = this.createElasticIp(scope, resourceInfo);
            resourceInfo.assign(elasticIp);
        }
    }

    private createElasticIp(scope: cdk.Construct, resourceInfo: ResourceInfo): CfnEIP {
        const elasticIp = new CfnEIP(scope, resourceInfo.id, {
            domain: 'vpc',
            tags: [{
                key: 'Name',
                value: this.createResourceName(scope, resourceInfo.resourceName)
            }]
        });

        return elasticIp;
    }
}

複数のリソースを生成するので、処理をループで回しています。

メインのプログラムはこちら。
ハイライト部分を追記しました。

lib/devio-stack.ts

import * as cdk from '@aws-cdk/core';
import { Vpc } from './resource/vpc';
import { Subnet } from './resource/subnet';
import { InternetGateway } from './resource/internetGateway';
import { ElasticIp } from './resource/elasticIp';

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

    // VPC
    const vpc = new Vpc();
    vpc.createResources(this);

    // Subnet
    const subnet = new Subnet(vpc.vpc);
    subnet.createResources(this);

    // Internet Gateway
    const internetGateway = new InternetGateway(vpc.vpc);
    internetGateway.createResources(this);

    // Elastic IP
    const elasticIp = new ElasticIp();
    elasticIp.createResources(this);
  }
}

少しずつネットワークまわりが出来上がって参りました。

テスト

テストコードはこちら。

test/resource/elasticIp.test.ts

import { expect, countResources, haveResource } from '@aws-cdk/assert';
import * as cdk from '@aws-cdk/core';
import * as Devio from '../../lib/devio-stack';

test('ElasticIp', () => {
    const app = new cdk.App();
    const stack = new Devio.DevioStack(app, 'DevioStack');

    expect(stack).to(countResources('AWS::EC2::EIP', 2));
    expect(stack).to(haveResource('AWS::EC2::EIP', {
        Domain: 'vpc',
        Tags: [{ 'Key': 'Name', 'Value': 'undefined-undefined-eip-ngw-1a' }]
    }));
    expect(stack).to(haveResource('AWS::EC2::EIP', {
        Domain: 'vpc',
        Tags: [{ 'Key': 'Name', 'Value': 'undefined-undefined-eip-ngw-1c' }]
    }));
});

以下を確認しています。

  • Elastic IP リソースが 2 つあること
  • 各 Elastic IP のプロパティが正しいこと

確認

マネジメントコンソール上でリソースを確認してみましょう。

2

できてます。

CloudFormation 版

今回のコードを CFn で書くと以下のようになります。

ElasticIpNgw1a:
  Type: AWS::EC2::EIP
  Properties:
    Domain: vpc
    Tags:
      - Key: Name
        Value: devio-stg-eip-ngw-1a
ElasticIpNgw1c:
  Type: AWS::EC2::EIP
  Properties:
    Domain: vpc
    Tags:
      - Key: Name
        Value: devio-stg-eip-ngw-1c

シンプルですね。

GitHub

今回のソースコードは コチラ です。

おわりに

これで準備が整いました。
というわけで次回は NAT ゲートウェイ を作っていきましょう。

リンク