CircleCI から、新しい Arm ベースのコンピューティングがプレビュー版としてリリースされました。このプレビュー版へのアクセスは、こちらから申請できます。
Arm プロセッサとアーキテクチャは、 開発チームの多数のアプリケーション インフラストラクチャにコンピューティング ノードとして採用され、普及が進んでいます。これからも、マイクロサービス、アプリケーション サーバー、データベースなどのワークロードをコスト効率よく実行するために、Arm アーキテクチャの需要は高まっていくでしょう。CircleCI ではこれまで、Arm ベースのコンピューティングを求める声に応じてセルフホスト ランナーを提供していました。しかし、Arm ベースのコンピューティングでアプリケーションをビルド、テスト、デプロイしたいというお客様の数はますます増えています。そこで、全 CircleCI ユーザー向けに 新しい Arm ベースのリソース クラス をリリースいたしました。このクラスを使用することで、自身でインフラストラクチャを管理することなく、CI/CD パイプラインの Arm ベースのインスタンス上でコードを実行することができます。本チュートリアルでは、この新しいArm リソース クラス を紹介してから、これらのクラスをパイプライン内で使用して Arm 向けアプリケーションのビルド、テスト、デプロイを行う方法について説明します。
前提条件
本チュートリアルを進めるには、以下の作業が必要です。
- GitHub から arm-executors サンプル リポジトリ をクローンする
- CircleCI アカウントに登録する
- アクセスを申請 してArm のプレビューに参加する
- CircleCI で arm-executor プロジェクトをセットアップする
- Amazon Web Services (AWS) アカウントを作成する
- プログラムでのアクセスが可能な AWS IAMS ユーザーを作成する
- AWS ECS の権限をこのユーザーに割り当てる
- AWS アクセス キーとシークレット を生成し、後ほど使用できるように AWS_ACCESS_KEY_ID と AWS_SECRET_ACCESS_KEY を保存する
- プログラムでのアクセスが可能な AWS IAMS ユーザーを作成する
- Docker Hub アカウントを作成する
- Docker Hub アクセス トークンを作成する
- Terraform CLI をローカルにインストールする
- Terraform Cloud アカウントを作成する
- Terraform Cloud 組織を新規作成する
- Terraform Cloud ワークスペースを新規作成し、
arm-aws-ecs
という名前を付け、"No VCS connection (VCS 接続なし)"
オプションを選択する arm-aws-ecs
ワークスペースで、ローカル実行モード を有効にする- Terraform API トークンを新規作成する
- CircleCI で以下のプロジェクト環境変数を作成する
AWS_ACCESS_KEY_ID
アクセス キー ID の値を入力するAWS_SECRET_ACCESS_KEY
シークレット アクセス キーの値を入力するDOCKER_LOGIN
Docker ユーザー名の値を入力するDOCKER_PWD
Docker Hub アクセス トークンの値を入力するTERRAFORM_TOKEN
Terraform API トークンの値を入力する
Arm コンピューティング リソース クラス
Arm コンピューティング リソース クラスは現在プレビュー版であり、Machine Executor として提供されています。そのため、パイプラインの構成定義では Machine Executor として実装します。Arm リソース クラスを使用してジョブを実行するには、プレビューへのアクセスが必要であることに注意してください。このチュートリアルの以下のセクションでは、Arm ベースの Executor で CI/CD パイプラインを構成および実行する方法を説明します。また、Terraformとインフラストラクチャのコード化を使用し、AWS Graviton2 コンピューティング ノードを基盤としたAWS ECS クラスタ を作成、デプロイ、破棄する方法についても説明します。
config.yml に Arm コンピューティングを実装する
下記のパイプライン構成例に、Arm リソース クラスの定義方法を示します。
version: 2.1
orbs:
node: circleci/node@4.2.0
jobs:
run-tests:
machine:
image: ubuntu-2004:202101-01
resource_class: arm.medium
steps:
- checkout
- node/install-packages:
override-ci-command: npm install
cache-path: ~/project/node_modules
- run:
name: 単体テストの実行
command: |
./node_modules/mocha/bin/mocha test/ --reporter mochawesome --reporter-options reportDir=test-results,reportFilename=test-results
- store_test_results:
path: test-results
- store_artifacts:
path: test-results
build_docker_image:
machine:
image: ubuntu-2004:202101-01
resource_class: arm.medium
steps:
- checkout
- run:
name: "Docker イメージ ARM V8 のビルド"
command: |
export TAG='0.1.<< pipeline.number >>'
export IMAGE_NAME=$CIRCLE_PROJECT_REPONAME
docker build -t $DOCKER_LOGIN/$IMAGE_NAME -t $DOCKER_LOGIN/$IMAGE_NAME:$TAG .
echo $DOCKER_PWD | docker login -u $DOCKER_LOGIN --password-stdin
docker push -a $DOCKER_LOGIN/$IMAGE_NAME
workflows:
build:
jobs:
- run-tests
- build_docker_image
このサンプルコードに含まれる run-tests:
ジョブは、Machine Executor を指定して Arm コンピューティング ノード リソース クラスを割り当てる方法を示しています。image:
キーでは、Executor に割り当てられるオペレーティング システムを指定します。resource_class:
では、利用する CircleCI のリソース クラス を指定します。 ここでは arm.medium
リソース クラス タイプを使用しています。このクラスでは、Arm アーキテクチャとリソース上でこれらのコードを実行およびビルドできます。build_docker_image:
ジョブでは、Arm コンピューティング インフラストラクチャ(AWS Graviton2 など)に確実にデプロイ可能な Arm64 対応の Docker イメージを、arm.medium
リソース クラスでビルドしています。
version: 2.1
orbs:
node: circleci/node@4.2.0
commands:
install_terraform:
description: "使用する Terraform のバージョンとアーキテクチャを指定 [amd64 または arm64]"
parameters:
version:
type: string
default: "0.13.5"
arch:
type: string
default: "arm64"
steps:
- run:
name: Terraform クライアントのインストール
command: |
cd /tmp
wget https://releases.hashicorp.com/terraform/<<
parameters.version >>/terraform_<<
parameters.version >>_linux_<<
parameters.arch >>.zip
unzip terraform_<< parameters.version >>_linux_<<
parameters.arch >>.zip
sudo mv terraform /usr/local/bin
jobs:
run-tests:
machine:
image: ubuntu-2004:202101-01
resource_class: arm.medium
steps:
- checkout
- node/install-packages:
override-ci-command: npm install
cache-path: ~/project/node_modules
- run:
name: 単体テストの実行
command: |
./node_modules/mocha/bin/mocha test/ --reporter mochawesome --reporter-options reportDir=test-results,reportFilename=test-results
- store_test_results:
path: test-results
- store_artifacts:
path: test-results
build_docker_image:
machine:
image: ubuntu-2004:202101-01
resource_class: arm.medium
steps:
- checkout
- run:
name: "Docker イメージ ARM V8 のビルド"
command: |
export TAG='0.1.<< pipeline.number >>'
export IMAGE_NAME=$CIRCLE_PROJECT_REPONAME
docker build -t $DOCKER_LOGIN/$IMAGE_NAME -t $DOCKER_LOGIN/$IMAGE_NAME:$TAG .
echo $DOCKER_PWD | docker login -u $DOCKER_LOGIN --password-stdin
docker push -a $DOCKER_LOGIN/$IMAGE_NAME
deploy_aws_ecs:
machine:
image: ubuntu-2004:202101-01
resource_class: arm.medium
steps:
- checkout
- run:
name: ローカルでの .terraformrc ファイルの作成
command: echo "credentials \"app.terraform.io\" {token = \"$TERRAFORM_TOKEN\"}" > $HOME/.terraformrc
- install_terraform:
version: 0.14.2
arch: arm64
- run:
name: AWS ECS クラスタへのアプリケーションのデプロイ
command: |
export TAG=0.1.<< pipeline.number >>
export DOCKER_IMAGE_NAME="${DOCKER_LOGIN}/${CIRCLE_PROJECT_REPONAME}"
cd terraform/aws/ecs
terraform init
terraform apply \
-var docker_img_name=$DOCKER_IMAGE_NAME \
-var docker_img_tag=$TAG \
--auto-approve
destroy_aws_ecs:
machine:
image: ubuntu-2004:202101-01
resource_class: arm.medium
steps:
- checkout
- run:
name: ローカルでの .terraformrc ファイルの作成
command: echo "credentials \"app.terraform.io\" {token = \"$TERRAFORM_TOKEN\"}" > $HOME/.terraformrc
- install_terraform:
version: 0.14.2
arch: arm64
- run:
name: AWS ECS クラスタの破棄
command: |
cd terraform/aws/ecs
terraform init
terraform destroy --auto-approve
workflows:
build:
jobs:
- run-tests
- build_docker_image
- deploy_aws_ecs
- approve_destroy:
type: approval
requires:
- deploy_aws_ecs
- destroy_aws_ecs:
requires:
- approve_destroy
AWS ECS にデプロイする
前のセクションのサンプル コードでは、Arm リソース クラスをパイプライン内で使用する方法について説明しました。本セクションでは、このコードを拡張してECS クラスタなどの AWS リソースを作成する方法について説明します。リソースの作成にあたっては、AWS Graviton2 EC2 コンピューティング ノードを基盤とし、Terraform とインフラストラクチャのコード化を使用します。
version: 2.1
orbs:
node: circleci/node@4.2.0
commands:
install_terraform:
description: "使用する Terraform のバージョンとアーキテクチャを指定 [amd64 または arm64]"
parameters:
version:
type: string
default: "0.13.5"
arch:
type: string
default: "arm64"
steps:
- run:
name: Terraform クライアントのインストール
command: |
cd /tmp
wget https://releases.hashicorp.com/terraform/<<
parameters.version >>/terraform_<<
parameters.version >>_linux_<<
parameters.arch >>.zip
unzip terraform_<< parameters.version >>_linux_<<
parameters.arch >>.zip
sudo mv terraform /usr/local/bin
jobs:
run-tests:
machine:
image: ubuntu-2004:202101-01
resource_class: arm.medium
steps:
- checkout
- node/install-packages:
override-ci-command: npm install
cache-path: ~/project/node_modules
- run:
name: 単体テストの実行
command: |
./node_modules/mocha/bin/mocha test/ --reporter mochawesome --reporter-options reportDir=test-results,reportFilename=test-results
- store_test_results:
path: test-results
- store_artifacts:
path: test-results
build_docker_image:
machine:
image: ubuntu-2004:202101-01
resource_class: arm.medium
steps:
- checkout
- run:
name: "Docker イメージ ARM V8 のビルド"
command: |
export TAG='0.1.<< pipeline.number >>'
export IMAGE_NAME=$CIRCLE_PROJECT_REPONAME
docker build -t $DOCKER_LOGIN/$IMAGE_NAME -t $DOCKER_LOGIN/$IMAGE_NAME:$TAG .
echo $DOCKER_PWD | docker login -u $DOCKER_LOGIN --password-stdin
docker push -a $DOCKER_LOGIN/$IMAGE_NAME
deploy_aws_ecs:
machine:
image: ubuntu-2004:202101-01
resource_class: arm.medium
steps:
- checkout
- run:
name: ローカルでの .terraformrc ファイルの作成
command: echo "credentials \"app.terraform.io\" {token = \"$TERRAFORM_TOKEN\"}" > $HOME/.terraformrc
- install_terraform:
version: 0.14.2
arch: arm64
- run:
name: AWS ECS クラスタへのアプリケーションのデプロイ
command: |
export TAG=0.1.<< pipeline.number >>
export DOCKER_IMAGE_NAME="${DOCKER_LOGIN}/${CIRCLE_PROJECT_REPONAME}"
cd terraform/aws/ecs
terraform init
terraform apply \
-var docker_img_name=$DOCKER_IMAGE_NAME \
-var docker_img_tag=$TAG \
--auto-approve
destroy_aws_ecs:
machine:
image: ubuntu-2004:202101-01
resource_class: arm.medium
steps:
- checkout
- run:
name: ローカルでの .terraformrc ファイルの作成
command: echo "credentials \"app.terraform.io\" {token = \"$TERRAFORM_TOKEN\"}" > $HOME/.terraformrc
- install_terraform:
version: 0.14.2
arch: arm64
- run:
name: AWS ECS クラスタの破棄
command: |
cd terraform/aws/ecs
terraform init
terraform destroy --auto-approve
workflows:
build:
jobs:
- run-tests
- build_docker_image
- deploy_aws_ecs
- approve_destroy:
type: approval
requires:
- deploy_aws_ecs
- destroy_aws_ecs:
requires:
- approve_destroy
このコードは、前のセクションのパイプライン構成例を拡張したものです。注目点は、数個の新しいジョブ(deploy_aws_ecs:
, approve_destroy:
, destroy_aws_ecs:
ジョブ)が定義されていることです。これらを詳しく見ていく前に、まず commands:
および install_terraform:
の各要素について説明します。
install_terraform: コマンド
CircleCI では、パイプライン パラメーターを使用して構成コードのカプセル化と再利用を行えます。install_terraform:
コマンドは、再利用可能なパイプライン コードを定義する一例です。パイプラインで特定のコマンドを繰り返し実行する場合は、パイプライン構成の拡張性と一元管理のために、再利用可能なcommand:
要素を定義することをお勧めします。deploy_aws_ecs:
ジョブと destroy_aws_ecs:
ジョブはどちらも Terraform コードを実行するので、パイプラインではTerraform cliのダウンロードとインストールを複数回行う必要があります。そこで、install_terraform:
コマンドにより再利用性を高めています。
commands:
install_terraform:
description: "使用する Terraform のバージョンとアーキテクチャを指定 [amd64 または arm64]"
parameters:
version:
type: string
default: "0.13.5"
arch:
type: string
default: "arm64"
steps:
- run:
name: Terraform クライアントのインストール
command: |
cd /tmp
wget https://releases.hashicorp.com/terraform/<<
parameters.version >>/terraform_<<
parameters.version >>_linux_<<
parameters.arch >>.zip
unzip terraform_<< parameters.version >>_linux_<<
parameters.arch >>.zip
sudo mv terraform /usr/local/bin
このコード ブロックでは、再利用可能なコマンドinstall_terraform:
を定義しています。parameters:
キーはパラメーターのリストを保持します。version:
パラメーターと arch:
パラメーターで、Terraform CLI のバージョンと CPU アーキテクチャをそれぞれ定義しています。これらのパラメーターを使用して、Executor でのクライアントのダウンロードとインストールを行います。このコード ブロックはcommand:
要素であるため、コマンドのsteps:
キーを定義する必要があります。上記の例では、run:
要素で対応する command:
キーを実行しています。 このキーは、<< parameter.version >>
および << parameter.arch >>
変数を使用してクライアントのバージョン番号と CPU アーキテクチャを指定し、特定の Terraform クライアントをダウンロードします。パイプライン パラメーター は、パイプライン構成における機能の最適化と一元管理に非常に便利です。詳しく知りたい方は、こちらのページをご覧ください。
deploy_aws_ecs ジョブ
パイプラインで定義されているdeploy_aws_ecs:
ジョブは、インフラストラクチャのコード化を活用して Amazon ECS クラスタを新規作成します。これには、仮想プライベート ネットワーク (VPC)、サブネット、ルート テーブル、アプリケーション ロード バランサー、EC2 自動スケーリング グループといった必要なリソースがすべて含まれます。このジョブは、アプリケーションのデプロイと実行に必要なすべてのインフラストラクチャを作成およびプロビジョニングします。対象のアーキテクチャは Arm なので、AWS ECS クラスタは AWS Gravtion2 ECS コンピューティング ノードで構成する必要があります。これらの AWS Gravtion2 ECS コンピューティング ノードで、前のパイプライン ジョブにおける Arm ベースの Docker アプリケーション イメージ ビルドを実行します。
deploy_aws_ecs:
machine:
image: ubuntu-2004:202101-01
resource_class: arm.medium
steps:
- checkout
- run:
name: ローカルでの .terraformrc ファイルの作成
command: echo "credentials \"app.terraform.io\" {token = \"$TERRAFORM_TOKEN\"}" > $HOME/.terraformrc
- install_terraform:
version: 0.14.2
arch: arm64
- run:
name: AWS ECS クラスタへのアプリケーションのデプロイ
command: |
export TAG=0.1.<< pipeline.number >>
export DOCKER_IMAGE_NAME="${DOCKER_LOGIN}/${CIRCLE_PROJECT_REPONAME}"
cd terraform/aws/ecs
terraform init
terraform apply \
-var docker_img_name=$DOCKER_IMAGE_NAME \
-var docker_img_tag=$TAG \
--auto-approve
このコード ブロックでは、先ほど触れた install_terraform:
コマンドの使い方を示しています。version:
パラメーターを 0.14.2、arch:
パラメーターを arm64 に設定しました。最後の run:
要素は Terraform を初期化します。そして、このパイプライン実行で作成された Docker イメージ名とタグの値を渡す対応パラメーターを指定して、terraform apply
コマンドを実行します。これらが完了すると、アプリケーションが作成され、完全な機能を備えた AWS ECS Graviton2 ベースのクラスタにデプロイされます。
destroy_aws_ecs ジョブ
ここまでは、deploy_aws_ecs
で AWS ECS のインフラストラクチャを作成してきました。その名の通り destroy_aws_ecs
ジョブはこの逆で、作成したすべてのインフラストラクチャとリソースをプログラムで破棄します。このジョブを使用すれば、極めてクリーンな方法で不要なインフラストラクチャを終了させることができます。
destroy_aws_ecs:
machine:
image: ubuntu-2004:202101-01
resource_class: arm.medium
steps:
- checkout
- run:
name: ローカルでの .terraformrc ファイルの作成
command: echo "credentials \"app.terraform.io\" {token = \"$TERRAFORM_TOKEN\"}" > $HOME/.terraformrc
- install_terraform:
version: 0.14.2
arch: arm64
- run:
name: AWS ECS クラスタの破棄
command: |
cd terraform/aws/ecs
terraform init
terraform destroy --auto-approve
ジョブ定義のほとんどは直前のコード ブロックと同じですが、最後の run:
要素に注目してください。この要素では、Terraform の初期化コマンドと、前のステップで作成したすべてのリソースを破棄する terraform destroy
コマンドを発行しています。
ワークフロー: approve_destroy ジョブ
最後に扱うのは、構成例のworkflows:
要素にある approve_destroy:
です。このジョブは 手動承認タイプです。 手動での承認が行われるまでワークフローを意図的に停止して保留状態にします。ここでは、CircleCI ダッシュボードでボタンを押下しなければ destroy_aws_ecs:
を実行できないようにしています。この承認ジョブがない場合は、パイプラインでは自動的に破棄ジョブをトリガーし、前のジョブで作成したリソースをすべて終了させます。承認タイプのジョブは、パイプライン実行において手動での操作や承認が必要な場合に便利です。
まとめ
CircleCI に、Arm コンピューティング ノードとして Arm 対応の Executor が加わりました。これにより、開発パイプラインで Arm アーキテクチャを利用できます。このチュートリアルでは、CircleCI の Arm コンピューティング ノードをパイプラインの Executor として実装する方法を紹介しました。また、Terraform とインフラストラクチャのコード化を使用して、AWS Graviton2 EC2 ノードを基盤とする AWS ECS クラスタにアプリケーションをデプロイする方法も示しました。このチュートリアルで扱ったサンプル コードはすべて GitHub にありますので、ぜひご覧ください。ご意見、ご感想は Twitter で @punkdata宛てにお寄せください。
最後までお読みいただき、ありがとうございました。