一條龍佈署 CI/CD 從 Travis 到 CodeDeploy 的 On-Premises (IAM User)

2017-04-23 AWS

之前有寫過一篇 一條龍佈署 CI/CD 從 Travis 到 CodeDeploy 的 On-Premises (IAM Role/STS) 的作法,對於 On-Premises 來說集中控管便於管理,而 AWS CodeDeploy 的另一個方式 IAM User 讓每一個 On-Premises Server 都擁有不同的 IAM User key 來訪問,這個作法我覺得有好有壞,

好在於你的 Key 要是不小心掉了,可以快速知道是哪一台發生問題,且不會所有 On-Premises 都淪陷

壞在於你的 IAM User 會多到爆炸 ..

 

關係架構圖

 

與使用 IAM Role/STS 不同的地方在於直接用 IAM User 訪問,而不再需要用 STS 交換 token 後用再 Assume Role 了

 

環境

  • Region(東京) = ap-northeast-1
  • 產品名稱 = project

在進行 CodeDeploy On-Premises 之前必須先確認你的網路環境允許連上以下 AWS 服務

  • S3 (每一個 S3 bucket 都是全球唯一的位址)
    • ${bucketname}.s3-${region}.amazonaws.com
  • CodeDeploy Server
    • codedeploy.${region}.amazonaws.com
  • AWSCLI 安裝
    • s3.amazonaws.com
  • CodeDeploy Agent 安裝
    • aws-codedeploy-us-east-1.s3.amazonaws.com (非 EC2 的 fail-safe mode 安裝位置)
    • aws-codedeploy-${region}.s3.amazonaws.com
    • codedeploy-commands.${region}.amazonaws.com

 

必要條件

用來建立以下服務的 IAM User 必須擁有以下權限

Attach

AWSCodeDeployFullAccess

lnline

iam:CreateAccessKey,
iam:CreateUser,
iam:DeleteAccessKey,
iam:DeleteUser,
iam:DeleteUserPolicy,
iam:ListAccessKeys,
iam:ListUserPolicies,
iam:PutUserPolicy,
iam:GetUser

此安裝將會建立以下 AWS 服務

  • 一個 S3 bucket
  • 一個 IAM User 給 Travis CI 使用 CodeDeploy, S3
  • 一個 IAM User 給 On-Premises 使用 CodeDeploy, S3 服務使用
  • 一個 IAM Role 給 CodeDeploy 服務使用
  • 一個 CodeDeploy Application 與 deployment_group
  • 在 CodeDeploy 註冊 On-Premises (register-on-premises-instance)

 

全程將使用 AWS command line 建立,將不會有 Web cosole 的執行過程

 

 

開始建立 CodeDeploy On-Premises (IAM User)

或者你可以用 shazi7804/codedeploy-permissions-onpremises 進行自動佈署。

 

Step 1: 建立 S3 bucket

$ aws s3api create-bucket --bucket codedeploy-project --region ap-northeast-1 --create-bucket-configuration LocationConstraint=ap-northeast-1

強者同事補充:根據 AWS-CLI 的 Help 指出,要在 eu-west-1 之外的 region 建 bucket,需要加上 LocationConstraint 參數。

確認可以訪問

$ aws s3 ls project

 

Step 2: 建立 IAM User for Travis CI

建立 IAM User

$ aws iam create-user --user-name travisci-project

 

Attach Policy – AWSCodeDeployDeployerAccess

$ aws iam attach-user-policy --user-name travisci-project --policy-arn arn:aws:iam::aws:policy/AWSCodeDeployDeployerAccess

 

lnline Policy – 授與 bucket name 為 codedeploy-project 有權限

$ tee travisci-project-lnline.json <<EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1487528506000",
            "Effect": "Allow",
            "Action": [
                "s3:*"
            ],
            "Resource": [
                "arn:aws:s3:::codedeploy-project/*"
            ]
        }
    ]
}
EOF
$ aws iam put-user-policy --user-name travis-project --policy-name s3-travisci-project --policy-document file://travisci-project-lnline.json
$ rm travisci-project-lnline.json

 

