【アプリもインフラも1つの言語で書ける】Wingのチュートリアルをやってみる

2023.08.31

最近Infrastructure from Code (IfC) という概念を知りました。

とりあえず、触って雰囲気を掴みたいと思いWingのチュートリアルをやってみました。

Wingとは

Wingとはクラウド向けのプログラミング言語です。

WingLangという独自の言語を使って、インフラとアプリを1つの言語で同時にコーディングできます。

公式サイト内のイントロダクションの動画が分かりやすくて、おすすめです。(15分と短くて見やすいです)

WingLangをコンパイルして、AWSやGCP、Azureなどに対応したTerraformやCDK、CFnを生成することができます。(2023/8時点では、AWSとTerraformに対応しています。)

AWS SDK等を使ったアプリケーションコードに関しても、同様に生成されます。

下記は実際のコードと作成されるAWSリソースです。

チュートリアルをやってみる

今回はローカルにインストールしてやってみます。エディタはVSCodeを使います。

ブラウザで試せるPlayGroudも用意されています。

Getting started | Wing

準備

以下をインストールしておきます。

AWS上にデプロイする際には、winglangからtfファイルを生成してTerraformを使ってデプロイします。

そのため、TerraformやAWS CLIも必要になります。

アプリケーションの作成

以下、ファイルを用意します。

hello.w

bring cloud;

let bucket = new cloud.Bucket();
let counter = new cloud.Counter(initial: 1);
let queue = new cloud.Queue();

queue.setConsumer(inflight (message: str) => {
  let index = counter.inc();
  bucket.put("wing-${index}.txt", "Hello, ${message}");
  log("file wing-${index}.txt created");
});

コードの内容としては、メッセージにキューが追加されるたびにカウントを追加してバケットにwing-${index}.txtを追加するものです。

Winglangという独自言語を使います。

WinglangにはPreflightとInflightという概念があります。

詳細は公式ドキュメントにて説明されています。

ざっくりいうと、Preflightはインフラコード、Inflightはアプリケーションコードという理解で良いかと思います。

上記のコード中では、inflightから始まるブロック(ハイライト部分)がInflightでほかはPreflightになります。

ローカル実行

Wingではローカルで実行して、リソースの動作を試すことができます。

以下のコマンドを実行すると、Wingコンソールがブラウザで開かれます。

$ wing it hello.w

ちなみにWingの拡張機能を使っている場合、VSCodeで開くこともできます。

コマンドパレットからOpen in Wing Consoleを選択すると以下のように表示されます。

リソースを可視化してくれるだけでも凄いんですが、データの入出力をテストすることができます。

今回のコードであれば、以下の一連の流れをローカルで確認できます。

  1. キューにメッセージを送信
  2. カウンターがカウントをインクリメント
  3. バケットにファイルを保存

キューに「test」というメッセージを送信します。

カウンターを確認すると、カウントがインクリメントされています。

バケットを確認するとwing-1.txtというファイルが作成されることを確認できます。

ファイルの内容にもメッセージで渡した値が入っていることを確認できました。

クラウドリソースのローカルテストは悩みどころが多いので、助かりますね。

AWS上にデプロイ

現時点では、Terraformを使ったAWSへのデプロイがサポートされています。

将来的には、AzureやGoogle Cloud、プロビジョニングツールとしてCFn等をサポートされるそうです。

Deploy to AWS | Wing

Wingのファイルをtfファイルに変換します。

$ wing compile --target tf-aws hello.w

tfファイルはtarget/hello.tfaws配下に作成されます。 main.tf.jsonにリソースの定義が書いています。

貼ると長くなるので省略しますが、DynamoDBやSQS、S3が定義されています。 winglangは10行程度ですが、200行程度(jsonですが)の定義が作成されました。

あとは、ディレクトリに移動してterraformを使ってリソースを作成します。

$ cd target/hello.tfaws
$ export AWS_REGION="ap-northeast-1"
$ # AWS認証情報をセット
$ terraform init
$ terraform apply

動作確認

ローカルと同様に確認していきます。

  1. キューにメッセージを送信
  2. カウンターがカウントをインクリメント
  3. バケットにファイルを保存

実際に作成されるAWSリソースと関連付けると以下になります。

まずはキュー(SQS)でメッセージを送信します。

カウンタとバケットを更新する用のLambdaが実行されていました。

カウンタ(DynamoDB)のcounterは2になっており、インクリメントされたことが分かります。

バケットを確認すると、wing-1.txtが作成されていました。

ファイルの中身も想定どおりの値になっています。

StateファイルをS3バックエンドに保管

デフォルトではStateファイルのバックエンドがローカルになります。

ローカルではCI/CDや複数人で作業をする際に、困ってしまいます。

ドキュメントを確認すると、解決策ありました。

Terraform Backends | Wing

バックエンドにS3を利用可能でした。詳細はドキュメント内で確認できます。

ざっくり書くと、以下のステップでできます。

  1. plugin.static-backend.jsにバックエンドを定義
  2. wing compileする

ちなみに、CI/CDに関してもGitHub Actionsを例にしてドキュメントに説明されていました。

CI/CD | Wing

おわりに

Wingのチュートリアルについてでした。

かなり少ない記述でインフラとアプリを作成することができます。ローカルのシミュレータも使いやすくて便利でした。

高度に抽象化されており、特定のユースケースでは開発効率がとても高そうです。

今後の発展が楽しみです。

以上、AWS事業本部の佐藤(@chari7311)でした。