pulumiとkubectlを用いたEKS環境構築方法をご紹介(前編)

こんにちは。フリージアの佐久間です。
Pulumiとkubectlを用いたEKS環境構築方法を2回に分けてご紹介しようと思います。

登場人物は以下の通りです。

name description
springboot Webアプリケーション
jib DockerイメージBuilder
eks awsで提供されているkubenates環境
pulumi Web技術でコーディング出来るIaCツール
kubectl Kubernetesコマンドラインツール
ecr awsのdockerレジストリー

前編では、VPC構築と、ECRにDockerイメージをアップロードするところまでをご紹介しようと思います。
タスクは以下の通りです。

  • springbootアプリケーションを用意
  • jibを使って、Dockerイメージ作成
  • pulumiのセットアップ
  • aws-cliのセットアップ
  • pulumiで、VPCとECRを構築
  • jibを作った、DockerイメージをECRにアップロード

それでは順番にやっていきたいと思います。

springbootアプリケーションを用意

こちらはSpring Initializrから作成頂いても、ご自身でご用意頂いても大丈夫です。
好きなリポジトリーをご利用ください。
ちなみに今回はbuild.gradleをkotlinスクリプトで書いていますので、合わせておくと理解が楽かと思います。

jibを使って、Dockerイメージ作成

次は、デプロイするDockerイメージを作るのですが、Google大先生が便利なツールを提供してくれています。

build.gradleに以下を追加してください。(サンプルはkotlinスクリプトです)

plugins {
	~~ any ~~
	id("com.google.cloud.tools.jib") version "1.5.1" // Jib追加
	~~ any ~~
}

jib {
	to {
		image = "sample/demo" // 作成されるImageName
	}
}

すると、以下のコマンドでDockerイメージが作成されます

$ ./gradlew jibDockerBuild

確認してみましょう。 おそらくこんな感じで、ローカルにDockerイメージが追加されてると思います。

$ docker images
> REPOSITORY        TAG                 IMAGE ID            CREATED             SIZE
> sample/demo       latest              032b65b1057b        49 years ago        165MB

Dockerイメージ作成はこれで以上です。

pulumiのセットアップ

色々とIaC(Infrastructure as a Code)ツールがあるかと思いますが、今回は「pulumi」を使ってみようと思います。

まずは、pulumiのインストール&セットアップです。

$ brew install pulumi

pulumiでは様々な言語を利用して、IaCが実現出来ます。
以下、対応しているテンプレート一覧です。

$ pulumi new -h
~~~~~~
その他の情報
~~~~~~
> Available Templates:
>  aws-go                     A minimal AWS Go Pulumi program
>  aws-javascript             A minimal AWS JavaScript Pulumi program
>  aws-python                 A minimal AWS Python Pulumi program
>  aws-typescript             A minimal AWS TypeScript Pulumi program
>  azure-go                   A minimal Azure Go Pulumi program
>  azure-javascript           A minimal Azure JavaScript Pulumi program
>  azure-python               A minimal Azure Python Pulumi program
>  azure-typescript           A minimal Azure TypeScript Pulumi program
>  digitalocean-go            A minimal DigitalOcean Go Pulumi program
>  digitalocean-javascript    A minimal DigitalOcean JavaScript Pulumi program
>  digitalocean-python        A minimal DigitalOcean Python Pulumi program
>  digitalocean-typescript    A minimal DigitalOcean TypeScript Pulumi program
>  gcp-go                     A minimal Google Cloud Go Pulumi program
>  gcp-javascript             A minimal Google Cloud JavaScript Pulumi program
>  gcp-python                 A minimal Google Cloud Python Pulumi program
>  gcp-typescript             A minimal Google Cloud TypeScript Pulumi program
>  go                         A minimal Go Pulumi program
>  hello-aws-javascript       A simple AWS serverless JavaScript Pulumi program
>  javascript                 A minimal JavaScript Pulumi program
>  kubernetes-javascript      A minimal Kubernetes JavaScript Pulumi program
>  kubernetes-python          A minimal Kubernetes Python Pulumi program
>  kubernetes-typescript      A minimal Kubernetes TypeScript Pulumi program
>  linode-go                  A minimal Linode Go Pulumi program
>  linode-javascript          A minimal Linode JavaScript Pulumi program
>  linode-python              A minimal Linode Python Pulumi program
>  linode-typescript          A minimal Linode TypeScript Pulumi program
>  openstack-go               A minimal OpenStack Go Pulumi program
>  openstack-javascript       A minimal OpenStack JavaScript Pulumi program
>  openstack-python           A minimal OpenStack Python Pulumi program
>  openstack-typescript       A minimal OpenStack TypeScript Pulumi program
>  packet-go                  A minimal Packet.net Go Pulumi program
>  packet-javascript          A minimal Packet.net JavaScript Pulumi program
>  packet-python              A minimal Packet.net Python Pulumi program
>  packet-typescript          A minimal Packet.net TypeScript Pulumi program
>  python                     A minimal Python Pulumi program
>  typescript                 A minimal TypeScript Pulumi program

