アクトインディ開発者ブログ

子供とお出かけ情報「いこーよ」を運営する、アクトインディ株式会社の開発者ブログです

AWS CDKでつまづいたところ3選

この記事は actindi Advent Calendar 2019 の13日目の記事です。 adventar.org

こんにちは!!こんにちは!!インフラエンジニアのyamamotoです。

AWSのリソースを作成・修正するのに、CloudFormationを使うととても便利に作れますね。
でもループ処理できなかったり、生のYAMLが見づらかったりと面倒なこともあります。

そこでCloud Development Kit(CDK)を使うと、CloudFormationスタックを手軽に作ることができます!

しかしCDKについてはまだまだ情報が少なく、思い通りに扱うのも割と大変です。ここでは私がCDKを使っていてつまづいた点を共有させていただきます。

※当ブログのコードはTypeScriptで記載しています。

マルチスタックにするときはこうする

ネット上のCDKのサンプルはシングルスタック(CloudFormationスタック一つで実行する)で扱われたものが多くあります。見通しがよく、一気にいろいろなリソースが構築できるので便利ですね。
ただ、実際の運用を考えると、VPCはVPCだけ、EC2はEC2だけ、というように、それぞれのリソースで別々に実行したくなってきます。

そこで、CDKではマルチスタックにできるようになっているのですが、マルチスタックのサンプルがあまり無いので、どういう書き方がスタンダードなのか分かりづらかったです。

結局、CDKのマルチスタック対応は、このように書きました。

bin/stack.ts

#!/usr/bin/env node
import 'source-map-support/register';
import { App, Tag } from '@aws-cdk/core';

import FooStack from '../lib/FooStack';
import BarStack from '../lib/BarStack';
import BazStack from '../lib/BazStack';

const app = new App();

new FooStack(app, 'foo-stack');
new BarStack(app, 'bar-stack');
new BazStack(app, 'baz-stack');

単純に、このような感じで並べて書きました。
一つ一つ書くのが面倒なのですが、プログラムですし、色々なやり方があると思います。

なお、実行するときは、下記のように引数で実行したいスタックを指定します。

$ cdk deploy foo-stack

EKSでは既存のVPCを読むときにSubnetが無いとダメ

せっかくなのでKubernetesをやりましょう。CDKでEKSクラスタを作成して、でも既存環境があるので既存のVPCを読み込みたい、というときはVpc.fromLookup()メソッドを使います。
しかし、VPCを読み込んでEKSクラスターを作成しようとするとエラーが出てしまいます。
これもいろいろ探してみたものの事例が無く、原因もわかりませんでした。

あれこれ試してみたところ、EKSに読み込ませるVPCにはパブリックサブネットとプライベートサブネットが定義されてないとダメだとわかりました。
パブリック?プライベート?なんだかわからない定義ですが、要はインターネットゲートウェイにルーティングされたサブネットか否か、というだけのようです。

では、VPCスタックでサブネットを作ってVPCを読み込むように書いて、とやってもやはりエラーになります……なんで?

どうもVPCを読み込むときは、サブネットの作成がCDKコードに記載されていてもダメで、サブネットが実在していないと通らないようでした。
なので、サブネットを作成するスタックを先に実行して、作成が済んでからVPCを読み込ませるようなスタック構成にしないとうまく動きません。

bin/stack.ts

const vpcStack = new VpcStack(app, 'vpc-stack');
const vpc = Vpc.fromLookup(vpcStack, vpcName, { vpcId, vpcName });

上記の例では、VpcStack()内でサブネットを作成して、その後外でVpc.fromLookup()を実行しています。
このようにすることで、サブネットが作成された状態でVPCを読み込むことができます。

EKSマスターロールにはパスを付けてはダメ

さて、あれこれ試しながらようやくCDKでEKSクラスタを立ち上げました。しかしなぜか突然kubectlで接続できなくなってしまいました。
ロールを見直してもだめ、何度やっても不可思議なエラーが出てしまう。これは一体なんなんだろう。

こないだまではkubectlも問題なく動いていたのになんでだろう……ふと、最近修正したところを考えてみると……
ひょっとして、EKSのマスターロールにパスを追加したからダメなのか?

    const eksRole = new Role(this, 'EksRole', {
      roleName: 'eks-master-role',
      assumedBy: new AccountRootPrincipal(),
      path: '/cdk',
    });

ロールにパスを追加しようとしたのには訳があって、CDKで取り扱うロールを明示的に区分けしたかったからなのですが、まさかEKS側で対応していないとは……
とはいえ、日進月歩で進化しているAWSですから、そのうち対応するでしょう。早く対応してほしいなぁ。

さいごに

CDKはまだまだ発展途上ではありますが、未来を感じさせるソリューションですね。
昔から考えると、コードでネットワークを構築してサーバーを立ち上げる、とか想像もつかないですよね。どんどん便利に快適なインフラ環境になっててワクワクします。

アクトインディではWebエンジニアを募集しています! actindi.net