AWSにRails + Nginxな環境をTerraformで構築してみようと思います。
はじめに
本連載で一つずつインフラを構築していきます。
ドメインのhttps化したり、ECS Fargateを使用したコンテナオーケストレーションを用いてアプリケーションをデプロイします。
この記事では、インフラの自動化を行います。
環境は以下です。
| OS | Cataline 10.15.6 |
| Terraform | 0.14.4 |
基本構文などこちらにまとめてますので、よかったらみてください!
AWS Terraform 基本コード まとめ
連載一覧
- terraform AWS環境構築 事前準備
- 【ネットワーク環境構築】terraform AWS環境構築 第1回
- 【ドメインhttps化・ACM(SSL)証明書発行】terraform AWS環境構築 第2回
- 【ロードバランサー構築】terraform AWS環境構築 第3回
- 【ECS Fargate(nginx)実行】terraform AWS環境構築 第4回
- 【RDS構築】terraform AWS環境構築 第5回
- 【Docker/ECR作成】terraform AWS環境構築 第6回
- 【ECS Fargate(rails + nginx)実行】terraform AWS環境構築 第7回
- 【CircleCIによるCI/CD】terraform AWS環境構築 番外 ←ここ
やること
以下の導入をします。
- RSpec の導入
- CircleCI の導入
インフラの自動化
CircleCI でテスト完了後、自動でデプロイしてくれるように設定します。
RSpec の導入
gem のインストール
Gemfile に以下を追記します。
group :development, :test do gem 'rspec-rails', '~> 5.0.0' end
bundle のインストール
$ bundle install
rspec のインストール
以下のコマンドで rspec をインストールします。
$ rails g rspec:install
簡単なテストの実装
root_path にアクセスして「ステータスコード200」が返ってくるかテストしてみましょう。
spec/requests/home_controller.rb
require 'rails_helper'
RSpec.describe "Homes", type: :request do
describe "GET /index" do
it 'responds successfully' do
get '/'
expect(response).to have_http_status 200
end
end
end
以下のコマンドでテスト実行してみましょう。
$ rails specHomes GET /index responds successfully Finished in 3.88 seconds (files took 1.78 seconds to load) 1 example, 0 failures
CircleCI の導入
.circleciフォルダとconfig.yml を作成して導入準備をします。
.cricleci/config.yml
version: 2.1
orbs:
aws-ecr: circleci/aws-ecr@6.15.3
aws-ecs: circleci/aws-ecs@2.1.0
aws-cli: circleci/aws-cli@2.0.0
jobs:
test:
docker:
- image: circleci/ruby:2.7.1-node-browsers
environment:
RAILS_ENV: test
MYSQL_HOST: 127.0.0.1
MYSQL_PORT: 3306
MYSQL_USER: root
MYSQL_ROOT_PASSWORD: password
- image: circleci/mysql:8.0.16
command: mysqld --default-authentication-plugin=mysql_native_password
environment:
MYSQL_HOST: 127.0.0.1
MYSQL_USER: root
MYSQL_ROOT_PASSWORD: password
working_directory: ~/terraform_and_rails/rails_hello
steps:
- checkout:
path: ~/terraform_and_rails
- restore_cache:
keys:
- rails-bundle-v2-{{ checksum "Gemfile.lock" }}
- rails-bundle-v2-
- run:
name: bundle install
command: bundle check --path vendor/bundle || bundle install --deployment
- save_cache:
key: rails-bundle-v2-{{ checksum "Gemfile.lock" }}
paths:
- vendor/bundle
- restore_cache:
keys:
- rails-yarn-{{ checksum "yarn.lock" }}
- rails-yarn-
- run:
name: yarn install
command: yarn install --cache-folder ~/.cache/yarn
- save_cache:
key: rails-yarn-{{ checksum "yarn.lock" }}
paths:
- ~/.cache/yarn
- run:
name: Wait for DB
command: dockerize -wait tcp://127.0.0.1:3306 -timeout 3m
- run:
name: Confiure Database setting
command: mv ./config/database.yml.ci ./config/database.yml
- run:
name: DB create
command: bundle exec rake db:create
- run:
name: Run rspec
command: |
mkdir /tmp/test-results
TEST_FILES="$(circleci tests glob "spec/**/*_spec.rb" | \
circleci tests split --split-by=timings)"
bundle exec rspec \
--format progress \
--out /tmp/test-results/rspec.xml \
--format documentation \
$TEST_FILES
- store_test_results:
path: /tmp/test-results
- store_artifacts:
path: /tmp/test-results
destination: test-results
workflows:
version: 2.1
test:
jobs:
- test
- aws-ecr/build-and-push-image:
requires:
- test
aws-access-key-id: ACCESS_KEY_ID
aws-secret-access-key: SECRET_ACCESS_KEY
path: ./rails_hello/
dockerfile: containers/app/Dockerfile
account-url: AWS_ECR_ACCOUNT_URL
repo: '${AWS_RESOURCE_RAILS}'
region: AWS_DEFAULT_REGION
tag: latest
extra-build-args: '--build-arg RAILS_MASTER_KEY=${RAILS_MASTER_KEY}'
- aws-ecs/deploy-service-update:
requires:
- aws-ecr/build-and-push-image
aws-region: AWS_DEFAULT_REGION
aws-access-key-id: ACCESS_KEY_ID
aws-secret-access-key: SECRET_ACCESS_KEY
family: 'rails_hello'
cluster-name: 'rails-hello'
service-name: 'rails_hello-service'
container-image-name-updates: 'container=rails,tag=latest'
test ジョブにて、gemのインストールやテストDBの用意してテストを実行します。
テストが成功すると、ビルドとECSサービスのアップデートが起動します。
- aws-ecr/build-and-push-image :ビルドしてECRにプッシュする
- aws-access-key-id :AWSのアクセスキー
- aws-secret-access-key:AWSのシークレットキー
- path:ビルドするディレクトリ
- dockerfile:ビルドするDockerfile
- account-url:ECRのURL
- repo:ECRのレポジトリ名
- region:リージョン
- tag:タグ
- extra-build-args:ビルドする環境変数
- aws-ecs/deploy-service-update:ECSサービスのアップデート
- aws-region:リージョン
- aws-access-key-id :AWSのアクセスキー
- aws-secret-access-key:AWSのシークレットキー
- family:タスク名
- cluster-name:クラスター名
- service-name:サービス名
- container-image-name-updates:アップデートするコンテナとタグ
以下の環境変数をCircleCIに設定してします。
- ACCESS_KEY_ID:<AWSのアクセスキー>
- SECRET_ACCESS_KEY:<AWSのシークレットキー>
- AWS_ECR_ACCOUNT_URL:AccountId.dkr.ecr.ap-northeast-1.amazonaws.com
- AWS_RESOURCE_RAILS:rails_hello
- AWS_DEFAULT_REGION:ap-northeast-1
- RAILS_MASTER_KEY:<Rails マスターキー>

