Software development of explosion! -夢の破片(カケラ)たちの日々-

ソフトウェア開発を中心としたコンピューター関連のネタを扱ったブログです

Software development is passion and explosion!

Scala で AWS CDK Javaを使ってみる

はじめに

Scala Advent Calendar 2019 - Qiita の 16日目への寄稿です。

AWS CDK が、 2019年7月11日 に Generally Available となりました。
そして、2019年11月26日に AWS CDK for Java も Generally Available となりました。
Scalaから使ったら更に読み書きし易くなったりしないものだろうか?と思い立ったので試してみます。

環境構築

AWS CDK の Getting Started Prerequisites を見ると、 Node.js が必要とのこと。
マシンのOSに依存させるのは嫌なので、ここではDockerイメージ内で作業することとします。

実行方法は、GitHubリポジトリーのREADMEをご覧ください。

いざ!CDK

実行したコンテナー内で cdk init --language java を実行します。

[zsh@d535e914ac9e cdk]$ dk init --language java
Applying project template app for java
Initializing a new git repository...

*** Please tell me who you are.

Run

  git config --global user.email "you@example.com"
  git config --global user.name "Your Name"

to set your account's default identity.
Omit --global to set the identity only in this repository.

fatal: unable to auto-detect email address (got 'zsh@be05ff957502.(none)')
Unable to initialize git repository for your project.
Executing mvn package...
# Welcome to your CDK Java project!

This is a blank project for Java development with CDK.

The `cdk.json` file tells the CDK Toolkit how to execute your app.

