実践!AWS CDK #10 インターネットゲートウェイ

題字・息子たち
2021.06.14

はじめに

今回はインターネットゲートウェイを構築します。

前回の記事はこちら。

AWS 構成図

1

インターネットゲートウェイを作成し、VPC にアタッチします。

設計

インターネットゲートウェイのプロパティはこちら。

リソース名 アタッチ先 VPC
devio-stg-igw devio-stg-vpc

インターネットゲートウェイは比較的シンプルなリソースなので、設定項目はリソース名(tags)くらいです。

ルールのおさらい

前回の最後で宣言した、今後の実装に関する(自分)ルールです。

  • 作成するリソースごとにファイル(クラス)を分割する
    • 例)internetGateway.tsInternetGateway クラス)
  • すべてのリソースクラスは抽象クラス Resource を継承する
  • 「あるリソースの生成に必要となるリソース」はコンストラクタに渡す
    • 渡すオブジェクトは CfnXXX クラスのインスタンス
  • リソースクラス内で複数のリソースを生成する場合はループで回す
    • new CfnXXX() を何度も実行しない
    • ResourceInfo インタフェースを用意してプロパティの変動部分のみを書き出す
  • 生成したリソースはリソースクラス内の public メンバ変数に格納し、外部クラスから参照可能とする

これらに従って実装していきます。

実装

インターネットゲートウェイに関するクラスを作成しました。

lib/resource/internetGateway.ts

import * as cdk from '@aws-cdk/core';
import { CfnInternetGateway, CfnVPCGatewayAttachment, CfnVPC } from '@aws-cdk/aws-ec2';
import { Resource } from './abstract/resource';

export class InternetGateway extends Resource {
    public igw: CfnInternetGateway;

    private readonly vpc: CfnVPC;

    constructor(vpc: CfnVPC) {
        super();
        this.vpc = vpc;
    }

    createResources(scope: cdk.Construct) {
        this.igw = new CfnInternetGateway(scope, 'InternetGateway', {
            tags: [{ key: 'Name', value: this.createResourceName(scope, 'igw') }]
        });

        new CfnVPCGatewayAttachment(scope, 'VpcGatewayAttachment', {
            vpcId: this.vpc.ref,
            internetGatewayId: this.igw.ref
        });
    }
}

インターネットゲートウェイの生成と VPC へのアタッチを行っています。
アタッチ時は VPC とインターネットゲートウェイの ID をそれぞれ指定します。VPCGatewayAttachment のインスタンスは他のクラスで利用する予定がないのでメンバ変数には保持しません。この場でアタッチしておしまいです。

new CfnXXX を 2 回実行していますが、対象が異なるリソースなのでこの場合はセーフです。(ルール違反ではない)

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

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';

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);
  }
}

テスト

テストコードはこちら。

test/resource/internetGateway.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('InternetGateway', () => {
    const app = new cdk.App();
    const stack = new Devio.DevioStack(app, 'DevioStack');

    expect(stack).to(countResources('AWS::EC2::InternetGateway', 1));
    expect(stack).to(haveResource('AWS::EC2::InternetGateway', {
        Tags: [{ 'Key': 'Name', 'Value': 'undefined-undefined-igw' }]
    }));

    expect(stack).to(countResources('AWS::EC2::VPCGatewayAttachment', 1));
});

以下を確認しています。

  • インターネットゲートウェイリソースが 1 つあること
  • リソース名が正しいこと
  • VPCGatewayAttachment リソースが 1 つあること

確認

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

2

作成されていますね。アタッチ先の VPC も意図通りになっています。

CloudFormation 版

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

InternetGateway:
  Type: AWS::EC2::InternetGateway
  Properties:
    Tags:
      - Key: Name
        Value: devio-stg-igw
VpcGatewayAttachment:
  Type: AWS::EC2::VPCGatewayAttachment
  Properties:
    VpcId:
      Ref: Vpc
    InternetGatewayId:
      Ref: InternetGateway

短めです。

GitHub

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

おわりに

長い時間をかけてベースを固めたおかげでスムーズに実装できました。設計って楽しいですね。

次回は NAT ゲートウェイに割り当てるための Elastic IP を作成しようと思います。

リンク