コンテナ時代のWebサービスの作り方

技術書典6で購入した本1冊目。
ガチで役に立つ本でした。

とりあえず、76/103ページまでやってみました。ここまで行くと、ソースをコミットしたら自動的にサイトに反映される仕組みが動きます。
が、多少悪戦苦闘したところもありますので、その辺をメモ。

リージョン

書籍では、東京リージョン(ap-northeast-1)を使うことになっていますが、元々オハイオを使っていたのでそちらのus-east-2を使うことにしてみました。
すると、

The image id '[ami-785c491f]' does not exist

となります。これはリージョンによって異なるので、ami-8b92b4eeに変更します。(参考)https://docs.docker.com/machine/drivers/aws/

Terraform

Terraform初体験。インフラをコードで定義するとはこういうことなんだ。
しかし、これも簡単に進ませてはくれません。

Error inspecting states in the "s3" backend:
    BucketRegionError: incorrect region, the bucket is not in 'us-east-2' region
	status code: 301, request id: , host id: 

今回一番ハマったかもしれないのはこのエラー。
例えば、

aws s3 ls

なんかを叩くと帰ってくるので、この接続でs3の所定のバケットが見えていないわけでもない。結局、フォルダ全体を一回消して、再度やり直したらOKという最悪パターンでした。

また、実際の発生順序は前後しますが、さらに進んでまたこのエラーが出るようになりましたが、書籍だと、aws_route_table.tf、aws_route_table_association.tfが、間違っているのでgithub(書籍に記載あり)のソースを見て記載しました。

rubyバージョン

元々のローカル環境がruby2.3.7だったのが悪いと思うのですが、最初にそれで進めてしまい、いざbuildが動くと

You must use Bundler 2 or greater with this lockfile

が出るようになってしまいました。
ちょこちょこやってみましたがダメなので、まずはローカル環境をアップすることにします。こちらなどを参考に。
https://reasonable-code.com/ruby-on-rails-environment/

でこれも色々ありましたが、まず、アプリフォルダと同じ場所にある.ruby-versionの記載修正が必要ですね。
さらに、作成済みGemfileの記述を ruby ‘2.6.2’にし、Dockerfileは
FROM ruby:2.6.2とした上で、

RUN \
    gem install bundler:2.0.1 && \
    bundle install && \
    rm -rf ~/.gem

という形で、bundler:2.0.1の記述を追加。
ついでに、この状態で

/usr/local/bundle/gems/execjs-2.7.0/lib/execjs/runtimes.rb:58:in `autodetect': Could not find a JavaScript runtime. See https://github.com/rails/execjs for a list of available runtimes. (ExecJS::RuntimeUnavailable)

というエラーになっていたので、

RUN apt-get update && \
    apt-get install -y nodejs

も追加しました。

AWSリソースの作成

まず書籍の誤記ですが、vpc/config.tfのkeyの記載は「terraform-sample/vpc/terraform.tfstate」ではなく、「sample/vpc/terraform.tfstate」が正しいです。
で、次はこんなエラー。

* aws_security_group.instance (destroy): 1 error(s) occurred:

* aws_security_group.instance: DependencyViolation: resource sg-07ae3339a31044567 has a dependent object
	status code: 400, request id: 93ebbe83-5cf6-410e-a9a3-e651292a534b

Terraform does not automatically rollback in the face of errors.
Instead, your Terraform state file has been partially updated with
any resources that successfully completed. Please address the error
above and apply again to incrementally change your infrastructure.

この時には、コンソールの方では、

aws_security_group.instance: Still destroying... (ID: sg-07ae3339a31044567, 10m0s elapsed)

というメッセージが出続けています。
要するに、このセキュリティグループを一旦削除して作りたいのに、削除ができない、ということのようで、確かに手動削除しようとしても削除できません。なので、このセキュリティグループを使用しているインスタンスを削除して、このセキュリティグループも削除してから、再度やり直すとOKでした。

Amazon ECS

さて、もう一息。ECSにクラスターが作成されたということで、この時よりは進んだ!

が、よくよく見ると、起動していない。サービスのページは下記のエラー。

service rails-service is unable to consistently start tasks successfully. For more information, see the Troubleshooting section.
service rails-service was unable to place a task because no container instance met all of its requirements. Reason: No Container Instances were found in your cluster. For more information, see the Troubleshooting section.

タスクのページは下記のエラー。

状況の理由	CannotPullContainerError: Error response from daemon: manifest for 442268206491.dkr.ecr.us-east-2.amazonaws.com/sample-image:latest not found
コマンド	["bundle","exec","pumactl","start"]

CircleCIを見ると下記のエラー。

rails aborted!
Don't know how to build task 'assets:precomp' (See the list of available tasks with `rake --tasks`)

precomp??単に、書籍から貼り付けた記述の途中にスペースが入っていたということでした。これを修正して、ソースをコミットするとこにより、無事動いた状態ができあがりました。

ただ、ページを開くためにどうURLを記述したら良いかがわからなかった・・・

これ以降について

この後は、DBをMySQLにしたりするのですが、さらにお金がかかりそうなので、一旦ここまで。
かなり本格仕様の構成ができるので、うまくカスタマイズして使いたいところです。
そして、本書が良書であるのは間違いないところで、自分の目の付け所の良さに感動です(違うか!)。