今回はtypescriptを使ってAWS環境構築を行うので、「aws-typescript」にしました。
pulumiの作業ディレクトリを作成し、pulumiプロジェクトを作成します。

$ mkdir 作成するpulumiディレクトリ名
$ pulumi new aws-typescript  --dir pulumi作業ディレクトリ名 -f

pulumiでは、state(pulumiの実行履歴)の管理方法として、クラウド環境を提供しています。
今回は、(値段的な兼ね合いで)pulumiのstateをローカルで管理したいので、localにログインします。

$ cd 作成したpulumiディレクトリ
$ mkdir -p .pulumi/stacks/
$ pulumi login file://./

今後、何かを実施する際にパスワードが聞かれます。
めんどくさい時は、環境変数に定義してやりましょう。

$ vim ~/.bashrc
$ export PULUMI_CONFIG_PASSPHRASE=`pulumiパスワード`
$ source ~/.bash_profile

pulumiではstackと呼ばれる環境に似た概念があります。
今回はstaging用のstackを作成します。

$ pulumi stack init [stack名]
$ pulumi config set aws:region ap-northeast-1

ここまででpulumiのセットアップは完了です。
pulumiではstackごとにconfigファイルが作成され、環境変数が定義されています。

aws-cliのセットアップ

続いて、awsの設定が必要です。
以下でaws-cliをインストールしてください。
AWS CLI のインストールと設定

以下のコマンドでAWSの認証情報を設定(or 確認)してください

$ aws configure
> AWS Access Key ID [None]: xxxxxxxxxxxxxxxxxxx
> AWS Secret Access Key [None]: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
> Default region name [None]: ap-northeast-1
> Default output format [None]: json

(pulumiは「~/.aws/credentials」のdefault設定を見に行きます)

pulumiで、VPCとECRを構築

ここから、実際のコードを書いていきます。
まずは、VPCとECRを作成しましょう。
作成したpulumi作業ディレクトリ直下に「index.ts」というファイルを作成して、以下を記述してください。

import * as pulumi from '@pulumi/pulumi'
import * as aws from '@pulumi/aws'
import * as awsx from '@pulumi/awsx'

