[JAWS-UG CLI] CodePipeline #1 パイプラインの作成

AWS CLIを利用して、CodePipeline上にパイプラインを作成してみます。


前提条件
========


CodePipelineへの権限
--------------------

CodePipelineに対してフル権限があること。


AWS CLIのバージョン
-------------------

以下のバージョンで動作確認済

- AWS CLI 1.11.2

```bash:コマンド:
aws --version
```

```json:結果(例):
      aws-cli/1.11.2 Python/2.7.11 Darwin/15.6.0 botocore/1.4.60
```

バージョンが古い場合は最新版に更新しましょう。

```bash:コマンド:
sudo -H pip install -U awscli
```


0. 準備
=======


0.1. リージョンの決定
---------------------

構築するリージョンを決めます。 (カレントユーザが利用するカレントリージョンも切り変わります。)

```bash:コマンド(バージニアリージョンの場合):
export AWS_DEFAULT_REGION='us-east-1'
```

注釈: 2016-10-10時点でCodePipelineはus-east-1/us-west-2/eu-west-1で提供されています。


0.2. 変数の確認
---------------

プロファイルが想定のものになっていることを確認します。

```bash:コマンド:
aws configure list
```

```text:結果(例)
            Name                    Value             Type    Location
            ----                    -----             ----    --------
         profile         codepipelineFull-prjz-mbp13        env    AWS_DEFAULT_PROFILE
      access_key     ****************XXXX shared-credentials-file
      secret_key     ****************XXXX shared-credentials-file
          region                         us-east-1  env    AWS_DEFAULT_REGION
```

AssumeRoleを利用している場合はprofileが '<not set>'と表示されます。 それ以外のときにprofileが '<not set>' と表示される場合は、以下を実行してください。

```text:変数の設定:
export AWS_DEFAULT_PROFILE=<IAMユーザ名>
```


1. 事前作業
===========

# 1.1. AWS IDの取得

```bash:コマンド:
AWS_ID=$( \
  aws sts get-caller-identity \
    --query 'Account' \
    --output text \
) \
  && echo ${AWS_ID}
```



1.1. パイプライン名の決定
-------------------------

```bash:変数の設定
CODEP_PIPELINE_NAME='handson-20161010'
```

同名のパイプラインが存在しないことを確認します。

```bash:コマンド:
aws codepipeline get-pipeline \
        --name ${CODEP_PIPELINE_NAME}
```

```json:結果(例):
      An error occurred (PipelineNotFoundException) when calling the GetPipeline operation: Account 'XXXXXXXXXXXX' does not have a pipeline with name 'handson-20161010'
```


1.2. IAMロールの指定
--------------------

```bash:変数の設定
IAM_ROLE_NAME='oneClick_AWS-CodePipeline-Service'
```

```bash:コマンド:
IAM_ROLE_ARN=$( \
        aws iam get-role \
          --role-name ${IAM_ROLE_NAME} \
          --query 'Role.Arn' \
          --output text \
) \
        && echo ${IAM_ROLE_ARN}
```

```json:結果(例):
      arn:aws:iam::XXXXXXXXXXXX:role/oneClick_AWS-CodePipeline-Service
```


1.3. S3バケットの指定
---------------------

```bash:変数の設定
S3_BUCKET_NAME="codepipeline-${AWS_DEFAULT_REGION}-${AWS_ID}" \
  && echo ${S3_BUCKET_NAME}
```

```bash:コマンド:
aws s3 mb s3://${S3_BUCKET_NAME}
```


1.4. リポジトリの指定
---------------------

CodeCommit上のリポジトリとブランチを指定します。

```bash:変数の設定
CODEC_REPOSITORY_NAME='handson-20161010'
      CODEC_BRANCH_NAME='master'
```


2. パイプラインの作成
=====================


2.2. パイプラインの雛形作成
---------------------------

```bash:変数の設定
FILE_INPUT="${CODEP_PIPELINE_NAME}.json" \
        && echo ${FILE_INPUT}
```