Step 3: 建立 IAM User for On-Premises

每一個 On-Premises 皆使用獨立的 IAM User,這邊示範建立 dev

$ aws iam create-user --user-name codedeploy-onpremises-project-dev

 

lnline IamPolicyfile.json

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "s3:GetObject",
        "s3:GetObjectVersion",
        "s3:ListBucket"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::codedeploy-project/*"
    }
  ]
}
$ aws iam put-user-policy --user-name codedeploy-onpremises-project-dev --policy-name iam-codedeploy-project-onpremises --policy-document file://IamPolicyfile.json.json
$ rm  IamPolicyfile.json

 

Step 4: 建立 IAM Role for CodeDeploy

給 CodeDeploy Server 的 IAM Role 一個 AWS account 僅需要一個。

$ tee role-codedeploy-trust.json <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "codedeploy.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF
$ aws iam create-role --role-name Role-CodeDeploy --assume-role-policy-document file://role-codedeploy-trust.json
$ rm role-codedeploy-trust.json

 

Attach policy

$ aws iam attach-role-policy --role-name Role-CodeDeploy --policy-arn arn:aws:iam::aws:policy/service-role/AWSCodeDeployRole

 

Create Profile

$ aws iam create-instance-profile --instance-profile-name Role_CodeDeploy-Profile

 

把 Role 和 Profile 關聯起來

$ aws iam add-role-to-instance-profile --role-name Role-CodeDeploy --instance-profile-name Role_CodeDeploy-Profile

 

Step 5: 建立 CodeDeploy

Create application

$ aws deploy create-application --application-name project --region ap-northeast-1

 

Create deployment_group (prod)

$ aws deploy create-deployment-group \
           --application-name project \
           --deployment-config-name CodeDeployDefault.AllAtOnce \
           --deployment-group-name prod \
           --service-role-arn arn:aws:iam::0123456789:role/Role-CodeDeploy \
           --region ap-northeast-1

 

Step 6: 註冊 CodeDeploy On-Premises

註冊 On-Premises instance

$ aws deploy register-on-premises-instance --instance-name project-dev --iam-user-arn arn:aws:iam::0123456789:user/codedeploy-onpremises-project-dev

 

替註冊的 On-Premises instance 加入 tags:Key=Name,Values=project-dev

$ aws deploy add-tags-to-on-premises-instances --instance-names project-dev --tags Key=Name,Values=project-dev

 

在 On-Premises Server 安裝 CodeDeploy

Step 1: 設定 Proxy

如果你的 On-Premises 不允許直接訪問外部網路,需要另外設定 Proxy,因為安裝 CodeDeploy 必須對外訪問。

建議先把他寫到 /etc/environment,否則在接下來的 sudo 會無法使用 export 環境變數

 

Step 2: 安裝 aws cli

$ sudo apt-get install -y wget unzip
$ cd /tmp
$ wget https://s3.amazonaws.com/aws-cli/awscli-bundle.zip
$ unzip awscli-bundle.zip
$ cd awscli-bundle
$ sudo chmod +x install
$ sudo ./install -i /usr/local/aws -b /usr/local/bin/aws

 

確認版本為最新的 aws cli

$ aws --version

 

在 On-Premises 必須取得 #Step 3: “建立 IAM User for On-Premises” 的 Access Key/ Secret Access Key,並且登記在 On-Premises Server 的 aws cli

$ aws configure

 

Step 3: 安裝 CodeDeploy agent

$ sudo apt-get install -y ruby
$ wget https://aws-codedeploy-ap-northeast-1.s3.amazonaws.com/latest/install
$ sudo chmod +x install
$ sudo ./install auto

install 有支援 proxy 參數,可以用 –proxy 解決

 

Step 4: 設定檔 codedeploy.onpremises.yml & codedeployagent.yml

建立 CodeDeploy On-Premises 需要使用的設定檔

$ sudo tee /etc/codedeploy-agent/conf/codedeploy.onpremises.yml <<EOF
---
aws_access_key_id: OnPremises IAM User 的 access key
aws_secret_access_key: OnPremises IAM User 的 secret key
iam_user_arn: arn:aws:iam::0123456789:user/codedeploy-project-onpremises-dev
region: ap-northeast-1
EOF
  • iam_session_arn 是在 #Step 6: “建立 CodeDeploy” 中建立的 sts session arn
  • aws_credentials_file 是要用來放 sts session 的 token and access key
  • region 為你 codedeploy 的所在地區

 

在 codedeployagent.yml 把 proxy 參數加入,讓 codedeploy agent 可以用 proxy 去更新

:proxy_uri: http://proxy.com:3128

 

重新啟動 CodeDeploy agent 把 proxy 的設定參數吃進去

$ sudo service codedeploy-agent restart

 

在 CodeDeploy 中決定 deploy 的 On-Premises instance tags

CodeDeploy 中的 deployment_group tags 必須和 On-Premises instance tags 符合才會進行 CodeDeploy。

你可以透過 Web cosole 在 CodeDeploy/Application/deployment_group/Search by tags 進行設定 tags,tags type 必須是 On-premises-instance

或是使用 awscli “更新” tags,此設定會直接覆蓋現有 tags,若有多筆 tags 可以用 json 或是多個 –on-premises-instance-tag-filters 來指定 tag

$ aws deploy update-deployment-group \
                       --application-name project \
                       --current-deployment-group-name master \
                       --on-premises-instance-tag-filters Key=Name,Value=project-dev,Type=KEY_AND_VALUE

 

或是用 json 更新 tags

$ tee multi_tags.json <<EOF
[
  {
    "Key": "project",
    "Value": "dev",
    "Type": "KEY_AND_VALUE"
  },
  {
    "Key": "project",
    "Value": "staging",
    "Type": "KEY_AND_VALUE"
  }
]
EOF
$ aws deploy update-deployment-group \
                       --application-name project \
                       --current-deployment-group-name master \
                       --on-premises-instance-tag-filters file://multi_tags.json

 

驗證

 

驗證服務正在使用

$ ps ax | grep codedeploy
codedeploy-agent: master 19248
codedeploy-agent: InstanceAgent::Plugins::CodeDeployPlugin::CommandPoller of master 19248

 

正常運作時 access codedeploy 的 log。

$ less /var/log/aws/codedeploy-agent/codedeploy-agent.log

2017-03-06 00:03:13 INFO  [codedeploy-agent(19252)]: Version file found in /opt/codedeploy-agent/.version.
2017-03-06 00:04:14 INFO  [codedeploy-agent(19252)]: [Aws::CodeDeployCommand::Client 200 61.019261 0 retries] poll_host_command(host_identifier:"arn:aws:sts::0123456789:assumed-role/Role-onpremises/project-session-server01")

收到 codedeploy 的 access log 狀態為 200

[codedeploy-agent(...)]: [Aws::CodeDeployCommand::Client 200 ....

 

 

Note

  • 已 register 的 On-Premises,如果要 deregister 必須等待 24H 後才會消除,一樣的 instance name 無法重複申請
  • CodeDeploy 的 On-Premises 方式不支援 Auto Scaling。
  • CodeDeploy 的 deploy tags 方式不支援 * 等字符,必須完整輸入 tag name。

Reference

CodeDeploy: deployment-config

2 Replies to “一條龍佈署 CI/CD 從 Travis 到 CodeDeploy 的 On-Premises (IAM User)”

  1. Yao-Siang Su表示:

    根據 AWS-CLI 的 Help 指出,要在 eu-west-1 之外的 region 建 bucket,需要加上 LocationConstraint 參數

    因此,以下指令可能要調整為:
    aws s3api create-bucket –bucket codedeploy-project –region ap-northeast-1 –create-bucket-configuration LocationConstraint=ap-northeast-1

給 Mr. 沙先生一點建議

彙整

分類

展開全部 | 收合全部

License

訂閱 Mr. 沙先生 的文章

輸入你的 email 用於訂閱