これで準備は完了です。
それとアセットプリコンパイルをする必要があるので、Dockerfileの最後に追記しましょう。
rails_hello/containers/app/Dockerfile
FROM ruby:2.7.1-alpine3.12
ENV TZ=Asia/Tokyo \
RAILS_ENV=production \
RAILS_SERVE_STATIC_FILES=false
ARG RAILS_MASTER_KEY
ENV RAILS_MASTER_KEY ${RAILS_MASTER_KEY}
RUN apk add --no-cache build-base libxml2-dev libxslt-dev \
tzdata ca-certificates mysql-dev mysql-client \
imagemagick imagemagick-dev imagemagick-c++ nodejs yarn && \
gem install bundler
WORKDIR /rails_hello
RUN mkdir -p tmp/sockets
ADD Gemfile /rails_hello/Gemfile
ADD Gemfile.lock /rails_hello/Gemfile.lock
# RUN bundle config set deployment 'true' && \
RUN bundle config set without 'test development' && \
bundle install
ADD . /rails_hello
RUN bundle exec rails assets:precompile # 追記
それでは早速、コードを変更後プッシュして変更が適用されるか確認しましょう。
index.html.erb
<h1>rails_hello</h1> <p>update index.html<p> <!--変更-->
プッシュされるとまずは test が走ります。

成功すると、aws-ecr/build-and-push-image が走ります。

成功すると、aws-ecs/deploy-service-update が走ります。

これも成功すると、新しくタスクが実行されていると思います。

それでは、ドメインにアクセスして更新されているか見てみましょう。

おわり
これで、CircleCIによるCI/CDは完了しました。お疲れさまでした!
インフラの自動化もできたことで、だいたいのインフラリソースはコード化をできるようになりました。
どんどんコード化してインフラ管理ライフ良くしていきましょう!
今後、go + next.js を実装してみようと思います。


コメント