CodeCommit のGitリポジトリにIAM Roleで接続する

CodeCommit

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

渡辺です。 2015年はAnsible, CodeDeploy, CodeCommitといった開発周りのプロダクトを色々と触ってきましたが、良い感じで整備されてきたなぁという印象があります。 環境構築からビルドまで全自動で走り、フルマネージドでサーバが動くというのは10年前どころか5年前でも中々難しいところでした。 数年後には「常識」になっているかもしれません。

さて、前回のエントリー(CodeCommitのGitリポジトリへの接続方法)では、IAMユーザを利用してCodeCommitのGitリポジトリに接続する方法を紹介しました。 CodeCommitのGitリポジトリへには、CodeCommitへのアクセス許可を持つIAMユーザを用意し、SSHの公開鍵を登録してSSH接続を行うか、アクセスキーを発行してHTTPS接続を行います。 これは、開発マシンなどから、CodeCommitのGitリポジトリを利用することを想定しています。 今回はJenkinsなどのCIサーバや、ビルドやデプロイを行うサーバがCodeCommitのGitリポジトリを利用する場合を想定しましょう。

EC2インスタンスにはRoleを付与する

EC2インスタンスからAWSリソースを利用する場合、IAMユーザのアクセスキーよりもIAM Roleを利用することが推奨されています。 IAM RoleはEC2インスタンスにアクセス許可を与える仕組みであるため、アクセスキーの管理が不要であり、インスタンスとIAMユーザを紐付ける必要がないからです。

例えば、EC2インスタンスに付与したRoleにS3のアクセス権を与えれば、EC2インスタンスはアクセスキー無しでS3にアクセスできます。 したがって、EC2インスタンスに付与したRoleにCodeCommitのアクセス権を与えれば、EC2インスタンスはアクセスキー無しでCodeCommitにアクセスできるはずです。 しかしながら、AWS CLIやAWS SDKを利用するわけではなく、gitコマンドを利用するため、使い勝手が異なります。

RoleでCodeCommitのgitリポジトリに接続する

Roleを利用してCodeCommitのgitリポジトリに接続する場合、前回と同様に、gitのcredential.helperオプションを利用してHTTPS接続を行います。 次のようにgitのconfigコマンドを利用して、credential.helperとcredential.UseHttpPathオプションを設定してください。

# git config --global credential.helper '!aws --region us-east-1 codecommit credential-helper $@'
# git config --global credential.UseHttpPath true
[credential]    
    helper = !aws --region us-east-1 credential-helper $@
    UseHttpPath = true

前回と異なり、プロファイルを指定していません。 これは、実行するEC2インスタンスにRoleが設定されているためです。

IAM Roleを利用すれば、CodeCommitのgitリポジトリに、SSHの鍵もアクセスキーも不要で接続できました。 CIサーバやデプロイサーバではこの方法がスマートでしょう。

cloud-initでCodeCommitからPlaybookを取得し、Ansibleを実行する

cloud-initは、EC2インスタンスの初期化時に実行する処理を定義できる仕組みです。 EC2インスタンスに必要なミドルウェアや設定ファイルなどを定義できます。 しかし、設定ファイルの管理が難しく、デバッグもやりにくいのが難点です。

設定ファイルはバージョン管理したいところです。 設定ファイルの挙動確認はローカル環境から手軽にやりたいところです。 cloud-initでAnsibleなどの構成管理ツールの設定ファイルをgitリポジトリから取得し、実行出来れば、これらの問題は解決します。

というわけで、cloud-initでCodeCommitからAnsibleのPlaybookを取得し、自己セットアップするスクリプトを書いてみました。

#!/bin/bash
ANSIBLE_PLAYBOOK_REPO=https://git-codecommit.us-east-1.amazonaws.com/v1/repos/example-playbook
ANSIBLE_PLAYBOOK_DIR=/var/ansible-playbook
ANSIBLE_PLAYBOOK=site.yml

# system update
yum -y update
# get ansible-playbook from CodeCommit
yum -y install git
git clone --config credential.helper='!aws --region us-east-1 codecommit credential-helper $@' --config credential.UseHttpPath=true $ANSIBLE_PLAYBOOK_REPO $ANSIBLE_PLAYBOOK_DIR
# run ansible (local)
cd $ANSIBLE_PLAYBOOK_DIR
pip install ansible
/usr/local/bin/ansible-playbook $ANSIBLE_PLAYBOOK

cloud-initでは、gitのconfigファイルを利用できないため、gitコマンドに直接credential-helperオプションを指定します。 cloud-initでの実行時なので、SSHアクセスやアクセスキーの利用は難しいですが、Roleを利用することでシンプルに実行することができます。

まとめ

これまで、EC2のAutoScalingを利用する時にネックだったのは、環境構築済みのゴールデンAMIを作成することでした。 ゴールデンAMIは起動が速いというメリットはありますが、環境が変更されるごとにAMIを作り直さなければいけないという手間があります。 一方、素のAmazonLinuxなどをcloud-initでセットアップする場合、複雑なコードとなる上コード管理がしにくく、デバッグが辛いため、なかなか手が出ませんでした。

もう、安心ですね。 CodeCommitからRoleを利用して定義ファイル(Playbook)を取得すれば、cloud-initでAnsibleによるセットアップが可能です。 さらにCodeDeployを組み合わせれば、縮退性にすぐれたサーバ環境を構築できます。

それでは、良いお年を!

AWS Cloud Roadshow 2017 福岡