Help us understand the problem. What is going on with this article?

CodeDeploy オンプレミスをためしてみました

More than 3 years have passed since last update.

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.ymlproxy_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 に対応するのはいつになるのでしょう。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away