It is a [Maven](https://maven.apache.org/) based project, so you can open this project with any Maven compatible Java IDE to build and run tests.

## Useful commands

 * `mvn package`     compile and run tests
 * `cdk ls`          list all stacks in the app
 * `cdk synth`       emits the synthesized CloudFormation template
 * `cdk deploy`      deploy this stack to your default AWS account/region
 * `cdk diff`        compare deployed stack with current state
 * `cdk docs`        open CDK documentation

Enjoy!

[zsh@d535e914ac9e cdk (master +)]$ 

これで、 pom.xml が出来ました。

[zsh@d535e914ac9e cdk (master +)]$ ls
src  target  README.md  cdk.json  pom.xml
[zsh@d535e914ac9e cdk (master +)]$ 

pomの中身とCDKのバージョン

作られたpom.xmlを見てみると、グループIDは software.amazon.awscdk、バージョンはCDK本体のバージョンの後ろに .DEVPREVIEW が付与された形。
おそらくGAになったら外れるでしょう。

[zsh@d535e914ac9e cdk (master +)]$ cat pom.xml 
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
         xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.myorg</groupId>
    <artifactId>cdk</artifactId>
    <version>0.1</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.7.0</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.6.0</version>
                <configuration>
                    <mainClass>com.myorg.CdkApp</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <!-- AWS Cloud Development Kit -->
        <dependency>
            <groupId>software.amazon.awscdk</groupId>
            <artifactId>core</artifactId>
            <version>1.18.0</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/junit/junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>
[zsh@d535e914ac9e cdk (master +)]$ cdk --version
1.18.0 (build bc924bc)
[zsh@d535e914ac9e cdk (master +)]$ 

sbtへ移植

new project

[zsh@73d67aca507d ~]$ sbt new scala/hello-world.g8
[info] Set current project to zsh (in build file:/home/zsh/)
[info] Set current project to zsh (in build file:/home/zsh/)

A template to demonstrate a minimal Scala application 

name [Hello World template]: 
Template applied in /home/zsh/./cdk

[zsh@73d67aca507d ~]$ ls
cdk  target
[zsh@73d67aca507d ~]$ cd cdk 
[zsh@73d67aca507d cdk (master +%)]$ ls
project  src  target  README.md  build.sbt  cdk.json  pom.xml
[zsh@73d67aca507d cdk (master +%)]$ 

これで、CDKを使うアプリの本体のベースが出来ました。
build.sbt へ pom.xml の内容を記述して、Scalaのコードを記述していきます。
build.sbt はこんな感じにしました。

import sbt.Keys.{libraryDependencies, scalaVersion}

scalaVersion := "2.13.1"

name := "hello-world"
organization := "com.github.poad"
version := "1.0"

val cdkVersion = "1.18.0"
libraryDependencies ++= Seq(
    "software.amazon.awscdk" % "core" % cdkVersion
)

流石に Java のコードを Scala へ移植する部分や、Javdocを調べてScalaのコードを記述する部分の説明については割愛します。

cdk.json

Getting Started With the AWS CDK - AWS Cloud Development Kit (AWS CDK) の 「cdk ls」を実行すると以下のようなエラーが出力されます。 (Javaのクラスを残したままだと発生しないかと思います。。。)

[zsh@bd8ee7c9cbb6 cdk (master *+)]$ cdk ls
[ERROR] Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.6.0:java (default-cli) on project cdk: An exception occured while executing the Java class. com.myorg.HelloApp -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException
Subprocess exited with error 1

あるいは、pom.xml を削除していると、以下のようなエラーが出力されます。

[zsh@bd8ee7c9cbb6 cdk (master *+%)]$ cdk ls
[ERROR] Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.6.0:java (default-cli): Goal requires a project to execute but there is no POM in this directory (/home/zsh/cdk). Please verify you invoked Maven from the correct directory. -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MissingProjectException
Subprocess exited with error 1

これらの原因は、cdk init で生成される cdk.json というファイルです。

{
  "app": "mvn -e -q exec:java",
  "context": {
    "@aws-cdk/core:enableStackNameDuplicates": "true"
  }
}

以下のように書き換えます。

{
  "app": "sbt run",
  "context": {
    "@aws-cdk/core:enableStackNameDuplicates": "true"
  }
}

これで正しく動くようになります。

[zsh@bd8ee7c9cbb6 cdk (master *+%)]$ cdk ls
[info] [launcher] getting org.scala-sbt sbt 1.3.4  (this may take some time)...
downloading https://repo1.maven.org/maven2/org/scala-sbt/sbt/1.3.4/sbt-1.3.4.jar ...
:: loading settings :: url = jar:file:/usr/local/sbt/bin/sbt-launch.jar!/org/apache/ivy/core/settings/ivysettings.xml
downloading https://repo1.maven.org/maven2/org/scala-sbt/main_2.12/1.3.4/main_2.12-1.3.4.jar ...
:: loading settings :: url = jar:file:/usr/local/sbt/bin/sbt-launch.jar!/org/apache/ivy/core/settings/ivysettings.xml
downloading https://repo1.maven.org/maven2/org/scala-sbt/io_2.12/1.3.1/io_2.12-1.3.1.jar ...
downloading https://repo1.maven.org/maven2/org/scala-lang/scala-library/2.12.10/scala-library-2.12.10.jar ...
:: loading settings :: url = jar:file:/usr/local/sbt/bin/sbt-launch.jar!/org/apache/ivy/core/settings/ivysettings.xml
:: loading settings :: url = jar:file:/usr/local/sbt/bin/sbt-launch.jar!/org/apache/ivy/core/settings/ivysettings.xml
    [SUCCESSFUL ] org.scala-sbt#sbt;1.3.4!sbt.jar (1087ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/logic_2.12/1.3.4/logic_2.12-1.3.4.jar ...
    [SUCCESSFUL ] org.scala-sbt#logic_2.12;1.3.4!logic_2.12.jar (460ms)
    [SUCCESSFUL ] org.scala-sbt#io_2.12;1.3.1!io_2.12.jar (1526ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/main-settings_2.12/1.3.4/main-settings_2.12-1.3.4.jar ...
downloading https://repo1.maven.org/maven2/org/scala-sbt/actions_2.12/1.3.4/actions_2.12-1.3.4.jar ...
    [SUCCESSFUL ] org.scala-sbt#actions_2.12;1.3.4!actions_2.12.jar (595ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/run_2.12/1.3.4/run_2.12-1.3.4.jar ...
    [SUCCESSFUL ] org.scala-sbt#main-settings_2.12;1.3.4!main-settings_2.12.jar (612ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/command_2.12/1.3.4/command_2.12-1.3.4.jar ...
    [SUCCESSFUL ] org.scala-sbt#run_2.12;1.3.4!run_2.12.jar (452ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/collections_2.12/1.3.4/collections_2.12-1.3.4.jar ...
    [SUCCESSFUL ] org.scala-sbt#command_2.12;1.3.4!command_2.12.jar (466ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/scripted-sbt-redux_2.12/1.3.4/scripted-sbt-redux_2.12-1.3.4.jar ...
    [SUCCESSFUL ] org.scala-lang#scala-library;2.12.10!scala-library.jar (2808ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/scripted-plugin_2.12/1.3.4/scripted-plugin_2.12-1.3.4.jar ...
    [SUCCESSFUL ] org.scala-sbt#scripted-sbt-redux_2.12;1.3.4!scripted-sbt-redux_2.12.jar (450ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/zinc-lm-integration_2.12/1.3.4/zinc-lm-integration_2.12-1.3.4.jar ...
    [SUCCESSFUL ] org.scala-sbt#collections_2.12;1.3.4!collections_2.12.jar (569ms)
downloading https://repo1.maven.org/maven2/org/scala-lang/modules/scala-xml_2.12/1.2.0/scala-xml_2.12-1.2.0.jar ...
    [SUCCESSFUL ] org.scala-sbt#scripted-plugin_2.12;1.3.4!scripted-plugin_2.12.jar (441ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/launcher-interface/1.1.3/launcher-interface-1.1.3.jar ...
    [SUCCESSFUL ] org.scala-sbt#zinc-lm-integration_2.12;1.3.4!zinc-lm-integration_2.12.jar (450ms)
downloading https://repo1.maven.org/maven2/org/apache/logging/log4j/log4j-api/2.11.2/log4j-api-2.11.2.jar ...
    [SUCCESSFUL ] org.scala-sbt#launcher-interface;1.1.3!launcher-interface.jar (454ms)
downloading https://repo1.maven.org/maven2/org/apache/logging/log4j/log4j-core/2.11.2/log4j-core-2.11.2.jar ...
    [SUCCESSFUL ] org.scala-lang.modules#scala-xml_2.12;1.2.0!scala-xml_2.12.jar(bundle) (685ms)
downloading https://repo1.maven.org/maven2/org/apache/logging/log4j/log4j-slf4j-impl/2.11.2/log4j-slf4j-impl-2.11.2.jar ...
    [SUCCESSFUL ] org.apache.logging.log4j#log4j-api;2.11.2!log4j-api.jar (465ms)
downloading https://repo1.maven.org/maven2/com/github/cb372/scalacache-caffeine_2.12/0.20.0/scalacache-caffeine_2.12-0.20.0.jar ...
    [SUCCESSFUL ] org.apache.logging.log4j#log4j-slf4j-impl;2.11.2!log4j-slf4j-impl.jar (469ms)
downloading https://repo1.maven.org/maven2/io/get-coursier/lm-coursier-shaded_2.12/2.0.0-RC5-2/lm-coursier-shaded_2.12-2.0.0-RC5-2.jar ...
    [SUCCESSFUL ] com.github.cb372#scalacache-caffeine_2.12;0.20.0!scalacache-caffeine_2.12.jar (449ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/util-logging_2.12/1.3.2/util-logging_2.12-1.3.2.jar ...
    [SUCCESSFUL ] org.apache.logging.log4j#log4j-core;2.11.2!log4j-core.jar (811ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/librarymanagement-core_2.12/1.3.0/librarymanagement-core_2.12-1.3.0.jar ...
    [SUCCESSFUL ] org.scala-sbt#util-logging_2.12;1.3.2!util-logging_2.12.jar (476ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/librarymanagement-ivy_2.12/1.3.0/librarymanagement-ivy_2.12-1.3.0.jar ...
    [SUCCESSFUL ] org.scala-sbt#librarymanagement-core_2.12;1.3.0!librarymanagement-core_2.12.jar (601ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/compiler-interface/1.3.1/compiler-interface-1.3.1.jar ...
    [SUCCESSFUL ] org.scala-sbt#compiler-interface;1.3.1!compiler-interface.jar (456ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/zinc-compile_2.12/1.3.1/zinc-compile_2.12-1.3.1.jar ...
    [SUCCESSFUL ] org.scala-sbt#librarymanagement-ivy_2.12;1.3.0!librarymanagement-ivy_2.12.jar (687ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/util-relation_2.12/1.3.2/util-relation_2.12-1.3.2.jar ...
    [SUCCESSFUL ] org.scala-sbt#util-relation_2.12;1.3.2!util-relation_2.12.jar (437ms)
downloading https://repo1.maven.org/maven2/com/eed3si9n/sjson-new-scalajson_2.12/0.8.2/sjson-new-scalajson_2.12-0.8.2.jar ...
    [SUCCESSFUL ] org.scala-sbt#zinc-compile_2.12;1.3.1!zinc-compile_2.12.jar (445ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/util-position_2.12/1.3.2/util-position_2.12-1.3.2.jar ...
    [SUCCESSFUL ] com.eed3si9n#sjson-new-scalajson_2.12;0.8.2!sjson-new-scalajson_2.12.jar (448ms)
downloading https://repo1.maven.org/maven2/com/eed3si9n/shaded-scalajson_2.12/1.0.0-M4/shaded-scalajson_2.12-1.0.0-M4.jar ...
    [SUCCESSFUL ] org.scala-sbt#util-position_2.12;1.3.2!util-position_2.12.jar (456ms)
downloading https://repo1.maven.org/maven2/org/spire-math/jawn-parser_2.12/0.10.4/jawn-parser_2.12-0.10.4.jar ...
    [SUCCESSFUL ] com.eed3si9n#shaded-scalajson_2.12;1.0.0-M4!shaded-scalajson_2.12.jar (463ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/completion_2.12/1.3.4/completion_2.12-1.3.4.jar ...
    [SUCCESSFUL ] org.spire-math#jawn-parser_2.12;0.10.4!jawn-parser_2.12.jar (468ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/task-system_2.12/1.3.4/task-system_2.12-1.3.4.jar ...
    [SUCCESSFUL ] org.scala-sbt#completion_2.12;1.3.4!completion_2.12.jar (448ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/tasks_2.12/1.3.4/tasks_2.12-1.3.4.jar ...
    [SUCCESSFUL ] org.scala-sbt#task-system_2.12;1.3.4!task-system_2.12.jar (524ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/testing_2.12/1.3.4/testing_2.12-1.3.4.jar ...
    [SUCCESSFUL ] org.scala-sbt#tasks_2.12;1.3.4!tasks_2.12.jar (455ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/util-tracking_2.12/1.3.2/util-tracking_2.12-1.3.2.jar ...
    [SUCCESSFUL ] org.scala-sbt#testing_2.12;1.3.4!testing_2.12.jar (465ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/zinc-classpath_2.12/1.3.1/zinc-classpath_2.12-1.3.1.jar ...
    [SUCCESSFUL ] org.scala-sbt#util-tracking_2.12;1.3.2!util-tracking_2.12.jar (443ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/zinc-apiinfo_2.12/1.3.1/zinc-apiinfo_2.12-1.3.1.jar ...
    [SUCCESSFUL ] org.scala-sbt#zinc-classpath_2.12;1.3.1!zinc-classpath_2.12.jar (459ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/zinc_2.12/1.3.1/zinc_2.12-1.3.1.jar ...
    [SUCCESSFUL ] org.scala-sbt#zinc-apiinfo_2.12;1.3.1!zinc-apiinfo_2.12.jar (453ms)
downloading https://repo1.maven.org/maven2/jline/jline/2.14.6/jline-2.14.6.jar ...
    [SUCCESSFUL ] org.scala-sbt#zinc_2.12;1.3.1!zinc_2.12.jar (448ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/util-control_2.12/1.3.2/util-control_2.12-1.3.2.jar ...
    [SUCCESSFUL ] org.scala-sbt#main_2.12;1.3.4!main_2.12.jar (9125ms)
downloading https://repo1.maven.org/maven2/com/swoval/file-tree-views/2.1.3/file-tree-views-2.1.3.jar ...
    [SUCCESSFUL ] jline#jline;2.14.6!jline.jar (447ms)
downloading https://repo1.maven.org/maven2/net/java/dev/jna/jna/4.5.0/jna-4.5.0.jar ...
    [SUCCESSFUL ] org.scala-sbt#util-control_2.12;1.3.2!util-control_2.12.jar (451ms)
downloading https://repo1.maven.org/maven2/net/java/dev/jna/jna-platform/4.5.0/jna-platform-4.5.0.jar ...
    [SUCCESSFUL ] net.java.dev.jna#jna;4.5.0!jna.jar (904ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/util-interface/1.3.2/util-interface-1.3.2.jar ...
    [SUCCESSFUL ] com.swoval#file-tree-views;2.1.3!file-tree-views.jar (1016ms)
downloading https://repo1.maven.org/maven2/com/eed3si9n/sjson-new-core_2.12/0.8.3/sjson-new-core_2.12-0.8.3.jar ...
    [SUCCESSFUL ] net.java.dev.jna#jna-platform;4.5.0!jna-platform.jar (839ms)
downloading https://repo1.maven.org/maven2/com/lmax/disruptor/3.4.2/disruptor-3.4.2.jar ...
    [SUCCESSFUL ] org.scala-sbt#util-interface;1.3.2!util-interface.jar (434ms)
downloading https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/3.7.0/protobuf-java-3.7.0.jar ...
    [SUCCESSFUL ] com.eed3si9n#sjson-new-core_2.12;0.8.3!sjson-new-core_2.12.jar (577ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/util-cache_2.12/1.3.2/util-cache_2.12-1.3.2.jar ...
    [SUCCESSFUL ] com.lmax#disruptor;3.4.2!disruptor.jar (676ms)
downloading https://repo1.maven.org/maven2/com/eed3si9n/sjson-new-murmurhash_2.12/0.8.3/sjson-new-murmurhash_2.12-0.8.3.jar ...
    [SUCCESSFUL ] com.eed3si9n#sjson-new-murmurhash_2.12;0.8.3!sjson-new-murmurhash_2.12.jar (444ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/test-agent/1.3.4/test-agent-1.3.4.jar ...
    [SUCCESSFUL ] io.get-coursier#lm-coursier-shaded_2.12;2.0.0-RC5-2!lm-coursier-shaded_2.12.jar (7176ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/test-interface/1.0/test-interface-1.0.jar ...
    [SUCCESSFUL ] com.google.protobuf#protobuf-java;3.7.0!protobuf-java.jar(bundle) (1011ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/compiler-bridge_2.12/1.3.1/compiler-bridge_2.12-1.3.1.jar ...
    [SUCCESSFUL ] org.scala-sbt#util-cache_2.12;1.3.2!util-cache_2.12.jar (987ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/zinc-classfile_2.12/1.3.1/zinc-classfile_2.12-1.3.1.jar ...
    [SUCCESSFUL ] org.scala-sbt#test-agent;1.3.4!test-agent.jar (449ms)
downloading https://repo1.maven.org/maven2/com/jcraft/jsch/0.1.54/jsch-0.1.54.jar ...
    [SUCCESSFUL ] org.scala-sbt#test-interface;1.0!test-interface.jar (443ms)
downloading https://repo1.maven.org/maven2/com/eed3si9n/gigahorse-okhttp_2.12/0.5.0/gigahorse-okhttp_2.12-0.5.0.jar ...
    [SUCCESSFUL ] org.scala-sbt#compiler-bridge_2.12;1.3.1!compiler-bridge_2.12.jar (446ms)
downloading https://repo1.maven.org/maven2/com/squareup/okhttp3/okhttp-urlconnection/3.7.0/okhttp-urlconnection-3.7.0.jar ...
    [SUCCESSFUL ] com.jcraft#jsch;0.1.54!jsch.jar (459ms)
downloading https://repo1.maven.org/maven2/com/eed3si9n/gigahorse-core_2.12/0.5.0/gigahorse-core_2.12-0.5.0.jar ...
    [SUCCESSFUL ] org.scala-sbt#zinc-classfile_2.12;1.3.1!zinc-classfile_2.12.jar (670ms)
downloading https://repo1.maven.org/maven2/com/squareup/okhttp3/okhttp/3.14.2/okhttp-3.14.2.jar ...
    [SUCCESSFUL ] com.eed3si9n#gigahorse-okhttp_2.12;0.5.0!gigahorse-okhttp_2.12.jar (452ms)
downloading https://repo1.maven.org/maven2/com/typesafe/ssl-config-core_2.12/0.4.0/ssl-config-core_2.12-0.4.0.jar ...
    [SUCCESSFUL ] com.squareup.okhttp3#okhttp-urlconnection;3.7.0!okhttp-urlconnection.jar (447ms)
downloading https://repo1.maven.org/maven2/org/reactivestreams/reactive-streams/1.0.2/reactive-streams-1.0.2.jar ...
    [SUCCESSFUL ] com.eed3si9n#gigahorse-core_2.12;0.5.0!gigahorse-core_2.12.jar (475ms)
downloading https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.26/slf4j-api-1.7.26.jar ...
    [SUCCESSFUL ] org.reactivestreams#reactive-streams;1.0.2!reactive-streams.jar (454ms)
downloading https://repo1.maven.org/maven2/org/scala-lang/modules/scala-parser-combinators_2.12/1.1.2/scala-parser-combinators_2.12-1.1.2.jar ...
    [SUCCESSFUL ] com.typesafe#ssl-config-core_2.12;0.4.0!ssl-config-core_2.12.jar(bundle) (1013ms)
downloading https://repo1.maven.org/maven2/com/typesafe/config/1.3.3/config-1.3.3.jar ...
    [SUCCESSFUL ] org.slf4j#slf4j-api;1.7.26!slf4j-api.jar (783ms)
downloading https://repo1.maven.org/maven2/com/squareup/okio/okio/1.17.2/okio-1.17.2.jar ...
    [SUCCESSFUL ] org.scala-lang.modules#scala-parser-combinators_2.12;1.1.2!scala-parser-combinators_2.12.jar(bundle) (690ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/zinc-core_2.12/1.3.1/zinc-core_2.12-1.3.1.jar ...
    [SUCCESSFUL ] com.squareup.okhttp3#okhttp;3.14.2!okhttp.jar (1709ms)
    [SUCCESSFUL ] com.typesafe#config;1.3.3!config.jar(bundle) (693ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/zinc-persist_2.12/1.3.1/zinc-persist_2.12-1.3.1.jar ...
downloading https://repo1.maven.org/maven2/org/scala-sbt/zinc-compile-core_2.12/1.3.1/zinc-compile-core_2.12-1.3.1.jar ...
    [SUCCESSFUL ] org.scala-sbt#zinc-core_2.12;1.3.1!zinc-core_2.12.jar (788ms)
downloading https://repo1.maven.org/maven2/com/trueaccord/scalapb/scalapb-runtime_2.12/0.6.0/scalapb-runtime_2.12-0.6.0.jar ...
    [SUCCESSFUL ] org.scala-sbt#zinc-compile-core_2.12;1.3.1!zinc-compile-core_2.12.jar (672ms)
downloading https://repo1.maven.org/maven2/com/trueaccord/lenses/lenses_2.12/0.4.12/lenses_2.12-0.4.12.jar ...
    [SUCCESSFUL ] com.squareup.okio#okio;1.17.2!okio.jar (1405ms)
downloading https://repo1.maven.org/maven2/com/lihaoyi/fastparse_2.12/0.4.2/fastparse_2.12-0.4.2.jar ...
    [SUCCESSFUL ] com.trueaccord.lenses#lenses_2.12;0.4.12!lenses_2.12.jar (481ms)
downloading https://repo1.maven.org/maven2/com/lihaoyi/fastparse-utils_2.12/0.4.2/fastparse-utils_2.12-0.4.2.jar ...
    [SUCCESSFUL ] com.lihaoyi#fastparse_2.12;0.4.2!fastparse_2.12.jar (635ms)
downloading https://repo1.maven.org/maven2/com/lihaoyi/sourcecode_2.12/0.1.3/sourcecode_2.12-0.1.3.jar ...
    [SUCCESSFUL ] com.lihaoyi#fastparse-utils_2.12;0.4.2!fastparse-utils_2.12.jar (478ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/sbinary_2.12/0.5.0/sbinary_2.12-0.5.0.jar ...
    [SUCCESSFUL ] com.trueaccord.scalapb#scalapb-runtime_2.12;0.6.0!scalapb-runtime_2.12.jar (1505ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/core-macros_2.12/1.3.4/core-macros_2.12-1.3.4.jar ...
    [SUCCESSFUL ] com.lihaoyi#sourcecode_2.12;0.1.3!sourcecode_2.12.jar (482ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/protocol_2.12/1.3.4/protocol_2.12-1.3.4.jar ...
    [SUCCESSFUL ] org.scala-sbt#core-macros_2.12;1.3.4!core-macros_2.12.jar (518ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/template-resolver/0.1/template-resolver-0.1.jar ...
    [SUCCESSFUL ] org.scala-sbt#sbinary_2.12;0.5.0!sbinary_2.12.jar (743ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/ipcsocket/ipcsocket/1.0.0/ipcsocket-1.0.0.jar ...
    [SUCCESSFUL ] org.scala-sbt#template-resolver;0.1!template-resolver.jar (441ms)
downloading https://repo1.maven.org/maven2/org/scala-lang/scala-compiler/2.12.10/scala-compiler-2.12.10.jar ...
    [SUCCESSFUL ] org.scala-sbt.ipcsocket#ipcsocket;1.0.0!ipcsocket.jar (455ms)
downloading https://repo1.maven.org/maven2/org/scala-lang/scala-reflect/2.12.10/scala-reflect-2.12.10.jar ...
    [SUCCESSFUL ] org.scala-sbt#protocol_2.12;1.3.4!protocol_2.12.jar (1202ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/util-scripted_2.12/1.3.2/util-scripted_2.12-1.3.2.jar ...
    [SUCCESSFUL ] org.scala-sbt#util-scripted_2.12;1.3.2!util-scripted_2.12.jar (450ms)
downloading https://repo1.maven.org/maven2/com/github/cb372/scalacache-core_2.12/0.20.0/scalacache-core_2.12-0.20.0.jar ...
    [SUCCESSFUL ] com.github.cb372#scalacache-core_2.12;0.20.0!scalacache-core_2.12.jar (457ms)
downloading https://repo1.maven.org/maven2/com/github/ben-manes/caffeine/caffeine/2.5.6/caffeine-2.5.6.jar ...
    [SUCCESSFUL ] com.github.ben-manes.caffeine#caffeine;2.5.6!caffeine.jar (1017ms)
downloading https://repo1.maven.org/maven2/org/scala-sbt/ivy/ivy/2.3.0-sbt-cb9cc189e9f3af519f9f102e6c5d446488ff6832/ivy-2.3.0-sbt-cb9cc189e9f3af519f9f102e6c5d446488ff6832.jar ...
    [SUCCESSFUL ] org.scala-sbt#zinc-persist_2.12;1.3.1!zinc-persist_2.12.jar (5683ms)
    [SUCCESSFUL ] org.scala-sbt.ivy#ivy;2.3.0-sbt-cb9cc189e9f3af519f9f102e6c5d446488ff6832!ivy.jar (1037ms)
    [SUCCESSFUL ] org.scala-lang#scala-reflect;2.12.10!scala-reflect.jar (6224ms)
    [SUCCESSFUL ] org.scala-lang#scala-compiler;2.12.10!scala-compiler.jar (8766ms)
:: retrieving :: org.scala-sbt#boot-app
    confs: [default]
    81 artifacts copied, 0 already retrieved
[info] [launcher] getting Scala 2.12.10 (for sbt)...
downloading https://repo1.maven.org/maven2/org/scala-lang/modules/scala-xml_2.12/1.0.6/scala-xml_2.12-1.0.6.jar ...
downloading https://repo1.maven.org/maven2/org/fusesource/jansi/jansi/1.12/jansi-1.12.jar ...
    [SUCCESSFUL ] org.fusesource.jansi#jansi;1.12!jansi.jar (1318ms)
    [SUCCESSFUL ] org.scala-lang.modules#scala-xml_2.12;1.0.6!scala-xml_2.12.jar(bundle) (2602ms)
:: retrieving :: org.scala-sbt#boot-scala
    confs: [default]
    6 artifacts copied, 0 already retrieved
[info] Loading project definition from /home/zsh/cdk/project
[info] Loading settings for project cdk from build.sbt ...
[info] Set current project to hello-world (in build file:/home/zsh/cdk/)
[warn] There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings.
[info] Compiling 2 Scala sources to /home/zsh/cdk/target/scala-2.13/classes ...
[info] Non-compiled module 'compiler-bridge_2.13' for Scala 2.13.1. Compiling...
8 warnings found
[info]   Compilation completed in 7.349s.
[info] Done compiling.
[info] running com.myorg.CdkApp 
[success] Total time: 27 s, completed Dec 10, 2019 2:32:33 PM
CdkStack
[zsh@bd8ee7c9cbb6 cdk (master *+%)]$ 

cdk.json の記述を変えれば Gradle などでも動きそうですね。

cdk deploy

[zsh@bd8ee7c9cbb6 cdk (master *+%)]$cdk deploy
[info] Loading project definition from /home/zsh/cdk/project
[info] Loading settings for project cdk from build.sbt ...
[info] Set current project to hello-world (in build file:/home/zsh/cdk/)
[info] running com.myorg.CdkApp 
[success] Total time: 2 s, completed Dec 10, 2019 2:33:53 PM
CdkStack: deploying...
CdkStack: creating CloudFormation changeset...
 0/2 | 2:34:07 PM | CREATE_IN_PROGRESS   | AWS::CDK::Metadata | CDKMetadata 
 0/2 | 2:34:09 PM | CREATE_IN_PROGRESS   | AWS::CDK::Metadata | CDKMetadata Resource creation Initiated
 1/2 | 2:34:09 PM | CREATE_COMPLETE      | AWS::CDK::Metadata | CDKMetadata 
 2/2 | 2:34:11 PM | CREATE_COMPLETE      | AWS::CloudFormation::Stack | CdkStack 

 ✅  CdkStack

Stack ARN:
arn:aws:cloudformation:us-west-2:XXXXXXXXXXXX:stack/CdkStack/xxxxxxxx-xxxx-xxxx-xxxx-067aa3cae1e0
[zsh@bd8ee7c9cbb6 cdk (master *+%)]$ 

これで CloudFormation Stack が出来ました。 f:id:poad1010:20191210233704p:plain

当然ながら、それで作られるリソースも居ます。 f:id:poad1010:20191210233810p:plain

cdk destroy

cdkで作ったStackやリソースを削除するには、 cdk destroy を使います。

[zsh@bd8ee7c9cbb6 cdk (master *+%)]$ cdk destroy
[info] Loading project definition from /home/zsh/cdk/project
[info] Loading settings for project cdk from build.sbt ...
[info] Set current project to hello-world (in build file:/home/zsh/cdk/)
[info] running com.myorg.CdkApp 
[success] Total time: 2 s, completed Dec 10, 2019 2:38:36 PM
Are you sure you want to delete: CdkStack (y/n)? y
CdkStack: destroying...

 ✅  CdkStack: destroyed
[zsh@bd8ee7c9cbb6 cdk (master *+%)]$ 

これで CloudFormation Stack が削除されました。 f:id:poad1010:20191210234013p:plain f:id:poad1010:20191210234024p:plain

流石に CloudFormation や CDK の API は調べていただくということで、説明はここまでとなります。

まとめ

以下の設定を行うだけで、とても簡単にAWS CDK を Scala で使うことが出来ました。

ただし、CDKのAPIが良くできていて、Scalaでやるメリットは大きくはなさそうです。(メリットがあるケースはアプリもScalaだから、CDKもScalaで使いたいといった言った程度でしょうか?)

検証コード

今回作った検証コードは こちら