8
1

More than 1 year has passed since last update.

AWS App Runner で、VPC Connector を使って Amazon RDS に接続してみた

Posted at

はじめに

2022年2月8日(米国時間)に、AWS App Runner にて Amazon VPC 接続用の機能が追加されました。アップデート前は、VPC 内にホストされている Amazon RDS などのサービスに接続することが出来ませんでした。このアップデートにより、VPC 内にホストされている RDS をはじめとした、各種サービスと連携ができるようになりました!

AWS では、VPC 内でホストされているサービスがあるため、ユースケースが広がるアップデートとなります。詳細は次のブログを参照してください。

また、このアップデートの留意点としては、App Runner にアクセスする経路は変わらずインターネットをつかったアクセスが必要です。アクセス元 → App Runner 方向のインバウンドトラフィックは、インターネットを経由した接続が必要で、App Runner → なにか 方向のアウトバウンドトラフィックは、自分たちが管理している VPC の経路をつかった接続となります。詳細は次のブログを参照してください。

image-20220214024159630.png

今回の記事は、Go 言語で作成した Docker Image を使って、VPC 内に構成している RDS for MySQL と接続する App Runner を作成してみる記事となります。

Go言語で動作確認用プログラムを作成

MySQL と接続するための Go言語のプログラムをローカル環境で作成します。エラーハンドリングなどは省略しているので、本番環境での利用はダメです。ローカルで開発するため、接続先の MySQL の情報は環境変数化しています。

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) {
    // 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)
}

ローカル環境では、Docker を使って MySQL を動かしている必要があります。詳細はこちらの記事に記載しております。

ローカルで、MySQL を動かしたうえで、Go 言語のプログラムの動作確認をしていきます。

go run app.go

ブラウザからアクセスすると、MySQL から取得した「MySQLのデータ」と、コンテナに付与されている IP アドレス一覧が表示されます。

image-20220214020450613.png

Go言語のプログラムをBuildします。

go build -o app

app ファイルがビルドされました。

> ls -la
total 6576
drwxr-xr-x 2 ec2-user docker      76 Feb 14 01:31 .
drwxr-xr-x 5 ec2-user docker      74 Feb 14 00:00 ..
-rwxr-xr-x 1 ec2-user docker 6714375 Feb 14 01:31 app
-rw-r--r-- 1 ec2-user docker    1567 Feb 14 01:28 app.go
-rw-r--r-- 1 ec2-user docker      87 Feb 14 01:30 Dockefile
-rw-r--r-- 1 ec2-user docker     101 Feb 14 00:55 go.mod
-rw-r--r-- 1 ec2-user docker     179 Feb 14 00:10 go.sum

ECR Repository 作成

これから Docker Image を作成していくのですが、Docker Image を保管するための ECR Repository を用意していきます。ECR の画面を開いて、Create Repository を押します。

image-20220214014643992.png

Repository 名を入力します。

image-20220214014815414.png

Create Repository を選択します。

image-20220214014832045.png

作成されました。

image-20220214014933307.png

Docker Image Build

次に、手元の環境で Docker Image を Build していきます。次のように Dockerfile を作成します。

  • ベースのイメージは、ECR Public にある Golang 1.16 のものを利用
  • Build した Go 言語のプログラムを、/workdir に格納
  • 8080 ポートを EXPOSE
FROM public.ecr.aws/docker/library/golang:1.16

RUN mkdir /workdir
COPY app /workdir

EXPOSE 8080
CMD ["/workdir/app"]

作成した ECR Repository を指定して、Docker Build を行います。

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

作成した Docker Image を使って、動作確認をします。

  • MySQL はローカルの Docker で稼働している前提 (172.17.0.2 の IP アドレスは、MySQL コンテナの IP アドレス)
docker run \
-it \
--env MYSQL_HOSTNAME=172.17.0.2 \
--env MYSQL_PORT=3306 \
--env MYSQL_USERNAME=root \
--env MYSQL_PASSWORD=mypassword \
-e BIND-ADDRESS=0.0.0.0 \
-p 8080:8080 \
xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/app-runner-testapp:0.0.1

ブラウザから動作確認をします。正常に稼働しています。

image-20220214020546187.png

ECR に Push

正常に Docker Image が作成できたので、ECR に Push していきます。まず、Login をします。

aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com

Login 後、ECR に Push を行います。

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

ECR に Push されています。

image-20220214020823610.png

latest tag も付与して Push をします。

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

image-20220214030554941.png

RDS の準備

App Runner から接続するための、RDS for MySQL を作成しました。

image-20220214021034385.png

これに、テストデータを入れていきましょう。

mysql -u admin -h single-rds01.chuxmuzmrpgx.ap-northeast-1.rds.amazonaws.com -p

テストデータを入れます。

CREATE DATABASE sugi01;
USE sugi01;

CREATE TABLE sample(
  id INT(11) NOT NULL AUTO_INCREMENT,
  name VARCHAR(10) NOT NULL,
  PRIMARY KEY (id)
);

INSERT INTO sample(name) VALUES ("RDSのデータ");

テストデータが格納されているか確認です。

mysql> SELECT * FROM sugi01.sample;
+----+-----------------+
| id | name            |
+----+-----------------+
|  3 | RDSのデータ     |
+----+-----------------+
1 row in set (0.00 sec)

App Runner の作成

それでは、App Runner で Service を作成していき、ECR に Push したコンテナイメージを動かしていきましょう。Create service を選びます。

image-20220214021428735.png

ECR 上で作成したコンテナイメージを指定します。

image-20220214021658794.png

Deployment settings は、Automatic にしておきます。これにより、latest イメージが更新されたときに、自動デプロイを行うようにします。

image-20220214021733415.png

Service の名前や、環境変数などを指定していきます。Go 言語のアプリケーションに渡すための、RDS の接続情報を与えましょう。

MYSQL_HOSTNAME single-rds01.chuxmuzmrpgx.ap-northeast-1.rds.amazonaws.com
MYSQL_PORT 3306
MYSQL_USERNAME admin
MYSQL_PASSWORD yourpassword

image-20220214022021271.png

Auto Scaling デフォルトのままにします。

image-20220214022047082.png

Health Check はデフォルトのままにします。

image-20220214022100593.png

Security もデフォルトのままにします。

image-20220214022119672.png

Networking では、RDS と接続するために、VPC Connector を作成していきます。

image-20220214022156317.png

VPC connector の名前や、接続する VPC, Subnet, Security Group などを指定します。

image-20220214023223464.png

指定された状態です。

image-20220214023243974.png

Next

image-20220214023254390.png

Create & Deploy を押します。

image-20220214023304982.png

Service の Deploy が走ります。

image-20220214023343280.png

一定時間後、Deploy が完了します。

image-20220214031400730.png

アクセス確認

該当のドメインにアクセスすると、作成したコンテナイメージが正常に稼働していることがわかります。RDS と接続が出来ており、「RDSのデータ」と表示さされています。

image-20220214031432175.png

8
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
1