PulumiのGoでAWS App Runnerを構築する


## Pulumiってなに？

以前書いた記事の通り、インフラのプロビジョニングツールです。

https://qiita.com/runeleaf/items/0e2b69bae38164aa826a

今回はGoでAWSのApp Runner環境を構築してみます。

前回からだいぶ間が空いているのですが、変わったことといえばPulumi 3.0がリリースされたこと、AWSネイティブプロバイダーを発表したことでしょうか。

https://www.infoq.com/jp/news/2021/11/pulumi-aws-native-provider/

なにがどう変わったのか細かく見るのもアレなので今回はPulumiでApp Runnerの環境をつくりたいと思います。

ちなみにまだRubyには対応していない。

## 準備



macOS Big Sur

```
$ sw_vers
ProductName:    macOS
ProductVersion: 11.6
```

```
$ pulumi version
v3.20.0
```

AWS環境変数設定

```
$ export AWS_REGION=ap-northeast-1
$ export AWS_PROFILE=<YOUR_PROFILE>
$ export AWS_ACCESS_KEY_ID=<YOUR_ACCESS_KEY_ID>
$ export AWS_SECRET_ACCESS_KEY=<YOUR_SECRET_ACCESS_KEY>
```

```
$ pulumi config set aws:profile runeleaf
```

Githubからアプリのソースコードを取得するので用意しておきます。Next.jsでささっと。

https://github.com/runeleaf/pulumi-app-example

## コードを書く

VPCやらALBやらは気にしなくていいので環境のみ構築します。

ワークスペースの作成

```
$ mkdir pulumi-apprunner
$ cd pulumi-apprunner
$ pulumi new aws-go
```

スタックの設定

```
$ pulumi stack init prod
$ pulumi stack select dev
```

ファイル構成

```
$ ls -T
.
├── apprunner.go
├── go.mod
├── go.sum
├── main.go
├── Pulumi.dev.yaml
└── Pulumi.yaml
```



コードを抜粋していきます。

#### main.go

```golang
package main

import (
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		apprunner, err := createAppRunner(ctx)
		if err != nil {
			return err
		}

		ctx.Export("App Runner", apprunner.ID())
		return nil
	})
}

```

main.goには構築するスタックを記述しておきます。今回はApp Runnerだけですが、FagateやRDSなども構築する場合はそれぞれfagate.goやrds.goなどにファイルを分割しておくのがよさそうです。

#### apprunner.go

```golang
package main

import (
	"os"

	"github.com/pulumi/pulumi-aws/sdk/v4/go/aws/apprunner"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func createAppRunner(ctx *pulumi.Context) (*apprunner.Service, error) {
	repository := pulumi.String("https://github.com/runeleaf/pulumi-app-example")
	arn := os.Getenv("GITHUB_CONNECTION_ARN")

	res, err := apprunner.NewService(ctx, "pulumi-app-example", &apprunner.ServiceArgs{
		ServiceName: pulumi.String("pulumi-app-example"),
		SourceConfiguration: &apprunner.ServiceSourceConfigurationArgs{
			AuthenticationConfiguration: &apprunner.ServiceSourceConfigurationAuthenticationConfigurationArgs{
				ConnectionArn: pulumi.String(arn),
			},
			CodeRepository: &apprunner.ServiceSourceConfigurationCodeRepositoryArgs{
				CodeConfiguration: &apprunner.ServiceSourceConfigurationCodeRepositoryCodeConfigurationArgs{
					CodeConfigurationValues: &apprunner.ServiceSourceConfigurationCodeRepositoryCodeConfigurationCodeConfigurationValuesArgs{
						BuildCommand: pulumi.String("npm install && npm run build"),
						Port:         pulumi.String("3000"),
						Runtime:      pulumi.String("NODEJS_12"),
						StartCommand: pulumi.String("npm start"),
					},
					ConfigurationSource: pulumi.String("API"),
				},
				RepositoryUrl: repository,
				SourceCodeVersion: &apprunner.ServiceSourceConfigurationCodeRepositorySourceCodeVersionArgs{
					Type:  pulumi.String("BRANCH"),
					Value: pulumi.String("main"),
				},
			},
		},
	})

	if err != nil {
		return nil, err
	}

	return res, nil
}

```

最終的なコードは以下のリポジトリにあります。

https://github.com/runeleaf/pulumi-apprunner

`GITHUB_CONNECTION_ARN`はAWSのWeb ConsoleからApp Runner > Github connectionsで確認することができます。

pulumi up時に新規でGithub接続を作成してApp Runnerの構築をする場合は`apprunner.NewConnection`にてGithub接続を作成し、それを利用する流れがよいのかなと。

#### ビルド

```
$ go get .
```

#### デプロイ

```
$ pulumi up -d -r
...ry)
```



## 所感

typescriptのほうが若干書きやすいかもですが、goでもそこまで変わらずに書くことができます。

なによりCloudFormationと比べたらpulumiのwebコンソールは見やすいのでとてもよいことだと感じています。

以前に比べたらドキュメントもだいぶ充実してきています。

AWSだけならCDKでいいのでは？とか、terraformから逃れられないとか、様々な事情はあると思いますが、近年バックエンドのAPIをマルチクラウドで提供する場面が増えてきていることを考えると、Pulumiを採用するのはとても使いやすいので選択肢としてはかなりよいと思います。



*Infrastructure as Code!!*