AWS CDKでの開発の流れについてまとめてみた

こんにちは。 エキサイト株式会社で内定者アルバイトをしている平石です。

今回は、AWS CDKを使ってクラウドアプリケーションリソースを定義する流れを勉強しましたので、まとめてみたいと思います。

※ この記事では全体の流れを軽く掴むことを目的としています。用語や必要な概念の詳しい内容はまた別の記事にまとめます。

前の記事

tech.excite.co.jp

そもそもAWS CDKとは?

公式ドキュメント(オープンソースの開発フレームワーク - AWS クラウド開発キット - AWS)によると、

AWS CDK(AWS Cloud Development Kit)は使い慣れたプログラミング言語を使用してクラウドアプリケーションリソースを定義するためのオープンソースのソフトウェア開発フレームワークです。

要は、これまで手作業でポチポチやっていたり、独自の言語や形式を使用してスクリプトを書いたりしてAWSのリソースを定義していたのを、我々が普段使っているプログラミング言語を使ってできるようにするためのものです。

サポートされている言語としては主にTypeScript、JavaScriptJavaPython、Goがあります。

では、実際に触ってみよう

どの言語で開発することを予定していたとしても、Node.jsで実行される同じバックエンドを使うことになります。 そこで、Node.jsをインストールする必要があります。Node.jsのバージョンとしては以下のページでactive long-term supportになっているバージョンが推奨されています。 本記事の執筆段階では、16.xですが変更されている可能性もあるので、以下のページを参照してください。

GitHub - nodejs/Release: Node.js Release Working Group

Credentials と Region の設定

次に、AWSへの認証情報と、リージョンの設定を行う必要があります。AWS CLIAWS CLI の最新バージョンをインストールまたは更新します。 - AWS Command Line Interface)をインストールしているのであれば、以下のコマンドを実行することで簡単に設定できます。

aws configure

コンソールに従って、AWS access key IDとsecret access key、default regionを入力します。これらはIAMで作成したものを利用します。

もし、AWS CLIをインストールしていないかつ、どうしてもしたくない場合には以下のように手動で~/.aws/config~/.aws/credentialsを作成、編集することでも設定できます。

~/.aws/config

[default]
region=AWS_DEFAULT_REGION

~/.aws/credentials

[default]
aws_access_key_id=AWS_ACCESS_KEY_ID
aws_secret_access_key=AWS_SECRET_ACCESS_KEY

AWS CDKのインストール

ここまで設定すれば、いよいよAWS CDKのインストールをします。インストール自体は一瞬で、

npm install -g aws-cdk

を実行することで完了します。

念の為、バージョン確認をしておきましょう。

cdk --version

以下のようなものが表示されれば、正常にインストールされています。(当然、インストールするタイミングによってバージョンは異なります。)

2.45.0 (build af1fb7c)

Bootstrapping

ここまでで、AWS CDKをインストールしましたが、これで開発に移ることができるわけではありません。
AWS CDKでスタックを開発するためにはデプロイ中にAWS CloudFormationを利用できるようにしなければなりません。
これには、専用のAmazon S3 bucketsとその他のcontainersなどのリソースが必要です。

では、これらのリソースを一つずつ設定していきましょう。
....と、書いたものの我々がそのような設定をしていく必要はありません。以下のコマンドを実行するだけで良いのです。あらかじめ自分のAWSアカウントのIDとリージョンだけは確認しておいてください。

cdk bootstrap aws://ACCOUNT-NUMBER(12桁のやつ)/REGION

プロジェクトを作成する

ここでは、AWS CDKプロジェクトを開発する手順を説明します。ターミナルで以下のコマンドを実行します。

mkdir my-project
cd my-project
cdk init app --language java

my-projectの部分はプロジェクト名なので自由に決定してください。私は、Javaで実装することを選択しましたが、--language javaには開発で使用したい言語を指定してください。

ここからはJavaで開発することを前提として説明しますが、大きな流れは他の言語でも同じです。

実際に開発する

ここまでで作成されたファイルを確認すると、my-project/src/main/java/com.myorg/MyProjectApp.javaファイルとmy-project/src/main/java/com.myorg/MyProjectStack.javaファイルがデフォルトで存在しているはず。

