AWS App Runner に ECR をトリガーに自動デプロイをしてみた

# はじめに

[前回の記事](https://qiita.com/sugimount-a/items/c0b32f1d1152104c1666)では、ECR に Push したコンテナイメージを App Runner にデプロイする方法を紹介しました。

今回の記事では、ECR に新しいバージョンのコンテナイメージを Push することで、自動でバージョンアップ(Blue Green デプロイ)されることを確認します。

デプロイの詳細な流れは、下記の App Runner 入門動画に公開されています。

https://www.youtube.com/watch?v=1-A5XlwM7Xg

![image-20220214202835660.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/fcda1ff6-ba4d-c5bf-cef9-bfefbb3b2a2a.png)



# 前提条件

App Runner の Service を構成するときに、Deployment settings を Automatic に設定していることが条件です。

![image-20220214200528285.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/c1d0a35c-790f-4eca-a414-e69c164f3387.png)



# バージョンアップ前

App Runner で稼働しているアプリケーションは、次の状態になっています。

![image-20220214200753359.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/c13a8af6-df2e-74f7-202f-37ffe2974ead.png)



# コンテナをバージョンアップして ECR に Push

Go言語のプログラムを変更して、バージョンに関する文字列を付与します。

```golang
package main

import (
	"database/sql"
	"fmt"
	"net"
	"net/http"
	"os"
	"time"

	_ "github.com/go-sql-driver/mysql"
)

var db *sql.DB

func handler(w http.ResponseWriter, r *http.Request) {
	// バージョンの表示
	fmt.Fprintf(w, "バージョン2\n")
	fmt.Fprintf(w, "\n")

	// MySQL のデータを表示
	row := db.QueryRow(`select * from sample`)

	var id, name string
	row.Scan(&id, &name)

	println(name)

	fmt.Fprintf(w, name+"\n")
	fmt.Fprintf(w, "\n")

	// ローカルのIPアドレスを表示
	fmt.Fprintf(w, "IPアドレス一覧"+"\n")

	interfaces, err := net.Interfaces()
	if err != nil {
		fmt.Println(err)
		return
	}
	for _, inter := range interfaces {
		addrs, err := inter.Addrs()
		if err != nil {
			fmt.Println(err)
			return
		}
		for _, a := range addrs {
			if ipnet, ok := a.(*net.IPNet); ok {
				if ipnet.IP.To4() != nil {
					fmt.Println(ipnet.IP.String())
					fmt.Fprintf(w, ipnet.IP.String()+"\n")
				}
			}
		}
	}

}

func main() {
	// MySQL のコネクションを取得
	mysql_hostname := os.Getenv("MYSQL_HOSTNAME")
	mysql_port := os.Getenv("MYSQL_PORT")
	mysql_username := os.Getenv("MYSQL_USERNAME")
	mysql_password := os.Getenv("MYSQL_PASSWORD")

	var err error

	db, err = sql.Open("mysql", mysql_username+":"+mysql_password+"@tcp("+mysql_hostname+":"+mysql_port+")/sugi01")
	if err != nil {
		println("MySQL のコネクション接続に失敗")
		panic(err)
	}
	defer db.Close()

	db.SetConnMaxLifetime(time.Minute * 3)
	db.SetMaxOpenConns(10)
	db.SetMaxIdleConns(10)

	http.HandleFunc("/", handler) // ハンドラを登録してウェブページを表示させる
	http.ListenAndServe(":8080", nil)
}
```



アプリケーションを動かし、動作確認をします。

```
go run app.go
```



トップに「バージョン2」という文字を表示するようにしました。これで、どのバージョンが稼働しているかわかりやすいです。

![image-20220214201212749.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/b479d1ba-dc56-1719-5ff6-3a31f01548dc.png)



go プログラムをビルドします。

```
go build -o app
```



Docker Image を Build します。

```
docker image build -t xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/app-runner-testapp:0.0.2 .
docker image build -t xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/app-runner-testapp:latest .
```



ECR に Push します

```
docker push xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/app-runner-testapp:0.0.2
docker push xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/app-runner-testapp:latest
```



ECR に Push されました

![image-20220214201618801.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/043342a1-3ee5-248a-c841-3a11db86fe6a.png)



# App Runner で自動更新

ECR に Push したことをトリガーに、新しいバージョンのデプロイプロセスが走ります。

![image-20220214201554085.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/8a8ebecb-38e1-905e-f521-fb6b40b9e69c.png)



この Operation 中でも、問題なく前のバージョンのアプリケーションにアクセスできます。この記事の環境だと、約2分ほど待つと Status が Running になりました。

![image-20220214202137181.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/a5fdf863-c72a-e39c-a803-0e3b16f3f5b9.png)



App Runner の Service にアクセスしてみると、正常にバージョンアップがされています。

![image-20220214202156656.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/c84f4790-346b-8f47-c4d3-f191a9394ea3.png)



# まとめ

App Runner の設定で自動デプロイを有効にすることで、ECR の更新をトリガーにした 自動 Blue Green デプロイメントを行うことが出来ました。CD パイプラインを自分たちで組む必要がないので、とても簡単で体験が良いですね。