AWS Copilot CLIでECSにgRPCサーバーをデプロイできるようになったよ
こちらのv1.13.0リリースにてCopilotでECSにgRPCサーバーをデプロイできるようになりました。
自分で出したPRということもあり、せっかくなので試してみたいとおもいます。
せっかちな人へ
GitHubにソースコードあげてます。
セットアップ
- Copilot CLIインストール
 
brew install aws/tap/copilot-cli
既にインストール済みの方は
brew upgrade aws/tap/copilot-cli
- protobufインストール
 
brew install protobuf
- go install
 
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.26
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.1
- grpcurlのインストール
 
brew install grpcurl
gRPCサーバーの作成
- mod init
 
go mod init helloworld
- go get
 
go get google.golang.org/grpc google.golang.org/protobuf
- protobuf
 
syntax = "proto3";
package helloworld;
option go_package = "./;helloworld";
// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (Empty) returns (HelloReply) {}
}
message Empty {}
// The response message containing the greetings
message HelloReply {
  string message = 1;
}
- generate code
 
protoc -I proto \
  --go_out proto/gen \
  --go_opt paths=source_relative \
  --go-grpc_out proto/gen \
  --go-grpc_opt paths=source_relative \
  proto/helloworld.proto
- main code
 
package main
import (
 "context"
 "log"
 "net"
 pb "helloworld/proto/gen"
 "google.golang.org/grpc"
)
type server struct {
 pb.UnimplementedGreeterServer
}
func (s *server) SayHello(ctx context.Context, in *pb.Empty) (*pb.HelloReply, error) {
 return &pb.HelloReply{Message: "Hello World"}, nil
}
func main() {
 lis, err := net.Listen("tcp", ":50051")
 if err != nil {
  log.Fatalf("failed to listen: %v", err)
 }
 s := grpc.NewServer()
 pb.RegisterGreeterServer(s, &server{})
 if err := s.Serve(lis); err != nil {
  log.Fatalf("failed to serve: %v", err)
 }
}
- Dockerfile
 
FROM golang:1.17 AS builder
RUN mkdir /app
ADD . /app
WORKDIR /app
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64  go build -o grpc ./
FROM alpine:latest
COPY  /app ./
RUN chmod +x ./grpc
ENTRYPOINT ["./grpc"]
EXPOSE 50051
- docker build
 
docker build -t helloworld .
- docker run
 
docker run --rm helloworld
- send request
 
$ grpcurl \
-plaintext \
-import-path proto \
-proto helloworld.proto \
localhost:50051 helloworld.Greeter/SayHello
{
  "message": "Hello World"
}
デプロイ
こちらの記事にある通り、ターゲットグループのプロトコルバージョンGRPCでは、リスナープロトコルとしてHTTPSが必須になります。
つまりドメインやSSL証明書が必要になります。
ただ、既にRoute53でドメインを登録している場合は、Copilotの設定でACMでの証明書の発行やRoute53でのDNSレコードの登録をイイ感じでやってくれます。
詳細はドキュメント Domainをご覧ください。
- copilot app init
 
copilot app init --domain cm-arai.com
app nameはaraiにします。
workload typeはLoad Balanced Web Serviceを選びます。

- copilot svc init
 
copilot svc init
service nameはhelloworldにします。
- copilot env init
 
copilot env init
env nameはtestにします。
- copilot deploy
 
copilot deploy --name helloworld --env test
- send request
 
エンドポイントは${SvcName}.${EnvName}.${AppName}.${DomainName}の関係です。
$ grpcurl \
-import-path proto \
-proto helloworld.proto \
helloworld.test.arai.cm-arai.com:443 helloworld.Greeter/SayHello
{
  "message": "Hello World"
}
まとめ
v1.13.0リリースでは、同日に発表されたFargate Graviton2のサポートもされています。
まだまだ使いづらい部分はあるともいますが、リリース頻度も高く更新も活発なため、今後に期待したいと思います。
Discussion