見出し画像

AWS CDKチュートリアル(1) 環境構築

はじめに

こんにちは、株式会社SHIFT DAAE部の栗山です。今回からAWS CDKのチュートリアルを執筆していきたいと思います。
第1本目の今回はCDKの環境構築方法の解説です。

本来であれば環境構築は「公式の説明通りにやってください」というのがベストだと思うのですが、AWS公式のCDKチュートリアル(入門ガイド)がメンテナンスされていないのか、そのままやると動きません。また必要な情報があちこち散らばっていて読みづらいため、本チュートリアルは環境構築から始めることにしました。

本記事は、上記の入門ガイドをベースにしたものです。以下に該当する方はぜひご覧ください。

  • CDKの環境構築方法をざっと把握したい方

  • 公式の説明通りにやって動かず困っている方

使用する言語などは以下です。

  • 言語:TypeScript

  • 環境:Linux(WSLのUbuntu20.04.5LTS)

前提条件

以下ができることを前提とします。

  • LinuxにNode.jsがインストールされていること。
    対応するNode.jsのバージョンはこちらをご確認ください。

  • AWSアカウントがあり、IAMユーザーを作成できること。

AWS CLIのインストール

CDKをインストールするには、AWS CLIが必要なのでAWS CLIをインストールします。

まずNode.jsがインストールされていることを確認します。

$ node --version
v16.17.0

次にAWS CLIがインストールされていないことを確認します。

$ aws –-version
Command 'aws' not found, but can be installed with:

sudo apt install awscli

Command not foundと出ているので、AWS CLIは未インストール状態です。
ここでひとつ、注意。
「sudo apt install awscli」でAWS CLIをインストールしてはいけません。
aptでインストールすると、AWS CLIのversion1が入ってしまいやり直す羽目になります。

では正しい方法でAWS CLIをインストールしましょう。コマンドは以下です。

curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install

コマンドの内容は、zipファイルをダウンロードして、解凍し、インストールするというものです。

このコマンドはAWS公式のものです。 CDKはアップデートが早いので上記コマンドもすぐ古くなるでしょう。上記コマンドを実行する前に、公式サイトを確認するようお願いします。

最後にAWS CLIがインストールされたことを確認します。

$ aws --version
aws-cli/2.7.31 Python/3.9.11 Linux/5.10.16.3-microsoft-standard-WSL2 exe/x86_64.ubuntu.20 prompt/off

このように出力されれば、AWS CLIのインストールは成功です。うまくいかない場合は、いったんUbuntu(WSL)を再起動してみてください。

AWS CLIの初期設定

AWS CLIをインストールしたら、次にAWSのアカウント情報を設定します。
まず、AWS CLIに設定するIAMユーザーを作成します。

まずはIAMに移動し、ユーザーを追加します(セキュリティ上、黒塗りしてある箇所がありますがお気になさらず)。

ユーザーの追加画面でユーザー名を入力し、「アクセスキー・プログラムによるアクセス」を選択します。

ユーザーにアクセス許可の設定をします。ここではAdministratorAccessにしておきます(権限は最小にするべきですが、今回はこれで)。

その後、画面の指示の通りに進むとユーザーが作成されます。
この画面に遷移したら、アクセスキーとシークレットアクセスキーを控えます。

これでCDK接続用のユーザーを作成し、そのアクセスキーとシークレットアクセスキーを取得することができました。

aws configureコマンドを打ち、画面の指示に従い、情報を入力していきます。
「Default region name」と「Default output format」はお好きな設定を。通常は以下の設定でよいと思います。

$ aws configure
AWS Access Key ID [None]: アクセスキー
AWS Secret Access Key [None]: アクセスキーのシークレット
Default region name [None]: ap-northeast-1
Default output format [None]: json

以下のコマンドでAWS CLIの設定がされたことを確認します。

