[AWS]パラメータストアで設定した値をCodeBuildで参照する

2023/7/1

AWS
Docker
Rails

はじめに

パラメータストアで設定した値をCodeBuildで参照する方法について調べて学んだことをまとめました。

具体的にはRailsのmaster keyの値をパラメータストアで設定した後、buildspec.ymlで環境変数に代入し、コンテナイメージをビルドする際に引数として渡します。

master key

Railsのmaster keyは、Rails 5.2以降で導入された機能です。

これは、Railsアプリケーションで暗号化された情報を安全に保管するために使用されます。主に、データベースの暗号化、外部APIキーの保管などに利用されます。

master keyは、Railsアプリケーションの暗号化されたcredentials(資格情報)ファイルを復号化するために使用されます。

credentialsファイルには、アプリケーションで使用される各種の秘密情報が含まれています。これには、データベースのパスワード、APIキー、トークン、暗号鍵などが含まれる場合があります。

master keyは、config/master.keyというファイルに格納されます。

このファイルはアプリケーションのルートディレクトリにあります。master keyを正しく保管することは非常に重要です。

不正なアクセスや情報漏洩を防ぐために、master keyは他の人と共有してはいけません。

特に、バージョン管理システム(例:Git)にmaster keyをコミットしないように注意する必要があります。

buildspec.yml

buildspec.ymlは、AWS CodeBuildでビルドプロジェクトを定義するための設定ファイルです。

AWS CodeBuildは、クラウドベースのビルドサービスであり、アプリケーションのビルド、テスト、パッケージング、デプロイなどを自動化するために使用されます。

buildspec.ymlファイルは、ビルドプロジェクトのビルドフェーズやアーティファクトの生成方法、テストの実行、デプロイ手順など、ビルドプロセス全体の手順を定義します。このファイルはプロジェクトのルートディレクトリに配置されます。

buildspec.ymlファイルの構造はYAML形式で記述されます。主なセクションとしては、次のようなものがあります。

  1. バージョン: buildspec.ymlのバージョンを指定します。現在のバージョンは0.2です。

  2. 環境変数: ビルドプロジェクトで使用する環境変数を定義します。これにはAWSのアクセスキーやシークレットアクセスキー、独自の環境変数などが含まれます。

  3. フェーズ: ビルドプロセスの各フェーズ(ビルド、テスト、デプロイなど)を定義します。各フェーズには、実行するコマンド、スクリプト、プロバイダーなどの情報が含まれます。

  4. アーティファクト: ビルドアーティファクトの保存場所やパッケージング方法を指定します。ビルドプロセスで生成された成果物(バイナリ、アーカイブ、デプロイ可能なパッケージなど)を指定した場所に保存することができます。

以下は、基本的なbuildspec.ymlファイルの例です。

version: 0.2

phases:
  install:
    commands:
      - npm install
  build:
    commands:
      - npm run build
  test:
    commands:
      - npm run test

artifacts:
  files:
    - '**/*'
  base-directory: 'dist'

この例では、Node.jsプロジェクトのビルドプロセスが定義されています。

installフェーズでは必要なパッケージのインストール、buildフェーズではアプリケーションのビルド、testフェーズではテストの実行が行われます。

また、生成された成果物はdistディレクトリに保存されます。

buildspec.ymlファイルはCodeBuildによって自動的に読み込まれ、指定された手順に従ってビルドプロセスが実行されます。

このファイルを使用することで、ビルドプロセスを簡単に再現可能にし、統一的なビルド環境を確保することができます。

Dockerfile

Dockerfileは、Dockerイメージを構築するためのテキストファイルです。Dockerイメージは、アプリケーションやサービスを実行するために必要なすべての依存関係や設定を含んだ軽量な仮想環境です。Dockerfileは、このDockerイメージを作成する手順を定義します。

通常、Dockerfileはプロジェクトのルートディレクトリに配置されます。Dockerfileには、以下のようなコマンドや指示が含まれます。

  1. ベースイメージの指定: Dockerイメージの基となるベースイメージを指定します。ベースイメージは、既存のDockerイメージを利用することもできます。

  2. 必要なパッケージや依存関係のインストール: アプリケーションが依存するパッケージやライブラリをインストールします。このステップでは、apt-getやyumなどのパッケージマネージャーを使用することがあります。

  3. ファイルの追加: アプリケーションのソースコードや設定ファイルなど、Dockerイメージに追加する必要のあるファイルを指定します。ADDやCOPYコマンドを使用して、ローカルのファイルやリモートのファイルをイメージにコピーすることができます。

  4. 環境変数の設定: アプリケーションが必要とする環境変数を設定します。ENVコマンドを使用して、キーと値のペアで環境変数を定義することができます。

  5. ポートのエクスポート: コンテナ内のアプリケーションが利用するポートをエクスポートします。EXPOSEコマンドを使用して、コンテナがリッスンするポートを指定することができます。

  6. 実行コマンドまたはエントリーポイントの指定: Dockerコンテナが起動された際に実行されるコマンドやスクリプトを指定します。CMDコマンドやENTRYPOINTコマンドを使用して、実行するコマンドやスクリプトを指定することができます。