```bash:変数の確認
cat << ETX

        IAM_ROLE_ARN:            ${IAM_ROLE_ARN}
        S3_BUCKET_NAME:          ${S3_BUCKET_NAME}
        CODEC_BRANCH_NAME:       ${CODEC_BRANCH_NAME}
        CODEC_REPOSITORY_NAME:   ${CODEC_REPOSITORY_NAME}
        CODED_DEPLOY_GROUP_NAME: ${CODED_DEPLOY_GROUP_NAME}
        CODED_APP_NAME:          ${CODED_APP_NAME}
        CODEP_PIPELINE_NAME:     ${CODEP_PIPELINE_NAME}
        FILE_INPUT:              ${FILE_INPUT}

ETX
```

```bash:コマンド:
cat << EOF > ${FILE_INPUT}
{
        "pipeline": {
          "roleArn": "${IAM_ROLE_ARN}",
          "stages": [
              {
                  "name": "Source",
                  "actions": [
                      {
                          "inputArtifacts": [],
                          "name": "Source",
                          "actionTypeId": {
                              "category": "Source",
                              "owner": "AWS",
                              "version": "1",
                              "provider": "CodeCommit"
                          },
                          "outputArtifacts": [
                              {
                                  "name": "MyApp"
                              }
                          ],
                          "configuration": {
                              "BranchName": "${CODEC_BRANCH_NAME}",
                              "RepositoryName": "${CODEC_REPOSITORY_NAME}"
                          },
                          "runOrder": 1
                      }
                  ]
              },
              {
                  "name": "Beta",
                  "actions": [
                      {
                          "inputArtifacts": [
                              {
                                  "name": "MyApp"
                              }
                          ],
                          "name": "${CODED_DEPLOY_GROUP_NAME}",
                          "actionTypeId": {
                              "category": "Deploy",
                              "owner": "AWS",
                              "version": "1",
                              "provider": "CodeDeploy"
                          },
                          "outputArtifacts": [],
                          "configuration": {
                              "ApplicationName": "${CODED_APP_NAME}",
                              "DeploymentGroupName": "${CODED_DEPLOY_GROUP_NAME}"
                          },
                          "runOrder": 1
                      }
                  ]
              }
          ],
          "artifactStore": {
              "type": "S3",
              "location": "${S3_BUCKET_NAME}"
          },
          "name": "${CODEP_PIPELINE_NAME}",
          "version": 1
        }
}
EOF

cat ${FILE_INPUT}
```

JSONファイルを作成したら、フォーマットが壊れてないか必ず確認します。

```bash:コマンド:
jsonlint -q ${FILE_INPUT}
```

```text:結果:
      (戻り値なし)
```


2.1. パイプラインの作成
-----------------------

```bash:コマンド:
aws codepipeline create-pipeline \
        --cli-input-json file://${FILE_INPUT}
```

```json:結果(例):
      {
        "pipeline": {
          "roleArn": "arn:aws:iam::XXXXXXXXXXXX:role/oneClick_AWS-CodePipeline-Service",
          "stages": [
              {
                  "name": "Source",
                  "actions": [
                      {
                          "inputArtifacts": [],
                          "name": "Source",
                          "actionTypeId": {
                              "category": "Source",
                              "owner": "AWS",
                              "version": "1",
                              "provider": "CodeCommit"
                          },
                          "outputArtifacts": [
                              {
                                  "name": "MyApp"
                              }
                          ],
                          "configuration": {
                              "BranchName": "handson-20161010",
                              "RepositoryName": "handson-20161010"
                          },
                          "runOrder": 1
                      }
                  ]
              },
              {
                  "name": "Beta",
                  "actions": [
                      {
                          "inputArtifacts": [
                              {
                                  "name": "MyApp"
                              }
                          ],
                          "name": "handson-app-20161010-deployment-group",
                          "actionTypeId": {
                              "category": "Deploy",
                              "owner": "AWS",
                              "version": "1",
                              "provider": "CodeDeploy"
                          },
                          "outputArtifacts": [],
                          "configuration": {
                              "ApplicationName": "handson-app-20161010",
                              "DeploymentGroupName": "handson-app-20161010-deployment-group"
                          },
                          "runOrder": 1
                      }
                  ]
              }
          ],
          "artifactStore": {
              "type": "S3",
              "location": "codepipeline-us-east-1-123456789012"
          },
          "name": "handson-20161010",
          "version": 1
        }
      }
```


2.2. パイプラインの一覧
-----------------------

```bash:コマンド:
aws codepipeline list-pipelines 
```

