背景
コロナで外出しづらくなったこともあり、以前から興味のあったCode for Japanに参加しました。
今回のプロジェクトは、Ruby on Railsでした。私は、Ruby初心者なので、コンテナやAWSまわりの足回りを固めるために活動してます。
私が、プロジェクトの参加からCI/CD構築までの流れを紹介します。興味がある方の参考になると嬉しいです。
3文まとめ
- Code for Japanに参加するのは簡単
- 当然だけど、AWSを触るのはNDAが必要
- GitHub ActionsでCI/CDを構築するは簡単
Code for Japan プロジェクト参加のきっかけ
東京都のコロナ対策サイトで気になって、ROM専でSlackにいました。
Slack コミュニティ - Code for Japanから、気軽に参加できます。
たまたま、slack上でメンバーの募集を見かけ、市民の政治参加に興味があり参加しますと声を掛けました。
Ruby初心者でしたが、心よく受け入れて頂きました。笑
参加したDIY City プロジェクト(市民参加型合意形成プラットフォーム)
地域で暮らす人たちや、その地域を愛する人たちが主役になり、自分たちでどんなまちにしたいのか、そのためにどんなことが必要なのかを考え、手を動かし、自分たちでつくっていく都市です。できるだけ多様な人がまちづくりに関わり、「要望する」のではなく「つくる」側として参画します。
上記のような構想をもとに、市区町村と協力してサービスを提供するプロジェクトです。市民が積極的に参加することで、より良い町づくりを目指します。
日本では、加古川市で2020/11から本稼働しています。
OSS decidim
上記のサイトは、Decidim (Free Open-Source participatory democracy for cities and organizations)をベースに構築されています。Ruby on railsで構築されており、これにパッチ修正をあてて稼働しています。翻訳など本家に取り込んでも問題ないものは、本家を修正しています。
このOSSで数年前から、バルセロナやヘルシンキなどいくつかの複数の都市で運用されています。都市ごとに、カスタマイズされており、どれも個性的で興味深いです。
バルセロナでは、うまく軌道にのり、下記のような成果が出ているようです。
2016年から2019年の3年間で、すでに市民の70%が登録しており、9000以上の市民からの新たな政策提案が集まっている
NDA締結
今回、CI/CD構築のため、AWSを触るので、NDA締結が必要でした。
一般的な内容で、クラウドサインで締結しました。
※私が勤めている弁護士ドットコムのサービスを使ってくれていました。
CI/CD概要
既にソースコードをGitHubで管理していたので、GitHub上で完結するGitHub Actionsを採用しました。
ユーザーがGitHubにコードをcommit pushすると、GitHub ActionsでイメージをBuildして、ECRにpush。その後、AWS ECRを使用してElastic Beanstalkにデプロイする非常にシンプルなパイプラインです。
AWS ECR作成
ECRは、Cloud Formationで作成しました。
AWSTemplateFormatVersion: "2010-09-09"
Description: Create ECR
Resources:
TestEcrPoc:
Type: AWS::ECR::Repository
Properties:
RepositoryName: hoge
ImageScanningConfiguration:
scanOnPush: "true"
ImageTagMutability: "MUTABLE"
LifecyclePolicy:
LifecyclePolicyText: |
{
"rules": [
{
"rulePriority": 1,
"description": "Delete image without tag after 7 days",
"selection": {
"tagStatus": "untagged",
"countType": "sinceImagePushed",
"countUnit": "days",
"countNumber": 7
},
"action": {
"type": "expire"
}
}
]
}
イメージスキャン
イメージスキャン - Amazon ECRを有効化しています。Pushするたびに、スキャンされます。
イメージスキャンは、オープンソースのClairプロジェクトからCommon Vulnerabilities and Exposures(CVE)データベースを使用してスキャンし、GUI上から結果を確認できる機能です。
ライフサイクルポリシー
タグなしのイメージだけ、7日経過後に削除するライフサイクルポリシーを設定しています。
ライフサイクルポリシーだけJSONで記述する必要があります。yamlの中なので、補完が効かず書きづらいですが、仕方がありません。
AWS IAMユーザーの作成
Elastic Beanstalkのアクセス権だけでなく、上記で作成したECRへのReadWriteアクセスも必要です。
GitHub Actionsで使うSecretsの設定
GitHubでは、レポジトリごとにSecretsが設定できます。
それを使用して、下記のキーで、上記で作成したIAMのアクセス情報とECRのレポジトリ名を保存します。
レポジトリ名は場合によっては、Secretsでなくてもいいと思います。
AWS_ACCESS_KEY_ID: *********************
AWS_SECRET_ACCESS_KEY: *********************
AWS_ECR_REPO_NAME: hoge
AWS ECRへのイメージのpush
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ap-northeast-1
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
- name: Build, tag, and push image to Amazon ECR
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: ${{ secrets.AWS_ECR_REPO_NAME }}
IMAGE_TAG: staging
run: |
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
AWS ECRへのログイン & Push
公式で、下記のActionが提供されているので、非常に簡単にpushできます。
aws-actions/amazon-ecr-login: Logs into Amazon ECR with the local Docker client.
Dockerrun.aws.jsonの作成
{
"AWSEBDockerrunVersion": "1",
"Logging": "/app/log",
"Image": {
"Name": "{RepositoryName}",
"Update": "true"
},
"Ports": [
{
"ContainerPort": "3000"
}
]
}
${RepositoryName}
はデプロイ時に、タグ付きのレポジトリ名にリプレイスします。
あえてdeployments
ディレクトリを掘って、その下に置いています。同じ階層にDockerfileがあると、そちらが優先されてしまうためです。また、デプロイ時にDockerrun.aws.jsonだけをzipすることで転送量を減らすのが狙いです。
Loggingセクションに コンテナ内のディレクトリを指定することで、ebの管理下にあるLogディレクトリにログを出力できます。
またGUI上のコンソールからLogの閲覧も可能になります。
AWS Elastic Beanstalkへのデプロイ
- uses: actions/setup-python@master
with:
python-version: "3.7"
- name: Install awsebcli
run: pip install -U awsebcli
- name: Deploy to Elastic Beanstalk
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: ${{ secrets.AWS_ECR_REPO_NAME }}
IMAGE_TAG: staging
EB_ENVIRONMENT_NAME: staging
run: |
cd deployments
sed -i -e "s|{RepositoryName}|$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG|g" Dockerrun.aws.json
eb deploy ${EB_ENVIRONMENT_NAME}
今回は、極力公式のActionだけにしたかったので、有志のBeanstalk Deploy · Actions · GitHub Marketplaceを使用しませんでした。要件次第では、使った方が楽だと思います。
eb コマンドを使用しているので、python環境の構築後にコマンドのインストールを行っています。
まとめ
GitHub Actionsを使用することで、比較的簡単にパイプラインが構築できました。
デジタル庁の民間登用やCode for Japanの東京都コロナ対策サイト、COCOAなどを契機に、一般市民がテクノロジーを活用して、行政サービスの問題や社会課題を解決するCivitechはこれから盛り上がっていくと思います。
コードの全体は、codeforjapan/decidim-cfj: Code for Japan Decidimにあります。
ぜひあなたのコントリビュートをお待ちしております。