$ aws ec2 describe-vpcs
{
    "Vpcs": [
        {
            "CidrBlock": "172.31.0.0/16",
            "DhcpOptionsId": "dopt-bf727bd8",
            "State": "available",
            -- 以下省略

describe-vpcsコマンドの結果が出力されれば、AWS CLIの初期設定は完了です。

CDKのインストール&初期設定

いよいよCDKのインストールです。

以下のコマンドでCDKがインストールされます。

$ sudo npm install -g aws-cdk

CDKがインストールされたことを確かめるには、以下のコマンドを打ちます。

$ cdk --version
2.44.0 (build bf32cb1)

CDKをインストールしたら、ブートストラップという初期設定が必要です。
共有のAWSアカウントの場合(社用アカウントなど)、すでにブートストラップがされていればこの作業は不要です。

まずブートストラップの設定情報を知るために以下のコマンドを打ちます。

$ aws sts get-caller-identity
{
    "UserId": "ユーザーID",
    "Account": "ACCOUNT-NUMBER",
    "Arn": "arn:aws:iam::ACCOUNT-NUMBER:user/ユーザー名"
}

上記コマンドの結果の「ACCOUNT-NUMBER」の部分を次で使用します。

以下のコマンドでブートストラップを行います。

cdk bootstrap aws://ACCOUNT-NUMBER/REGION

「ACCOUNT-NUMBER」は上記コマンドの結果で出たものです。
REGIONは使用するリージョン(ap-northeast-1など)を設定すればいいと思います。

以上でCDKのインストール&初期設定は完了です。

CDKのプロジェクトの作成

次にCDKのプロジェクトを作成します。以下のように空のディレクトリを作成し、そのディレクトリ内でcdk initコマンドを打つとプロジェクトが作成されます。

mkdir sample-cdk
cd sample-cdk
cdk init --language typescript SampleCdk

どのようなファイルが作成されるのか、treeコマンドで確認してみましょう。

$ tree -L 2
.
├── README.md
├── bin
│   └── sample-cdk.ts
├── cdk.json
├── jest.config.js
├── lib
│   └── sample-cdk-stack.ts
├── node_modules
│   ├── @ampproject
      省略
├── package-lock.json
├── package.json
├── test
│   └── sample-cdk.test.ts
└── tsconfig.json

ポイントとなるファイルを紹介します。 一つ目は、binの配下にできる.tsファイルです。
ファイル名は「<ディレクトリ名>.ts」になるので、上記コマンドの場合「sample-cdk.ts」になります。

このファイルでは、libの配下に作成したStackを読み込み、そのインスタンスをnewします。
以下がcdk initコマンドで作成直後にbin配下にできるファイルです。

[sample-cdk.ts]

#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import { SampleCdkStack } from '../lib/sample-cdk-stack';

const app = new cdk.App();
new SampleCdkStack(app, 'SampleCdkStack', {
  /* If you don't specify 'env', this stack will be environment-agnostic.
   * Account/Region-dependent features and context lookups will not work,
   * but a single synthesized template can be deployed anywhere. */

  /* Uncomment the next line to specialize this stack for the AWS Account
   * and Region that are implied by the current CLI configuration. */
  // env: { account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION },

  /* Uncomment the next line if you know exactly what Account and Region you
   * want to deploy the stack to. */
  // env: { account: '123456789012', region: 'us-east-1' },

  /* For more information, see https://docs.aws.amazon.com/cdk/latest/guide/environments.html */
});

コメントで書かれているように、Stackをnewする際にaccountやregionなどを設定します。

次にポイントとなるのが、libの配下にできるファイルです。
ファイル名は「<ディレクトリ名>-stack.ts」になるので、上記コマンドの場合「sample-cdk-stack.ts」になります。

[sample-cdk-stack.ts]

import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
// import * as sqs from 'aws-cdk-lib/aws-sqs';

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

    // The code that defines your stack goes here

    // example resource
    // const queue = new sqs.Queue(this, 'SampleCdkQueue', {
    //   visibilityTimeout: cdk.Duration.seconds(300)
    // });
  }
}

このファイルでは、作成するAWSインスタンスの具体的な設定を記述します。そうしておいて、前述のbin配下のファイルからこのファイルを呼び出すというわけです。

コード例

では、CDKの動作確認のためにVPCを作成してみましょう。

まずはbin配下のファイルです。コメントを消して、必要な情報のみにするとこのようになります。 ACCOUNT-NUMBERはaws sts get-caller-identityで取得した値を記述してください。

[sample-cdk.ts]

#!/usr/bin/env node
import "source-map-support/register";
import * as cdk from "aws-cdk-lib";
import { SampleCdkStack } from "../lib/sample-cdk-stack";

const app = new cdk.App();
new SampleCdkStack(app, "SampleCdkStack", {
  env: { account: "ACCOUNT-NUMBER", region: "ap-northeast-1" },
});

次にlib配下のファイルです。公式のコード例を動くように修正すると以下になります。

[sample-cdk-stack.ts]

import * as cdk from "aws-cdk-lib";
import { Construct } from "constructs";
import { SubnetType, Vpc } from "aws-cdk-lib/aws-ec2";
export class SampleCdkStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const vpc = new Vpc(this, "MainVpc", {
      // CHANGE: this is where we define how many AZs to use
      maxAzs: 2,

      // CHANGE: We define a single subnet configuration per AZ.
      subnetConfiguration: [
        {
          // CHANGE: this is it's CIDR mask so 255.255.255.0
          cidrMask: 24,

          // CHANGE: a name for each of these subnets
          name: "public-subnet",

          // CHANGE: and the subnet type to be used - here we will have
          // a public subnet. There are other options available here.
          subnetType: SubnetType.PUBLIC,
        },
      ],
    });
  }
}