以下は、基本的なDockerfileの例です。

# ベースイメージの指定
FROM ubuntu:latest

# 必要なパッケージのインストール
RUN apt-get update && apt-get install -y \
    python3 \
    python3-pip

# アプリケーションのファイルの追加
ADD app.py /app/app.py

# ポートのエクスポート
EXPOSE 80

# 実行コマンドの指定
CMD ["python3", "/app/app.py"]

この例では、Ubuntuをベースイメージとして使用し、Pythonとpipをインストールします。

また、ローカルのapp.pyファイルをイメージ内の/app/app.pyに追加し、ポート80をエクスポートします。

最後に、python3 /app/app.pyコマンドを実行するように指定しています。

Dockerfileを使用すると、開発者は簡単に環境を再現し、アプリケーションを異なる環境で簡単に実行できるようになります。

ビルドコマンド(docker build)を使用してDockerイメージをビルドし、イメージを実行するコマンド(docker run)を使用してコンテナを起動することができます。

パラメータストアに設定した値の名前の確認

パラメータストアに設定した値の名前を確認します。

今回は「/sample/rails-master-key」となっています。

001.png

buildspec.ymlの編集

環境変数としてパラメータストアの名前を設定します。

env:
  parameter-store:
    RAILS_MASTER_KEY: "/sample/rails-master-key"

コンテナイメージをビルドする際に設定した環境変数(= パラメータストアの値 = Rails master key)を引数として渡します。

docker build --build-arg RAILS_MASTER_KEY=$RAILS_MASTER_KEY /

以下は、筆者が実際に使用しているbuildspec.ymlの例です。

version: 0.2

env:
  variables:
    # コンテナ名を設定する
    CONTAINER_NAME: "container-name"
  parameter-store:
    # パラメータストアの名前を設定する
    RAILS_MASTER_KEY: "/sample/rails-master-key"

phases:
  pre_build:
    commands:
      # AWS アカウント ID を取得する
      - AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text)
      # リポジトリの URI を設定する
      - REPOSITORY_URI=${AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com/${CONTAINER_NAME}
      # コミット ID をもとに、コンテナイメージのタグを生成する
      - IMAGE_TAG=$(echo ${CODEBUILD_RESOLVED_SOURCE_VERSION} | cut -c 1-7)
      # ECR にログインする
      - aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin ${AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com

  build:
    commands:
      # コンテナイメージをビルドする
      - docker build --build-arg RAILS_MASTER_KEY=$RAILS_MASTER_KEY --platform=linux/amd64 -t ${REPOSITORY_URI}:latest -f docker/production/Dockerfile .
      # 生成したイメージタグを付与する
      - docker tag ${REPOSITORY_URI}:latest ${REPOSITORY_URI}:${IMAGE_TAG}

  post_build:
    commands:
      # ビルドしたコンテナイメージを ECR にプッシュする
      - docker push ${REPOSITORY_URI}:${IMAGE_TAG}
      # "コンテナの名前" と "コンテナイメージの URI" を imagedefinitions.json に書き込む
      - printf '[{"name":"%s","imageUri":"%s"}]' ${CONTAINER_NAME} ${REPOSITORY_URI}:${IMAGE_TAG}  > imagedefinitions.json

artifacts:
  files:
    - imagedefinitions.json

CodeBuildの環境変数の設定

CodeBuildの該当ビルドプロジェクトにて環境変数を設定します。

値はパラメータストアで設定した値の名前を入力し、タイプは「パラメータ」を選択します。(名前は任意です。)

002.png

Dockerfileの編集

buildspec.ymlで設定した引数をCodeBuildの環境変数を元に受け取るよう設定します。

ARG RAILS_MASTER_KEY

以下は、筆者が実際に使用しているDockerfileの例です。

FROM ruby:3.2.1-slim

ARG RAILS_MASTER_KEY

ENV RAILS_ENV production
ENV RAILS_SERVE_STATIC_FILES true
ENV RAILS_LOG_TO_STDOUT true

RUN apt-get update -qq && apt-get install -y build-essential libpq-dev vim git imagemagick
RUN mkdir /app
WORKDIR /app
ADD Gemfile /app/Gemfile
ADD Gemfile.lock /app/Gemfile.lock

ENV BUNDLER_VERSION 2.4.10
RUN gem update --system \
    && gem install bundler -v $BUNDLER_VERSION \
    && bundle install -j 4

RUN bundle install
ADD . /app

RUN bundle exec rails assets:precompile

EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0", "-p", "3000"]

以上でRailsのmaster keyの値をパラメータストアで設定した後、buildspec.ymlで環境変数に代入し、コンテナイメージをビルドする際に引数として利用することができます。


今回はここまでです。