```json:結果(例):
      {
        "pipelines": [
          {
              "updated": 1234567890.123,
              "version": 1,
              "name": "handson-20161010",
              "created": 1234567890.123
          }
        ]
      }
```


2.3. パイプラインの確認
-----------------------

```bash:コマンド:
aws codepipeline get-pipeline \
        --name ${CODEP_PIPELINE_NAME}
```

```json:結果:
      {
        "pipeline": {
          "roleArn": "arn:aws:iam::XXXXXXXXXXXX:role/oneClick_AWS-CodePipeline-Service",
          "stages": [
              {
                  "name": "Source",
                  "actions": [
                      {
                          "inputArtifacts": [],
                          "name": "Source",
                          "actionTypeId": {
                              "category": "Source",
                              "owner": "AWS",
                              "version": "1",
                              "provider": "CodeCommit"
                          },
                          "outputArtifacts": [
                              {
                                  "name": "MyApp"
                              }
                          ],
                          "configuration": {
                              "BranchName": "master",
                              "RepositoryName": "handson-20161010"
                          },
                          "runOrder": 1
                      }
                  ]
              },
              {
                  "name": "Beta",
                  "actions": [
                      {
                          "inputArtifacts": [
                              {
                                  "name": "MyApp"
                              }
                          ],
                          "name": "handson-app-20161010-deployment-group",
                          "actionTypeId": {
                              "category": "Deploy",
                              "owner": "AWS",
                              "version": "1",
                              "provider": "CodeDeploy"
                          },
                          "outputArtifacts": [],
                          "configuration": {
                              "ApplicationName": "handson-app-20161010",
                              "DeploymentGroupName": "handson-app-20161010-deployment-group"
                          },
                          "runOrder": 1
                      }
                  ]
              }
          ],
          "artifactStore": {
              "type": "S3",
              "location": "codepipeline-us-east-1-123456789012"
          },
          "name": "handson-20161010",
          "version": 1
        }
      }
```


3. 事後作業
===========


パイプラインのステータス確認
----------------------------

```bash:コマンド:
aws codepipeline get-pipeline-state \
        --name ${CODEP_PIPELINE_NAME}
```

```json:結果(例):
      {
        "updated": 1234567890.123,
        "created": 1234567890.123,
        "pipelineVersion": 1,
        "pipelineName": "handson-20161010",
        "stageStates": [
          {
              "actionStates": [
                  {
                      "actionName": "Source",
                      "revisionUrl": "https://us-east-1.console.aws.amazon.com/codecommit/home#/repository/handson-20161010/browse/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/--/",
                      "entityUrl": "https://us-east-1.console.aws.amazon.com/codecommit/home#/repository/handson-20161010/browse/master/--/",
                      "latestExecution": {
                          "status": "Succeeded",
                          "lastStatusChange": 1234567890.12
                      },
                      "currentRevision": {
                          "revisionId": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                          "created": 1234567890.123
                      }
                  }
              ],
              "latestExecution": {
                  "pipelineExecutionId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
                  "status": "Succeeded"
              },
              "stageName": "Source"
          },
          {
              "actionStates": [
                  {
                      "actionName": "handson-app-20161010-deployment-group",
                      "entityUrl": "https://us-east-1.console.aws.amazon.com/codedeploy/home?#/applications/handson-app-20161010",
                      "latestExecution": {
                          "status": "Succeeded",
                          "lastStatusChange": 1234567890.123,
                          "externalExecutionUrl": "https://us-east-1.console.aws.amazon.com/codedeploy/home?#/deployments/d-xxxxxxxxx",
                          "externalExecutionId": "d-xxxxxxxxx",
                          "summary": "Deployment Succeeded"
                      },
                      "currentRevision": {
                          "revisionId": "{"bucket":"codepipeline-us-east-1-xxxxxxxxxxxx","key":"handson-20161010/MyApp/xxxxxxx","bundleType":"zip","version":null,"etag":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-x"}",
                          "created": 1234567890.123
                      }
                  }
              ],
              "inboundTransitionState": {
                  "enabled": true
              },
              "latestExecution": {
                  "pipelineExecutionId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
                  "status": "Succeeded"
              },
              "stageName": "Beta"
          }
        ]
      }
```


完了
====