上記でポイントになるのは3行目のimport文です。
AWSの公式の例では@aws-cdk/aws-ec2からインストールするのですが、これが間違いです。

現在のCDK(2系)ではaws-cdk-libを使用するからです。
そのため、AWS公式の例のコードをそのまま使用すると動きません。

動作確認

では、実際にCDKを動かしてみましょう。

$ cdk deploy

上記コマンドを打ち、以下のような出力が出れば成功です。これでAWS上にリソースが作成されました。

SampleCdkStackDeployment time: 70.35s

ではマネジメントコンソールから確認してみましょう。

CDKのデプロイ状況を確認するにはCloud Formationのスタックを見ます。
以下の画像でSampleCdkStackが作成されたことがわかります。

今回はVpcを作成したので、Vpcの方からも見てみましょう。 SampleCdkStack/MainVpcが存在しています。

今回はただVpcを作成しただけなので、これで終わりです。

最後に作成したリソースを消しましょう。以下コマンドです。

cdk destroy

以下のような出力が出ればリソースの削除は成功です。
これで時間単位で料金がかかるリソースを作成した際も安心ですね。

SampleCdkStack: destroying...

 ✅  SampleCdkStack: destroyed

最後に

CDKの環境構築は以上です。

次回は、もう少し「作った感」のある例をご紹介できたらと思います。
最後までお読みいただき、ありがとうございます。

参考文献

\もっと身近にもっとリアルに!DAAE公式Twitter/


執筆者プロフィール:Kuriyama Akira
DAAE開発エンジニア。前職はPMとエンジニアを兼任しつつC++でデスクトップアプリを開発。モダンなWEBアプリを勉強する日々。

お問合せはお気軽に
https://service.shiftinc.jp/contact/

SHIFTについて(コーポレートサイト)
https://www.shiftinc.jp/

SHIFTのサービスについて(サービスサイト)
https://service.shiftinc.jp/

SHIFTの導入事例
https://service.shiftinc.jp/case/

お役立ち資料はこちら
https://service.shiftinc.jp/resources/

SHIFTの採用情報はこちら 
https://recruit.shiftinc.jp/career/