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 spec
Homes 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 を実装してみようと思います。
コメント