それぞれの中身は以下のようになっています。

my-project/src/main/java/com.myorg/MyProjectApp.java

package com.myorg;

import software.amazon.awscdk.App;
import software.amazon.awscdk.Environment;
import software.amazon.awscdk.StackProps;

import java.util.Arrays;

public class AwsCdkFirstApp {
    public static void main(final String[] args) {
        App app = new App();
        
        new AwsCdkFirstStack(app, "AwsCdkFirstStack", StackProps.builder()
                // 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 block to specialize this stack for the AWS Account
                // and Region that are implied by the current CLI configuration.
                /*
                .env(Environment.builder()
                        .account(System.getenv("CDK_DEFAULT_ACCOUNT"))
                        .region(System.getenv("CDK_DEFAULT_REGION"))
                        .build())
                */

                // Uncomment the next block if you know exactly what Account and Region you
                // want to deploy the stack to.
                /*
                .env(Environment.builder()
                        .account("123456789012")
                        .region("us-east-1")
                        .build())
                */

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

        app.synth();
    }
}

my-project/src/main/java/com.myorg/MyProjectStack.java

package com.myorg;

import software.constructs.Construct;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;
// import software.amazon.awscdk.Duration;
// import software.amazon.awscdk.services.sqs.Queue;

public class AwsCdkFirstStack extends Stack {
    public AwsCdkFirstStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public AwsCdkFirstStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        // The code that defines your stack goes here

        // example resource
        // final Queue queue = Queue.Builder.create(this, "AwsCdkFirstQueue")
        //         .visibilityTimeout(Duration.seconds(300))
        //         .build();
    }
}

ここではmy-project/src/main/java/com.myorg/MyProjectStack.javaの18行目の下に以下のようなコードを挿入してみましょう。

Bucket.Builder.create(this, "MyFirstBucket")
                .versioned(true)
                .bucketName("sample-bucket-name")
                .build();

このコードは物理IDがsample-bucket-nameであるようなAmazon S3 bucketを作成しています。

Building, Synthesizing and Deploying

AWS CDKでは実行する前にアプリケーションを自動でコンパイルしてくれます。しかし、エラーや実行テストをチェックするためにアプリケーションを手動でビルドすると良いでしょう。

これは、IDEmvn compileをプロジェクトのルートディレクトリで実行することで行うことができます(「mvnコマンド」がないと怒られるときにはMaven – Download Apache MavenMavenをダウンロードしてください)。

また、mvn testを実行することで、書いたテストを全て実行できます。

AWS CDKアプリケーションで定義されたスタックは以下のコマンドで個別に、または同時に「合成」して「デプロイ」することができます。

cdk synth                 # app defines single stack
cdk deploy FirstStack SecondStack   # app defines two or more stacks; two are deployed

合成ではスタックのコードからAWS CloudFormationのテンプレートを作成します。 デプロイでは実際にAWS上にリソースを作成します。

cdk deployでもテンプレートの合成ができるので、cdk synthは必須でありませんが、CloudFormationを熟知しておりテンプレートを確認したい場合や事前の(最低限の)エラー検出もしてくれるので実行しておくと良いでしょう

今回は、一つのスタックしか定義していないため、以下を実行することで合成、デプロイが終了します。

cdk synth
cdk deploy

上記を実行してエラーが出なければ、CDKを用いたインフラの定義は終了です。

 ✅  MyProjectStack

✨  Deployment time: 45.69s

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:xxxxxxxxxxxx:stack/MyProjectStack/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

✨  Total time: 50.35s

念の為、マネジメントコンソールなどで作成したリソースが存在することを確認しておきましょう。

なお、cdk deploy実行時に

sample-bucket-name already exists

というエラーが出るかと思いますが、これはS3がグローバルなリソースであり、bucketNameがグローバルで一意でなければならないためです。適当な(他の人が付けなさそうな)名前にすると解消されます。

終わりに

今回は、AWS CDKを用いてインフラを定義、運用する方法の基本を紹介しました。

では、また次回。

次の記事

tech.excite.co.jp

参考文献