const config = new pulumi.Config()
// ECRリポジトリー作成
const repository = new aws.ecr.Repository(config.require('ECR_REPOSITORY_NAME'), {
  name: config.require('ECR_REPOSITORY_NAME'),
  imageTagMutability: 'IMMUTABLE'
})
// VPC作成
const vpc = new awsx.ec2.Vpc(config.require('VPC_NAME'), {
  numberOfAvailabilityZones: 3, // ← サブネットの数指定。アベイラビリティゾーン分だけpublic/privateサブネットが作成される
  // ↓こんな感じに細かく指定も出来る
  // subnets: [
  //   { type: "private", name: 'private-1', location: { availabilityZone: 'ap-northeast-1a', cidrBlock: 'x.x.x.x/24' } as VpcSubnetLocation },
  //   { type: "public", name: 'public-1', location: { availabilityZone: 'ap-northeast-1a', cidrBlock: 'x.x.x.x/24' } as VpcSubnetLocation, mapPublicIpOnLaunch: true },
  //   { type: "private", name: 'private-2', location: { availabilityZone: 'ap-northeast-1c', cidrBlock: 'x.x.x.x/24' } as VpcSubnetLocation },
  //   { type: "public", name: 'public-2', location: { availabilityZone: 'ap-northeast-1c', cidrBlock: 'x.x.x.x/24' } as VpcSubnetLocation, mapPublicIpOnLaunch: true },
  // ],
  instanceTenancy: 'default',
  numberOfNatGateways: 1, // ← NatGateway数の指定
  cidrBlock: config.require('VPC_CIDR_BLOCK'), // VPCのCIDR指定
  tags: { Name: config.require('VPC_NAME') } // VPCの名前
} as VpcArgs);

今回は「@pulumi/aws」ではなく、「@pulumi/awsx」を利用するようにしました。
理由は単純で「@pulumi/awsx」はAWSのCDP(Cloud Design Pattern)沿って、ある程度自動で構築されるようになっているからです。

続いて、ソースコード内で利用している環境変数を定義します。

$ pulumi config set aws:region ap-northeast-1
$ pulumi config set VPC_NAME [VPCの名前]
$ pulumi config set VPC_CIDR_BLOCK [VPCのCIDR]
$ pulumi config set ECR_REPOSITORY_NAME [ECRのリポジトリー名]

ここまで出来たらpulumiを使ってVPCとECRを構築しましょう。
コマンドは簡単です。

$ pulumi update

pulumiはデフォルトでdry-run(のようなこと)をしてくれます。
(実際にdry-runをしているわけではないので、実行時に普通にエラーが出ます。)
構築されるものが問題なさそうであれば、迷わず「yes」を選択しましょう。
VPCの構築は、大体5~10分くらいで完了します。
pulumiが完了したら、VPCをこちらで確認してみましょう。

jibで作った、DockerイメージをECRにアップロード

先程、ECRの構築をしたので、ECRにDockerイメージをアップロードしましょう。

  • Imageにタグ付け(バージョン変えること)
$ docker tag sample/demo xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/demo:[イメージのバージョン]
  • ECRにログイン
$ aws ecr get-login --region ap-northeast-1 --no-include-email
$ 出てきたコマンドを貼ってDockerログイン
  • Imageプッシュ(バージョン変えること)
$ docker push xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/demo:[イメージのバージョン]

以上で、ECRにDockerイメージがアップロードされました。
実際にWeb上からアクセスして確認してみてください。
東京リージョン(ap-northeast-1)で作成された場合はこちらで確認出来ます。

まとめ

pulumiを利用することで、簡単にAWSにVPCとECRを構築することが出来ました。
最近正式版になったばかりで情報が少ないのですが、Web技術でインフラ構築が出来るので、一度触ってみるもの良いのではないかと思います。
困ったときは公式ブログを見るのがオススメです。 また公式Slack部屋もありますので、困ったらそちらで質問を投げるのも良いのではないでしょうか。 pulumiには「terraform import(既存の環境をterraform管理下にインポート)」に該当する機能が無いのが少し残念ですが、typescriptで簡単に書ける旨味は堪能出来ました。
今後も大注目のツールです!

今回のサンプルは以下のURLに置いてあります。
リポジトリー
こちらを参考にしつつ、試してみてください。

次回予告

次回は、実際にEKSにAPIをデプロイするところまでご紹介しようかと思います。

  • pulumiで、EKSを構築
  • kubectlでDockerイメージリリース

pulumiとkubectlを用いたEKS環境構築方法をご紹介(後編)

最後に

本記事を見て、ご意見やご指摘等ございましたら、「[email protected]」まで是非ご連絡ください。

Twitterもやってます。ご興味ありましたら、フォローしてください。
Twitter:asakuma0401