CodeDeploy オンプレミスをためしてみました。
結論
配布元に github を指定したときは、S3 へのアクセスは不要です。
codedeploy-agent が対応している配布元が、S3 か Github.com なので、そのままだと配布元データの場所はインターネット上になりますが、少しエージェントを手直しすれば、オンプレミスのリポジトリからデプロイできました。
サポートするOS
The AWS CodeDeploy agent has been tested
- Amazon Linux 2014.09.1, 2015.03, 2016.03.0, 2016.03.1
- Ubuntu Server 14.04 LTS
- Windows Server 2008 R2 and Windows Server 2012 R2
- Red Hat Enterprise Linux (RHEL) 7.x
今回は、Ubuntu 16.04.1 LTS で実験したため、リストにはありません。
The AWS CodeDeploy agent is available as open source for you to adapt to
your needs. It can be used with other on-premises instance operating
systems. For more information, go to the AWS CodeDeploy Agent repository in GitHub.
自分で直してね、ということで。
Ubuntu 16.04.1 LTS
Ruby2.0 が動作すればなんとかなりそうです。
rubyパッケージは2.3なので、PPAから ruby2.0
をインストールして直接エージェントをインストールします。
$ sudo apt-add-repository ppa:brightbox/ruby-ng
$ sudo apt-get update
$ sudo apt-get install ruby2.0 libruby2.0
エージェントを手動でインストールします。
$ wget https://aws-codedeploy-ap-northeast-1.s3.amazonaws.com/latest/install
$ wget https://aws-codedeploy-ap-northeast-1.s3.amazonaws.com/latest/VERSION
$ cat VERSION
{"rpm":"releases/codedeploy-agent-1.0-1.1037.noarch.rpm","deb":"releases/codedeploy-agent_1.0-1.1037_all.deb","msi":"releases/codedeploy-agent-1.0.1.998.msi"}
$ wget https://aws-codedeploy-ap-northeast-1.s3.amazonaws.com/releases/codedeploy-agent_1.0-1.1037_all.deb
$ sudo dpkg -i codedeploy-agent_1.0-1.1037_all.deb
dpkg -L codedeploy-agent するとインストールされたファイル一覧が表示されます。
一覧の中に設定ファイルがありました。
/etc/codedeploy-agent/conf/codedeployagent.yml
---
:log_aws_wire: false
:log_dir: '/var/log/aws/codedeploy-agent/'
:pid_dir: '/opt/codedeploy-agent/state/.pid/'
:program_name: codedeploy-agent
:root_dir: '/opt/codedeploy-agent/deployment-root'
:verbose: false
:wait_between_runs: 1
:proxy_uri:
:max_revisions: 5
セットアップ
$ export AWS_REGION=us-east-1
$ NAME=Ubuntu-16
$ IAM_USER_ARN=arn:aws:iam::XXXXXXXXXXXX:user/XXXXXXXXXX
ここで使用する IAM ユーザには、つぎの内容のポリシーをアタッチして作成してあります。
ポリシー > CodeDeply-On-Premises
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"codedeploy:*",
"iam:CreateAccessKey",
"iam:CreateUser",
"iam:DeleteAccessKey",
"iam:DeleteUser",
"iam:DeleteUserPolicy",
"iam:ListAccessKeys",
"iam:ListUserPolicies",
"iam:PutUserPolicy",
"iam:GetUser",
"tag:GetTags",
"tag:GetResources"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"s3:Get*",
"s3:List*"
],
"Resource": [
"arn:aws:s3:::aws-codedeploy-us-east-1/*",
"arn:aws:s3:::aws-codedeploy-us-east-2/*",
"arn:aws:s3:::aws-codedeploy-us-west-1/*",
"arn:aws:s3:::aws-codedeploy-us-west-2/*",
"arn:aws:s3:::aws-codedeploy-ap-northeast-1/*",
"arn:aws:s3:::aws-codedeploy-ap-northeast-2/*",
"arn:aws:s3:::aws-codedeploy-ap-south-1/*",
"arn:aws:s3:::aws-codedeploy-ap-southeast-1/*",
"arn:aws:s3:::aws-codedeploy-ap-southeast-2/*",
"arn:aws:s3:::aws-codedeploy-eu-central-1/*",
"arn:aws:s3:::aws-codedeploy-eu-west-1/*",
"arn:aws:s3:::aws-codedeploy-sa-east-1/*"
]
}
]
}
オンプレミスインスタンスの登録
$ aws deploy register-on-premises-instance --instance-name $NAME --iam-user-arn $IAM_USER_ARN --region $AWS_REGION
$ aws deploy add-tags-to-on-premises-instances
--instance-name $NAME --tags Key=Name,Value=CodeDeploy-OnPremises
あるいは、一行でまとめて実行できます。
$ aws deploy register --instance-name $NAME --iam-user-arn $IAM_USER_ARN --region $AWS_REGION --tags Key=Name,Value=CodeDeploy-OnPremises
エージェントのインストール
$ sudo aws deploy install --override-config --config-file codedeploy.onpremises.yml
codedeploy.onpremises.yml
:
---
aws_access_key_id: XXXXXXXXXXXXXXXXXXXX
aws_secret_access_key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
iam_user_arn: arn:aws:iam::XXXXXXXXXXXX:user/XXXXXXXXXX
region: us-east-1
デプロイのセットアップ
アプリケーションを作成します。
aws deploy create-application --application-name MyApp --region $AWS_REGION
ロールを作成します。
aws iam create-role --role-name CodeDeploy-OnPremises --assume-role-policy-document file://CodeDeploy-Trust.json
CodeDeploy-Trust.json
:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": [ "codedeploy.us-east-1.amazonaws.com" ] }, "Action":
"sts:AssumeRole" } ] }
$ SERVICE_ROLE_ARN=arn:aws:iam::XXXXXXXXXXXX:role/CodeDeploy-OnPremises
オンプレミスインスタンスが使用するIAMユーザにロールをアタッチします。
aws iam attach-role-policy --role-name CodeDeployServiceRole --policy-arn $SERVICE_ROLE_ARN
デプロイメントグループを作成します。
aws deploy create-deployment-group \
--region $AWS_REGION --application-name MyApp \
--deployment-group-name MyDepGroup \
--deployment-config-name CodeDeployDefault.OneAtATime \
--on-premises-instance-tag-filters Key=Name,Value=Ubuntu-16,Type=KEY_AND_VALUE \
--service-role-arn $SERVICE_ROLE_ARN
デプロイ
デプロイしてみます。
appspec.yml
:
version: 0.0
os: linux
files:
- source: subtree
destination: /opt/codedeploy-on-premises
- source: README.md
destination: /opt/codedeploy-on-premises
- source: LICENSE
destination: /opt/codedeploy-on-premises
hooks:
ApplicationStop:
- location: scripts/application-stop.sh
timeout: 300
runas: root
BeforeInstall:
- location: scripts/before-install.sh
timeout: 300
runas: root
AfterInstall:
- location: scripts/after-install.sh
timeout: 300
runas: root
ApplicationStart:
- location: scripts/application-start.sh
timeout: 300
runas: root
ValidateService:
- location: scripts/validate-service.sh
timeout: 300
runas: root
$ aws deploy create-deployment --region $AWS_REGION --application-name MyApp --deployment-config-name CodeDeployDefault.OneAtATime --deployment-group-name MyDepGroup --github-location repository=xxxxx/yyyyyy,commitId=zzzzzzzz
クレデンシャルについて
EC2インスタンスの場合
インスタンスプロファイルで設定するので不要です。オンプレミス
codedeploy.onpremises.yml
で指定します。
登録ごとに1対1でIAMユーザが必要です。Github.com へのアクセス
マネージメントコンソールで 「Githubに接続」を実行しておけば、デプロイ時にOAuthのアクセストークンがエージェントに渡ってくるようです。
ログではマスクされて、 "GitHubAccessToken"=>"REDACTED" になります。
エージェントの動作
デプロイするファイルはここに展開されます。
/opt/codedeploy-agent/deployment-root/${DEPLOYMENT_GROUP_ID}/${DEPLOYMENT_ID}/deployment-archive
max_revisions
で指定した世代分保存されています。
ポーリング対象のURL。ここからコマンドを受け取っているようです。
vendor/gems/codedeploy-commands-1.0.0/lib/aws/plugins/deploy_control_endpoint.rb
:
url = "https://codedeploy-commands.#{cfg.region}.amazonaws.com"
poll_host_command(host_identifier: IAM_USER_ARN)
codedeployagent.yml
に proxy_uri
の項目があるので、プロキシサーバ経由でも使えるようです。(未確認)
ログファイルの場所
/var/log/aws/codedeploy-agent/codedeploy-agent.log
/opt/codedeploy-agent/deployment-root/deployment-logs/codedeploy-agent-deployments.log
フック
スクリプトの実行で、終了ステータス 0 のとき成功、それ以外の時は失敗です。
ApplicationStop だけ実行タイミングが異なります。
ApplicationStopで指定されたスクリプトは、今回のデプロイではなく、後のデプロイの時に、このデプロイしたアプリケーションを停止するためにに使用されます。
Install
appspec.yml
に書かれたインストール対象のファイルは、Install のステップで存在していれば良いようです。
files:
に記載しておいて、BeforeInstall スクリプトで準備することもできそうです。
たとえばこのように。
DEPLOYMENT_ROOT=/opt/codedeploy-agent/deployment-root
DEPLOYMENT_DIR=$DEPLOYMENT_ROOT/${DEPLOYMENT_GROUP_ID}/${DEPLOYMENT_ID}
[ -d $DEPLOYMENT_DIR/subtree ] || mkdir $DEPLOYMENT_DIR/subtree
cd /path/to/workset
git pull
rsync -a --exclude .git . $DEPLOYMENT_DIR/subtree/.
スクリプト中で利用できる環境変数
APPLICATION_NAME=デプロイアプリケーション名
DEPLOYMENT_GROUP_NAME=デプロイグループ名
DEPLOYMENT_GROUP_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
DEPLOYMENT_ID=d-XXXXXXXXX
LIFECYCLE_EVENT=ステージ名
AWS_HOST_IDENTIFIER=codedeploy.onpremises.ymlのiam_user_arn
AWS_ACCESS_KEY=codedeploy.onpremises.ymlのaws_access_key_id
AWS_SECRET_KEY=codedeploy.onpremises.ymlのaws_secret_access_key
AWS_REGION=リージョン名
PWD=/opt/codedeploy-agent
ステージ名: (ApplicationStop|BeforeInstall|AfterInstall|ApplicationStart|ValidateService)
手元のリポジトリからデプロイしたいとき
gitbucketをセットアップして実験しました。
エージェントの lib/instance_agent/plugins/codedeploy/command_executor.rb
の中にdownload_from_s3()
やdownload_from_github()
があります。
ここのURLを書き換えて、ダウンロードしてくるアーカイブのタイプも変更しました。
private
def download_from_github(deployment_spec, account, repo, commit,
anonymous, token)
retries = 0
errors = []
if InstanceAgent::Platform.util.supported_oses.include? 'windows'
deployment_spec.bundle_type = 'zip'
format = 'zipball'
else
#deployment_spec.bundle_type = 'tar'
#format = 'tarball'
deployment_spec.bundle_type = 'zip'
format = 'zip'
end
#uri = URI.parse("https://api.github.com/repos/#{account}/#{repo}/#{format}/#{commit}")
#options = {:ssl_verify_mode => OpenSSL::SSL::VERIFY_PEER, :redirect => true, :ssl_ca_cert => ENV['AWS_SSL_CA_DIRECTORY']}
uri = URI.parse("https://gitbucket.repository.local/#{account}/#{repo}/archive/#{commit}.#{format}")
options = {:ssl_verify_mode => OpenSSL::SSL::VERIFY_NONE, :redirect => true, :ssl_ca_cert => ENV['AWS_SSL_CA_DIRECTORY']}
ダウンロードはHTTP/HTTPSのみ対応可能です。
渡せるパラメータが限られるため、自由度はありません。
認証が必要な場合は、別途 BeforeInstall スクリプトで取得する方がよさそうです。
気になる点
Ruby 2.0.0系の公式サポートは2016年2月24日に終了しています。
Ruby 2.0.0系に関しては今後バグ修正や脆弱性修正のパッチがリリースされることはありません。
Ruby 2.3 に対応するのはいつになるのでしょう。