0
0

「AWS Hands-on for Beginners AWS Code サービス群を活用して、CI/CD のための構成を構築しよう!」をAWS CLIでやってみる

Last updated at Posted at 2024-09-14

上記、「AWS Hands-on for Beginners AWS Code サービス群を活用して、CI/CD のための構成を構築しよう!」 をAWS CLIでやってみる
image.png
ハンズオンから引用

Cloud9とCodeCommitは新規利用できなくなりました。
今まで利用したことがあるアカウントはまだ利用できるようです。

02 S3 をデプロイ先とした、CI/CD 環境を構築する【事前準備 + CodeCommit編】

S3バケット

変数

コマンド
# 変数
date_var=$(date +%Y%m%d) \
&& echo ${date_var}
S3_BUCKET_NAME="h4b-handson-${date_var}-bucket" \
&& echo ${S3_BUCKET_NAME}
REGION="ap-northeast-1" \
&& echo ${REGION}

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # 変数
[cloudshell-user@ip-10-132-76-170 ~]$ date_var=$(date +%Y%m%d) \
> && echo ${date_var}
20240914
[cloudshell-user@ip-10-132-76-170 ~]$ S3_BUCKET_NAME="h4b-handson-${date_var}-bucket" \
> && echo ${S3_BUCKET_NAME}
h4b-handson-20240914-bucket
[cloudshell-user@ip-10-132-76-170 ~]$ REGION="ap-northeast-1" \
> && echo ${REGION}
ap-northeast-1

作成

コマンド
# バケット作成
aws s3api create-bucket \
    --bucket ${S3_BUCKET_NAME} \
    --create-bucket-configuration LocationConstraint=${REGION}

# パブリックアクセスをすべてブロック:オフ
aws s3api put-public-access-block \
    --bucket ${S3_BUCKET_NAME} \
    --public-access-block-configuration 'BlockPublicAcls=false,IgnorePublicAcls=false,BlockPublicPolicy=false,RestrictPublicBuckets=false'

# バケットの静的ウェブサイトホスティングを有効にする
aws s3 website s3://${S3_BUCKET_NAME}/ \
    --index-document index.html

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # バケット作成
[cloudshell-user@ip-10-132-76-170 ~]$ aws s3api create-bucket \
>     --bucket ${S3_BUCKET_NAME} \
>     --create-bucket-configuration LocationConstraint=${REGION}
{
    "Location": "http://h4b-handson-20240914-bucket.s3.amazonaws.com/"
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # パブリックアクセスをすべてブロック:オフ
[cloudshell-user@ip-10-132-76-170 ~]$ aws s3api put-public-access-block \
>     --bucket ${S3_BUCKET_NAME} \
>     --public-access-block-configuration 'BlockPublicAcls=false,IgnorePublicAcls=false,BlockPublicPolicy=false,RestrictPublicBuckets=false'
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # バケットの静的ウェブサイトホスティングを有効にする
[cloudshell-user@ip-10-132-76-170 ~]$ aws s3 website s3://${S3_BUCKET_NAME}/ \
>     --index-document index.html

バケットポリシー適用

コマンド
# バケットポリシー(JSON)
BACKET_POLICY=$(cat << EOF
{
  "Version": "2012-10-17",
  "Statement": [
      {
          "Sid": "PublicReadGetObject",
          "Effect": "Allow",
          "Principal": "*",
          "Action": [
              "s3:GetObject"
          ],
          "Resource": [
              "arn:aws:s3:::${S3_BUCKET_NAME}/*"
          ]
      }
  ]
}
EOF
) \
&& echo ${BACKET_POLICY}

# JSONフォーマットの確認
echo ${BACKET_POLICY} | python -m json.tool

# バケットポリシー
aws s3api put-bucket-policy \
    --bucket ${S3_BUCKET_NAME} \
    --policy "${BACKET_POLICY}"

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # バケットポリシー(JSON)
[cloudshell-user@ip-10-132-76-170 ~]$ BACKET_POLICY=$(cat << EOF
> {
>   "Version": "2012-10-17",
>   "Statement": [
>       {
>           "Sid": "PublicReadGetObject",
>           "Effect": "Allow",
>           "Principal": "*",
>           "Action": [
>               "s3:GetObject"
>           ],
>           "Resource": [
>               "arn:aws:s3:::${S3_BUCKET_NAME}/*"
>           ]
>       }
>   ]
> }
> EOF
> ) \
> && echo ${BACKET_POLICY}
{ "Version": "2012-10-17", "Statement": [ { "Sid": "PublicReadGetObject", "Effect": "Allow", "Principal": "*", "Action": [ "s3:GetObject" ], "Resource": [ "arn:aws:s3:::h4b-handson-20240914-bucket/*" ] } ] }
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-132-76-170 ~]$ echo ${BACKET_POLICY} | python -m json.tool
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::h4b-handson-20240914-bucket/*"
            ]
        }
    ]
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # バケットポリシー
[cloudshell-user@ip-10-132-76-170 ~]$ aws s3api put-bucket-policy \
>     --bucket ${S3_BUCKET_NAME} \
>     --policy "${BACKET_POLICY}"

ファイルのアップロード

コマンド
aws s3 cp index.html s3://${S3_BUCKET_NAME}/

出力
[cloudshell-user@ip-10-132-76-170 ~]$ aws s3 cp index.html s3://${S3_BUCKET_NAME}/
upload: ./index.html to s3://h4b-handson-20240914-bucket/index.html

アクセス確認

コマンド
curl http://${S3_BUCKET_NAME}.s3-website-${REGION}.amazonaws.com

出力
[cloudshell-user@ip-10-132-76-170 ~]$ curl http://${S3_BUCKET_NAME}.s3-website-${REGION}.amazonaws.com
<!DOCTYPE html>

<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>S3 Static Web Hosting</title>
</head>
<body>
  Hello, AWS World!!
</body>
</html>

CodeCommit

変数

コマンド
REPOSITORY_NAME="h4b-hands-on" \
&& echo ${REPOSITORY_NAME}

出力
[cloudshell-user@ip-10-132-76-170 ~]$ REPOSITORY_NAME="h4b-hands-on" \
> && echo ${REPOSITORY_NAME}
h4b-hands-on

作成

コマンド
# 作成
aws codecommit create-repository \
    --repository-name ${REPOSITORY_NAME}

# ARN取得
CODECOMMIT_ARN=$(
    aws codecommit get-repository \
        --repository-name ${REPOSITORY_NAME} \
        --query repositoryMetadata.Arn\
        --output text
) \
&& echo ${CODECOMMIT_ARN}

# クローンURL取得
CLONEURLHTTP=$(
    aws codecommit get-repository \
        --repository-name ${REPOSITORY_NAME} \
        --query repositoryMetadata.cloneUrlHttp \
        --output text
) \
&& echo ${CLONEURLHTTP}

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # 作成
[cloudshell-user@ip-10-132-76-170 ~]$ aws codecommit create-repository \
>     --repository-name ${REPOSITORY_NAME}
{
    "repositoryMetadata": {
        "accountId": "999999999999",
        "repositoryId": "944f7933-79af-41e8-a9af-35db1f7d0324",
        "repositoryName": "h4b-hands-on",
        "lastModifiedDate": "2024-09-14T06:11:57.395000+00:00",
        "creationDate": "2024-09-14T06:11:57.395000+00:00",
        "cloneUrlHttp": "https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/h4b-hands-on",
        "cloneUrlSsh": "ssh://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/h4b-hands-on",
        "Arn": "arn:aws:codecommit:ap-northeast-1:999999999999:h4b-hands-on",
        "kmsKeyId": "arn:aws:kms:ap-northeast-1:999999999999:key/be6cce38-51e3-4f2b-b1a3-b33b3ace5ca0"
    }
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # ARN取得
[cloudshell-user@ip-10-132-76-170 ~]$ CODECOMMIT_ARN=$(
>     aws codecommit get-repository \
>         --repository-name ${REPOSITORY_NAME} \
>         --query repositoryMetadata.Arn\
>         --output text
> ) \
> && echo ${CODECOMMIT_ARN}
arn:aws:codecommit:ap-northeast-1:999999999999:h4b-hands-on
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # クローンURL取得
[cloudshell-user@ip-10-132-76-170 ~]$ CLONEURLHTTP=$(
>     aws codecommit get-repository \
>         --repository-name ${REPOSITORY_NAME} \
>         --query repositoryMetadata.cloneUrlHttp \
>         --output text
> ) \
> && echo ${CLONEURLHTTP}
https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/h4b-hands-on

Cloud9

変数

コマンド
# Cloud9環境名
CLOUD9_ENVIRONMENT_NAME="aws-code-hands-on" \
&& echo ${CLOUD9_ENVIRONMENT_NAME}

# インスタンスタイプ
CLOUD9_INSTANCE_TYPE="t2.micro" \
&& echo ${CLOUD9_INSTANCE_TYPE}

# プラットフォーム
CLOUD9_IMAGE_ID="resolve:ssm:/aws/service/cloud9/amis/amazonlinux-2-x86_64" \
&& echo ${CLOUD9_IMAGE_ID}

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # Cloud9環境名
[cloudshell-user@ip-10-132-76-170 ~]$ CLOUD9_ENVIRONMENT_NAME="aws-code-hands-on" \
> && echo ${CLOUD9_ENVIRONMENT_NAME}
aws-code-hands-on
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # インスタンスタイプ
[cloudshell-user@ip-10-132-76-170 ~]$ CLOUD9_INSTANCE_TYPE="t2.micro" \
> && echo ${CLOUD9_INSTANCE_TYPE}
t2.micro
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # プラットフォーム
[cloudshell-user@ip-10-132-76-170 ~]$ CLOUD9_IMAGE_ID="resolve:ssm:/aws/service/cloud9/amis/amazonlinux-2-x86_64" \
> && echo ${CLOUD9_IMAGE_ID}
resolve:ssm:/aws/service/cloud9/amis/amazonlinux-2-x86_64

作成

コマンド
# Cloud9環境作成
CLOUD9_ENVIRONMENT_ID=$(
    aws cloud9 create-environment-ec2 \
        --name ${CLOUD9_ENVIRONMENT_NAME} \
        --instance-type ${CLOUD9_INSTANCE_TYPE} \
        --image-id ${CLOUD9_IMAGE_ID} \
        --connection-type CONNECT_SSM \
        --automatic-stop-time-minutes 30 \
        --query environmentId \
        --output text
) \
&& echo ${CLOUD9_ENVIRONMENT_ID}

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # Cloud9環境作成
[cloudshell-user@ip-10-132-76-170 ~]$ CLOUD9_ENVIRONMENT_ID=$(
>     aws cloud9 create-environment-ec2 \
>         --name ${CLOUD9_ENVIRONMENT_NAME} \
>         --instance-type ${CLOUD9_INSTANCE_TYPE} \
>         --image-id ${CLOUD9_IMAGE_ID} \
>         --connection-type CONNECT_SSM \
>         --automatic-stop-time-minutes 30 \
>         --query environmentId \
>         --output text
> ) \
> && echo ${CLOUD9_ENVIRONMENT_ID}
ed3b1f77024c4af9a55a94214b74ff54

以降、Cloud9で実施

認証ヘルパー

コマンド
git config --global credential.helper '!aws codecommit credential-helper $@'
git config --global credential.UseHttpPath true
git config --global user.name "username"
git config --global user.email "username@example.com"

出力
admin:~/environment $ git config --global credential.helper '!aws codecommit credential-helper $@'
admin:~/environment $ git config --global credential.UseHttpPath true
admin:~/environment $ git config --global user.name "username"
admin:~/environment $ git config --global user.email "username@example.com"

CLONEURLHTTPは適宜変更

コマンド
CLONEURLHTTP="https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/h4b-hands-on"
git clone ${CLONEURLHTTP}
cd h4b-hands-on/

出力
admin:~/environment $ CLONEURLHTTP="https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/h4b-hands-on"
admin:~/environment $ git clone ${CLONEURLHTTP}
Cloning into 'h4b-hands-on'...
warning: You appear to have cloned an empty repository.
admin:~/environment $ cd h4b-hands-on/
admin:~/environment/h4b-hands-on (master) $ 

WebUIで/home/ec2-user/environment/h4b-hands-onにindex.htmlをアップロード後に以下を実施

コマンド
git add -A
git commit -m "init."
git push origin master

出力
admin:~/environment/h4b-hands-on (master) $ git add -A
admin:~/environment/h4b-hands-on (master) $ git commit -m "init."
[master (root-commit) 1c189c5] init.
 1 file changed, 11 insertions(+)
 create mode 100644 index.html
admin:~/environment/h4b-hands-on (master) $ git push origin master
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 335 bytes | 335.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
remote: Validating objects: 100%
To https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/h4b-hands-on
 * [new branch]      master -> master

以降、CloudShellで実施

リポジトリの確認

コマンド
aws codecommit get-folder \
    --repository-name ${REPOSITORY_NAME} \
    --folder-path /

出力
[cloudshell-user@ip-10-132-76-170 ~]$ aws codecommit get-folder \
>     --repository-name ${REPOSITORY_NAME} \
>     --folder-path /
{
    "commitId": "1c189c5b91ee7b0685e7cc3855f7685fb651f114",
    "folderPath": "",
    "treeId": "7a6801edd926242e01e4ab62c9aecbb63946bb05",
    "subFolders": [],
    "files": [
        {
            "blobId": "c5f146332875b0c706ce665a2fd8f2be55859a25",
            "absolutePath": "index.html",
            "relativePath": "index.html",
            "fileMode": "NORMAL"
        }
    ],
    "symbolicLinks": [],
    "subModules": []
}

03 S3 をデプロイ先とした、CI/CD 環境を構築する【CodePipeline 編】

変数

コマンド
# パイプライン名
PIPELINE_NAME="h4b-hands-on-s3" \
&& echo ${PIPELINE_NAME}

# ポリシー名
PIPELINE_IAM_POLICY_NAME="AWSCodePipelineServiceRole-ap-northeast-1" \
&& echo ${PIPELINE_IAM_POLICY_NAME}

# ロール名
PIPELINE_IAM_ROLE_NAME="AWSCodePipelineServiceRole-ap-northeast-1" \
&& echo ${PIPELINE_IAM_ROLE_NAME}

# IAMパス
IAM_PATH="/service-role/" \
&& echo ${IAM_PATH}

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # パイプライン名
[cloudshell-user@ip-10-132-76-170 ~]$ PIPELINE_NAME="h4b-hands-on-s3" \
> && echo ${PIPELINE_NAME}
h4b-hands-on-s3
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # ポリシー名
[cloudshell-user@ip-10-132-76-170 ~]$ PIPELINE_IAM_POLICY_NAME="AWSCodePipelineServiceRole-ap-northeast-1" \
> && echo ${PIPELINE_IAM_POLICY_NAME}
AWSCodePipelineServiceRole-ap-northeast-1
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # ロール名
[cloudshell-user@ip-10-132-76-170 ~]$ PIPELINE_IAM_ROLE_NAME="AWSCodePipelineServiceRole-ap-northeast-1" \
> && echo ${PIPELINE_IAM_ROLE_NAME}
AWSCodePipelineServiceRole-ap-northeast-1
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # IAMパス
[cloudshell-user@ip-10-132-76-170 ~]$ IAM_PATH="/service-role/" \
> && echo ${IAM_PATH}
/service-role/

IAM

IAMポリシー

コマンド
# IAMポリシー
POLICY_DOCUMENT_JSON=$(cat << EOF
{
    "Statement": [
        {
            "Action": [
                "iam:PassRole"
            ],
            "Resource": "*",
            "Effect": "Allow",
            "Condition": {
                "StringEqualsIfExists": {
                    "iam:PassedToService": [
                        "cloudformation.amazonaws.com",
                        "elasticbeanstalk.amazonaws.com",
                        "ec2.amazonaws.com",
                        "ecs-tasks.amazonaws.com"
                    ]
                }
            }
        },
        {
            "Action": [
                "codecommit:CancelUploadArchive",
                "codecommit:GetBranch",
                "codecommit:GetCommit",
                "codecommit:GetRepository",
                "codecommit:GetUploadArchiveStatus",
                "codecommit:UploadArchive"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "codedeploy:CreateDeployment",
                "codedeploy:GetApplication",
                "codedeploy:GetApplicationRevision",
                "codedeploy:GetDeployment",
                "codedeploy:GetDeploymentConfig",
                "codedeploy:RegisterApplicationRevision"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "codestar-connections:UseConnection"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "elasticbeanstalk:*",
                "ec2:*",
                "elasticloadbalancing:*",
                "autoscaling:*",
                "cloudwatch:*",
                "s3:*",
                "sns:*",
                "cloudformation:*",
                "rds:*",
                "sqs:*",
                "ecs:*"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "lambda:InvokeFunction",
                "lambda:ListFunctions"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "opsworks:CreateDeployment",
                "opsworks:DescribeApps",
                "opsworks:DescribeCommands",
                "opsworks:DescribeDeployments",
                "opsworks:DescribeInstances",
                "opsworks:DescribeStacks",
                "opsworks:UpdateApp",
                "opsworks:UpdateStack"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "cloudformation:CreateStack",
                "cloudformation:DeleteStack",
                "cloudformation:DescribeStacks",
                "cloudformation:UpdateStack",
                "cloudformation:CreateChangeSet",
                "cloudformation:DeleteChangeSet",
                "cloudformation:DescribeChangeSet",
                "cloudformation:ExecuteChangeSet",
                "cloudformation:SetStackPolicy",
                "cloudformation:ValidateTemplate"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "codebuild:BatchGetBuilds",
                "codebuild:StartBuild",
                "codebuild:BatchGetBuildBatches",
                "codebuild:StartBuildBatch"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Effect": "Allow",
            "Action": [
                "devicefarm:ListProjects",
                "devicefarm:ListDevicePools",
                "devicefarm:GetRun",
                "devicefarm:GetUpload",
                "devicefarm:CreateUpload",
                "devicefarm:ScheduleRun"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "servicecatalog:ListProvisioningArtifacts",
                "servicecatalog:CreateProvisioningArtifact",
                "servicecatalog:DescribeProvisioningArtifact",
                "servicecatalog:DeleteProvisioningArtifact",
                "servicecatalog:UpdateProduct"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "cloudformation:ValidateTemplate"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "ecr:DescribeImages"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "states:DescribeExecution",
                "states:DescribeStateMachine",
                "states:StartExecution"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "appconfig:StartDeployment",
                "appconfig:StopDeployment",
                "appconfig:GetDeployment"
            ],
            "Resource": "*"
        }
    ],
    "Version": "2012-10-17"
}
EOF
) \
&& echo ${POLICY_DOCUMENT_JSON}

# JSONフォーマットの確認
echo ${POLICY_DOCUMENT_JSON} | python -m json.tool

# ポリシーの作成
aws iam create-policy \
    --policy-name ${PIPELINE_IAM_POLICY_NAME} \
    --path ${IAM_PATH} \
    --policy-document "${POLICY_DOCUMENT_JSON}"

# ARN取得
PIPELINE_IAM_POLICY_ARN=$(
    aws iam list-policies \
        --query "Policies[?PolicyName=='${PIPELINE_IAM_POLICY_NAME}'].Arn" \
        --output text
) \
&& echo ${PIPELINE_IAM_POLICY_ARN}

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # IAMポリシー
[cloudshell-user@ip-10-132-76-170 ~]$ POLICY_DOCUMENT_JSON=$(cat << EOF
> {
>     "Statement": [
>         {
>             "Action": [
>                 "iam:PassRole"
>             ],
>             "Resource": "*",
>             "Effect": "Allow",
>             "Condition": {
>                 "StringEqualsIfExists": {
>                     "iam:PassedToService": [
>                         "cloudformation.amazonaws.com",
>                         "elasticbeanstalk.amazonaws.com",
>                         "ec2.amazonaws.com",
>                         "ecs-tasks.amazonaws.com"
>                     ]
>                 }
>             }
>         },
>         {
>             "Action": [
>                 "codecommit:CancelUploadArchive",
>                 "codecommit:GetBranch",
>                 "codecommit:GetCommit",
>                 "codecommit:GetRepository",
>                 "codecommit:GetUploadArchiveStatus",
>                 "codecommit:UploadArchive"
>             ],
>             "Resource": "*",
>             "Effect": "Allow"
>         },
>         {
>             "Action": [
>                 "codedeploy:CreateDeployment",
>                 "codedeploy:GetApplication",
>                 "codedeploy:GetApplicationRevision",
>                 "codedeploy:GetDeployment",
>                 "codedeploy:GetDeploymentConfig",
>                 "codedeploy:RegisterApplicationRevision"
>             ],
>             "Resource": "*",
>             "Effect": "Allow"
>         },
>         {
>             "Action": [
>                 "codestar-connections:UseConnection"
>             ],
>             "Resource": "*",
>             "Effect": "Allow"
>         },
>         {
>             "Action": [
>                 "elasticbeanstalk:*",
>                 "ec2:*",
>                 "elasticloadbalancing:*",
>                 "autoscaling:*",
>                 "cloudwatch:*",
>                 "s3:*",
>                 "sns:*",
>                 "cloudformation:*",
>                 "rds:*",
>                 "sqs:*",
>                 "ecs:*"
>             ],
>             "Resource": "*",
>             "Effect": "Allow"
>         },
>         {
>             "Action": [
>                 "lambda:InvokeFunction",
>                 "lambda:ListFunctions"
>             ],
>             "Resource": "*",
>             "Effect": "Allow"
>         },
>         {
>             "Action": [
>                 "opsworks:CreateDeployment",
>                 "opsworks:DescribeApps",
>                 "opsworks:DescribeCommands",
>                 "opsworks:DescribeDeployments",
>                 "opsworks:DescribeInstances",
>                 "opsworks:DescribeStacks",
>                 "opsworks:UpdateApp",
>                 "opsworks:UpdateStack"
>             ],
>             "Resource": "*",
>             "Effect": "Allow"
>         },
>         {
>             "Action": [
>                 "cloudformation:CreateStack",
>                 "cloudformation:DeleteStack",
>                 "cloudformation:DescribeStacks",
>                 "cloudformation:UpdateStack",
>                 "cloudformation:CreateChangeSet",
>                 "cloudformation:DeleteChangeSet",
>                 "cloudformation:DescribeChangeSet",
>                 "cloudformation:ExecuteChangeSet",
>                 "cloudformation:SetStackPolicy",
>                 "cloudformation:ValidateTemplate"
>             ],
>             "Resource": "*",
>             "Effect": "Allow"
>         },
>         {
>             "Action": [
>                 "codebuild:BatchGetBuilds",
>                 "codebuild:StartBuild",
>                 "codebuild:BatchGetBuildBatches",
>                 "codebuild:StartBuildBatch"
>             ],
>             "Resource": "*",
>             "Effect": "Allow"
>         },
>         {
>             "Effect": "Allow",
>             "Action": [
>                 "devicefarm:ListProjects",
>                 "devicefarm:ListDevicePools",
>                 "devicefarm:GetRun",
>                 "devicefarm:GetUpload",
>                 "devicefarm:CreateUpload",
>                 "devicefarm:ScheduleRun"
>             ],
>             "Resource": "*"
>         },
>         {
>             "Effect": "Allow",
>             "Action": [
>                 "servicecatalog:ListProvisioningArtifacts",
>                 "servicecatalog:CreateProvisioningArtifact",
>                 "servicecatalog:DescribeProvisioningArtifact",
>                 "servicecatalog:DeleteProvisioningArtifact",
>                 "servicecatalog:UpdateProduct"
>             ],
>             "Resource": "*"
>         },
>         {
>             "Effect": "Allow",
>             "Action": [
>                 "cloudformation:ValidateTemplate"
>             ],
>             "Resource": "*"
>         },
>         {
>             "Effect": "Allow",
>             "Action": [
>                 "ecr:DescribeImages"
>             ],
>             "Resource": "*"
>         },
>         {
>             "Effect": "Allow",
>             "Action": [
>                 "states:DescribeExecution",
>                 "states:DescribeStateMachine",
>                 "states:StartExecution"
>             ],
>             "Resource": "*"
>         },
>         {
>             "Effect": "Allow",
>             "Action": [
>                 "appconfig:StartDeployment",
>                 "appconfig:StopDeployment",
>                 "appconfig:GetDeployment"
>             ],
>             "Resource": "*"
>         }
>     ],
>     "Version": "2012-10-17"
> }
> EOF
> ) \
> && echo ${POLICY_DOCUMENT_JSON}
{ "Statement": [ { "Action": [ "iam:PassRole" ], "Resource": "*", "Effect": "Allow", "Condition": { "StringEqualsIfExists": { "iam:PassedToService": [ "cloudformation.amazonaws.com", "elasticbeanstalk.amazonaws.com", "ec2.amazonaws.com", "ecs-tasks.amazonaws.com" ] } } }, { "Action": [ "codecommit:CancelUploadArchive", "codecommit:GetBranch", "codecommit:GetCommit", "codecommit:GetRepository", "codecommit:GetUploadArchiveStatus", "codecommit:UploadArchive" ], "Resource": "*", "Effect": "Allow" }, { "Action": [ "codedeploy:CreateDeployment", "codedeploy:GetApplication", "codedeploy:GetApplicationRevision", "codedeploy:GetDeployment", "codedeploy:GetDeploymentConfig", "codedeploy:RegisterApplicationRevision" ], "Resource": "*", "Effect": "Allow" }, { "Action": [ "codestar-connections:UseConnection" ], "Resource": "*", "Effect": "Allow" }, { "Action": [ "elasticbeanstalk:*", "ec2:*", "elasticloadbalancing:*", "autoscaling:*", "cloudwatch:*", "s3:*", "sns:*", "cloudformation:*", "rds:*", "sqs:*", "ecs:*" ], "Resource": "*", "Effect": "Allow" }, { "Action": [ "lambda:InvokeFunction", "lambda:ListFunctions" ], "Resource": "*", "Effect": "Allow" }, { "Action": [ "opsworks:CreateDeployment", "opsworks:DescribeApps", "opsworks:DescribeCommands", "opsworks:DescribeDeployments", "opsworks:DescribeInstances", "opsworks:DescribeStacks", "opsworks:UpdateApp", "opsworks:UpdateStack" ], "Resource": "*", "Effect": "Allow" }, { "Action": [ "cloudformation:CreateStack", "cloudformation:DeleteStack", "cloudformation:DescribeStacks", "cloudformation:UpdateStack", "cloudformation:CreateChangeSet", "cloudformation:DeleteChangeSet", "cloudformation:DescribeChangeSet", "cloudformation:ExecuteChangeSet", "cloudformation:SetStackPolicy", "cloudformation:ValidateTemplate" ], "Resource": "*", "Effect": "Allow" }, { "Action": [ "codebuild:BatchGetBuilds", "codebuild:StartBuild", "codebuild:BatchGetBuildBatches", "codebuild:StartBuildBatch" ], "Resource": "*", "Effect": "Allow" }, { "Effect": "Allow", "Action": [ "devicefarm:ListProjects", "devicefarm:ListDevicePools", "devicefarm:GetRun", "devicefarm:GetUpload", "devicefarm:CreateUpload", "devicefarm:ScheduleRun" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "servicecatalog:ListProvisioningArtifacts", "servicecatalog:CreateProvisioningArtifact", "servicecatalog:DescribeProvisioningArtifact", "servicecatalog:DeleteProvisioningArtifact", "servicecatalog:UpdateProduct" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "cloudformation:ValidateTemplate" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "ecr:DescribeImages" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "states:DescribeExecution", "states:DescribeStateMachine", "states:StartExecution" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "appconfig:StartDeployment", "appconfig:StopDeployment", "appconfig:GetDeployment" ], "Resource": "*" } ], "Version": "2012-10-17" }
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-132-76-170 ~]$ echo ${POLICY_DOCUMENT_JSON} | python -m json.tool
{
    "Statement": [
        {
            "Action": [
                "iam:PassRole"
            ],
            "Resource": "*",
            "Effect": "Allow",
            "Condition": {
                "StringEqualsIfExists": {
                    "iam:PassedToService": [
                        "cloudformation.amazonaws.com",
                        "elasticbeanstalk.amazonaws.com",
                        "ec2.amazonaws.com",
                        "ecs-tasks.amazonaws.com"
                    ]
                }
            }
        },
        {
            "Action": [
                "codecommit:CancelUploadArchive",
                "codecommit:GetBranch",
                "codecommit:GetCommit",
                "codecommit:GetRepository",
                "codecommit:GetUploadArchiveStatus",
                "codecommit:UploadArchive"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "codedeploy:CreateDeployment",
                "codedeploy:GetApplication",
                "codedeploy:GetApplicationRevision",
                "codedeploy:GetDeployment",
                "codedeploy:GetDeploymentConfig",
                "codedeploy:RegisterApplicationRevision"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "codestar-connections:UseConnection"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "elasticbeanstalk:*",
                "ec2:*",
                "elasticloadbalancing:*",
                "autoscaling:*",
                "cloudwatch:*",
                "s3:*",
                "sns:*",
                "cloudformation:*",
                "rds:*",
                "sqs:*",
                "ecs:*"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "lambda:InvokeFunction",
                "lambda:ListFunctions"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "opsworks:CreateDeployment",
                "opsworks:DescribeApps",
                "opsworks:DescribeCommands",
                "opsworks:DescribeDeployments",
                "opsworks:DescribeInstances",
                "opsworks:DescribeStacks",
                "opsworks:UpdateApp",
                "opsworks:UpdateStack"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "cloudformation:CreateStack",
                "cloudformation:DeleteStack",
                "cloudformation:DescribeStacks",
                "cloudformation:UpdateStack",
                "cloudformation:CreateChangeSet",
                "cloudformation:DeleteChangeSet",
                "cloudformation:DescribeChangeSet",
                "cloudformation:ExecuteChangeSet",
                "cloudformation:SetStackPolicy",
                "cloudformation:ValidateTemplate"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "codebuild:BatchGetBuilds",
                "codebuild:StartBuild",
                "codebuild:BatchGetBuildBatches",
                "codebuild:StartBuildBatch"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Effect": "Allow",
            "Action": [
                "devicefarm:ListProjects",
                "devicefarm:ListDevicePools",
                "devicefarm:GetRun",
                "devicefarm:GetUpload",
                "devicefarm:CreateUpload",
                "devicefarm:ScheduleRun"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "servicecatalog:ListProvisioningArtifacts",
                "servicecatalog:CreateProvisioningArtifact",
                "servicecatalog:DescribeProvisioningArtifact",
                "servicecatalog:DeleteProvisioningArtifact",
                "servicecatalog:UpdateProduct"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "cloudformation:ValidateTemplate"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "ecr:DescribeImages"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "states:DescribeExecution",
                "states:DescribeStateMachine",
                "states:StartExecution"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "appconfig:StartDeployment",
                "appconfig:StopDeployment",
                "appconfig:GetDeployment"
            ],
            "Resource": "*"
        }
    ],
    "Version": "2012-10-17"
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # ポリシーの作成
[cloudshell-user@ip-10-132-76-170 ~]$ aws iam create-policy \
>     --policy-name ${PIPELINE_IAM_POLICY_NAME} \
>     --path ${IAM_PATH} \
>     --policy-document "${POLICY_DOCUMENT_JSON}"
{
    "Policy": {
        "PolicyName": "AWSCodePipelineServiceRole-ap-northeast-1",
        "PolicyId": "ANPAWFKRCMKOYJIXRZWZM",
        "Arn": "arn:aws:iam::999999999999:policy/service-role/AWSCodePipelineServiceRole-ap-northeast-1",
        "Path": "/service-role/",
        "DefaultVersionId": "v1",
        "AttachmentCount": 0,
        "PermissionsBoundaryUsageCount": 0,
        "IsAttachable": true,
        "CreateDate": "2024-09-14T06:18:27+00:00",
        "UpdateDate": "2024-09-14T06:18:27+00:00"
    }
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # ARN取得
[cloudshell-user@ip-10-132-76-170 ~]$ PIPELINE_IAM_POLICY_ARN=$(
>     aws iam list-policies \
>         --query "Policies[?PolicyName=='${PIPELINE_IAM_POLICY_NAME}'].Arn" \
>         --output text
> ) \
> && echo ${PIPELINE_IAM_POLICY_ARN}

IAMロール

コマンド
# 信頼関係ポリシードキュメントの作成
ASSUME_ROLE_POLICY_DOCUMENT=$(cat << EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "codepipeline.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
EOF
) \
&& echo ${ASSUME_ROLE_POLICY_DOCUMENT}

# JSONフォーマットの確認
echo ${ASSUME_ROLE_POLICY_DOCUMENT} | python -m json.tool

# IAMロールの作成
aws iam create-role \
    --path ${IAM_PATH} \
    --role-name ${PIPELINE_IAM_ROLE_NAME} \
    --assume-role-policy-document "${ASSUME_ROLE_POLICY_DOCUMENT}"

# ARN取得
PIPELINE_IAM_ROLE_ARN=$(
    aws iam get-role \
        --role-name ${PIPELINE_IAM_ROLE_NAME} \
        --query 'Role.Arn' \
        --output text
) \
&& echo ${PIPELINE_IAM_ROLE_ARN}

# IAMロールにポリシーをアタッチ
aws iam attach-role-policy \
    --role-name ${PIPELINE_IAM_ROLE_NAME} \
    --policy-arn ${PIPELINE_IAM_POLICY_ARN}

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # 信頼関係ポリシードキュメントの作成
[cloudshell-user@ip-10-132-76-170 ~]$ ASSUME_ROLE_POLICY_DOCUMENT=$(cat << EOF
> {
>     "Version": "2012-10-17",
>     "Statement": [
>         {
>             "Effect": "Allow",
>             "Principal": {
>                 "Service": "codepipeline.amazonaws.com"
>             },
>             "Action": "sts:AssumeRole"
>         }
>     ]
> }
> EOF
> ) \
> && echo ${ASSUME_ROLE_POLICY_DOCUMENT}
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "codepipeline.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-132-76-170 ~]$ echo ${ASSUME_ROLE_POLICY_DOCUMENT} | python -m json.tool
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "codepipeline.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # IAMロールの作成
[cloudshell-user@ip-10-132-76-170 ~]$ aws iam create-role \
>     --path ${IAM_PATH} \
>     --role-name ${PIPELINE_IAM_ROLE_NAME} \
>     --assume-role-policy-document "${ASSUME_ROLE_POLICY_DOCUMENT}"
{
    "Role": {
        "Path": "/service-role/",
        "RoleName": "AWSCodePipelineServiceRole-ap-northeast-1",
        "RoleId": "AROAWFKRCMKOS5HCI6B76",
        "Arn": "arn:aws:iam::999999999999:role/service-role/AWSCodePipelineServiceRole-ap-northeast-1",
        "CreateDate": "2024-09-14T06:19:04+00:00",
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Effect": "Allow",
                    "Principal": {
                        "Service": "codepipeline.amazonaws.com"
                    },
                    "Action": "sts:AssumeRole"
                }
            ]
        }
    }
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # ARN取得
[cloudshell-user@ip-10-132-76-170 ~]$ PIPELINE_IAM_ROLE_ARN=$(
>     aws iam get-role \
>         --role-name ${PIPELINE_IAM_ROLE_NAME} \
>         --query 'Role.Arn' \
>         --output text
> ) \
> && echo ${PIPELINE_IAM_ROLE_ARN}
arn:aws:iam::999999999999:role/service-role/AWSCodePipelineServiceRole-ap-northeast-1
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # IAMロールにポリシーをアタッチ
[cloudshell-user@ip-10-132-76-170 ~]$ aws iam attach-role-policy \
>     --role-name ${PIPELINE_IAM_ROLE_NAME} \
>     --policy-arn ${PIPELINE_IAM_POLICY_ARN}

アーティファクト用 S3バケット

コマンド
# アーティファクト用のS3バケット名
ARTIFACTSTORE_BUCKET_NAME="codepipeline-${REGION}-artifactstore-`date +%Y%m%d`" \
&& echo ${ARTIFACTSTORE_BUCKET_NAME}

# アーティファクト用のS3バケット作成
aws s3api create-bucket \
    --bucket ${ARTIFACTSTORE_BUCKET_NAME} \
    --create-bucket-configuration LocationConstraint=${REGION}
    
# アーティファクト用のS3バケットポリシー(JSON)
ARTIFACTSTORE_BACKET_POLICY=$(cat << EOF
{
    "Version": "2012-10-17",
    "Id": "SSEAndSSLPolicy",
    "Statement": [
        {
            "Sid": "DenyUnEncryptedObjectUploads",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::${ARTIFACTSTORE_BUCKET_NAME}/*",
            "Condition": {
                "StringNotEquals": {
                    "s3:x-amz-server-side-encryption": "aws:kms"
                }
            }
        },
        {
            "Sid": "DenyInsecureConnections",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::${ARTIFACTSTORE_BUCKET_NAME}/*",
            "Condition": {
                "Bool": {
                    "aws:SecureTransport": "false"
                }
            }
        }
    ]
}
EOF
) \
&& echo ${ARTIFACTSTORE_BACKET_POLICY}

# JSONフォーマットの確認
echo ${ARTIFACTSTORE_BACKET_POLICY} | python -m json.tool

# バケットポリシー
aws s3api put-bucket-policy \
    --bucket ${ARTIFACTSTORE_BUCKET_NAME} \
    --policy "${ARTIFACTSTORE_BACKET_POLICY}"

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # アーティファクト用のS3バケット名
[cloudshell-user@ip-10-132-76-170 ~]$ ARTIFACTSTORE_BUCKET_NAME="codepipeline-${REGION}-artifactstore-`date +%Y%m%d`" \
> && echo ${ARTIFACTSTORE_BUCKET_NAME}
codepipeline-ap-northeast-1-artifactstore-20240914
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # アーティファクト用のS3バケット作成
[cloudshell-user@ip-10-132-76-170 ~]$ aws s3api create-bucket \
>     --bucket ${ARTIFACTSTORE_BUCKET_NAME} \
>     --create-bucket-configuration LocationConstraint=${REGION}
{
    "Location": "http://codepipeline-ap-northeast-1-artifactstore-20240914.s3.amazonaws.com/"
}
[cloudshell-user@ip-10-132-76-170 ~]$     
[cloudshell-user@ip-10-132-76-170 ~]$ # アーティファクト用のS3バケットポリシー(JSON)
[cloudshell-user@ip-10-132-76-170 ~]$ ARTIFACTSTORE_BACKET_POLICY=$(cat << EOF
> {
>     "Version": "2012-10-17",
>     "Id": "SSEAndSSLPolicy",
>     "Statement": [
>         {
>             "Sid": "DenyUnEncryptedObjectUploads",
>             "Effect": "Deny",
>             "Principal": "*",
>             "Action": "s3:PutObject",
>             "Resource": "arn:aws:s3:::${ARTIFACTSTORE_BUCKET_NAME}/*",
>             "Condition": {
>                 "StringNotEquals": {
>                     "s3:x-amz-server-side-encryption": "aws:kms"
>                 }
>             }
>         },
>         {
>             "Sid": "DenyInsecureConnections",
>             "Effect": "Deny",
>             "Principal": "*",
>             "Action": "s3:*",
>             "Resource": "arn:aws:s3:::${ARTIFACTSTORE_BUCKET_NAME}/*",
>             "Condition": {
>                 "Bool": {
>                     "aws:SecureTransport": "false"
>                 }
>             }
>         }
>     ]
> }
> EOF
> ) \
> && echo ${ARTIFACTSTORE_BACKET_POLICY}
{ "Version": "2012-10-17", "Id": "SSEAndSSLPolicy", "Statement": [ { "Sid": "DenyUnEncryptedObjectUploads", "Effect": "Deny", "Principal": "*", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::codepipeline-ap-northeast-1-artifactstore-20240914/*", "Condition": { "StringNotEquals": { "s3:x-amz-server-side-encryption": "aws:kms" } } }, { "Sid": "DenyInsecureConnections", "Effect": "Deny", "Principal": "*", "Action": "s3:*", "Resource": "arn:aws:s3:::codepipeline-ap-northeast-1-artifactstore-20240914/*", "Condition": { "Bool": { "aws:SecureTransport": "false" } } } ] }
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-132-76-170 ~]$ echo ${ARTIFACTSTORE_BACKET_POLICY} | python -m json.tool
{
    "Version": "2012-10-17",
    "Id": "SSEAndSSLPolicy",
    "Statement": [
        {
            "Sid": "DenyUnEncryptedObjectUploads",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::codepipeline-ap-northeast-1-artifactstore-20240914/*",
            "Condition": {
                "StringNotEquals": {
                    "s3:x-amz-server-side-encryption": "aws:kms"
                }
            }
        },
        {
            "Sid": "DenyInsecureConnections",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::codepipeline-ap-northeast-1-artifactstore-20240914/*",
            "Condition": {
                "Bool": {
                    "aws:SecureTransport": "false"
                }
            }
        }
    ]
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # バケットポリシー
[cloudshell-user@ip-10-132-76-170 ~]$ aws s3api put-bucket-policy \
>     --bucket ${ARTIFACTSTORE_BUCKET_NAME} \
>     --policy "${ARTIFACTSTORE_BACKET_POLICY}"

パイプライン定義ファイル

コマンド
# パイプライン定義ファイル
PIPELINE_JSON=$(cat << EOF
{
    "pipeline": {
        "name": "${PIPELINE_NAME}",
        "roleArn": "${PIPELINE_IAM_ROLE_ARN}",
        "artifactStore": {
            "type": "S3",
            "location": "${ARTIFACTSTORE_BUCKET_NAME}"
        },
        "stages": [
            {
                "name": "Source",
                "actions": [
                    {
                        "name": "Source",
                        "actionTypeId": {
                            "category": "Source",
                            "owner": "AWS",
                            "provider": "CodeCommit",
                            "version": "1"
                        },
                        "runOrder": 1,
                        "configuration": {
                            "BranchName": "master",
                            "OutputArtifactFormat": "CODE_ZIP",
                            "PollForSourceChanges": "false",
                            "RepositoryName": "${REPOSITORY_NAME}"
                        },
                        "outputArtifacts": [
                            {
                                "name": "SourceArtifact"
                            }
                        ],
                        "inputArtifacts": [],
                        "region": "ap-northeast-1",
                        "namespace": "SourceVariables"
                    }
                ]
            },
            {
                "name": "Deploy",
                "actions": [
                    {
                        "name": "Deploy",
                        "actionTypeId": {
                            "category": "Deploy",
                            "owner": "AWS",
                            "provider": "S3",
                            "version": "1"
                        },
                        "runOrder": 1,
                        "configuration": {
                            "BucketName": "${S3_BUCKET_NAME}",
                            "Extract": "true"
                        },
                        "inputArtifacts": [
                            {
                                "name": "SourceArtifact"
                            }
                        ],
                        "region": "ap-northeast-1",
                        "namespace": "DeployVariables"
                    }
                ]
            }
        ],
        "version": 1,
        "executionMode": "QUEUED",
        "pipelineType": "V2"
    }
}
EOF
) \
&& echo ${PIPELINE_JSON}

# JSONフォーマットの確認
echo ${PIPELINE_JSON} | python -m json.tool

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # パイプライン定義ファイル
[cloudshell-user@ip-10-132-76-170 ~]$ PIPELINE_JSON=$(cat << EOF
> {
>     "pipeline": {
>         "name": "${PIPELINE_NAME}",
>         "roleArn": "${PIPELINE_IAM_ROLE_ARN}",
>         "artifactStore": {
>             "type": "S3",
>             "location": "${ARTIFACTSTORE_BUCKET_NAME}"
>         },
>         "stages": [
>             {
>                 "name": "Source",
>                 "actions": [
>                     {
>                         "name": "Source",
>                         "actionTypeId": {
>                             "category": "Source",
>                             "owner": "AWS",
>                             "provider": "CodeCommit",
>                             "version": "1"
>                         },
>                         "runOrder": 1,
>                         "configuration": {
>                             "BranchName": "master",
>                             "OutputArtifactFormat": "CODE_ZIP",
>                             "PollForSourceChanges": "false",
>                             "RepositoryName": "${REPOSITORY_NAME}"
>                         },
>                         "outputArtifacts": [
>                             {
>                                 "name": "SourceArtifact"
>                             }
>                         ],
>                         "inputArtifacts": [],
>                         "region": "ap-northeast-1",
>                         "namespace": "SourceVariables"
>                     }
>                 ]
>             },
>             {
>                 "name": "Deploy",
>                 "actions": [
>                     {
>                         "name": "Deploy",
>                         "actionTypeId": {
>                             "category": "Deploy",
>                             "owner": "AWS",
>                             "provider": "S3",
>                             "version": "1"
>                         },
>                         "runOrder": 1,
>                         "configuration": {
>                             "BucketName": "${S3_BUCKET_NAME}",
>                             "Extract": "true"
>                         },
>                         "inputArtifacts": [
>                             {
>                                 "name": "SourceArtifact"
>                             }
>                         ],
>                         "region": "ap-northeast-1",
>                         "namespace": "DeployVariables"
>                     }
>                 ]
>             }
>         ],
>         "version": 1,
>         "executionMode": "QUEUED",
>         "pipelineType": "V2"
>     }
> }
> EOF
> ) \
> && echo ${PIPELINE_JSON}
{ "pipeline": { "name": "h4b-hands-on-s3", "roleArn": "arn:aws:iam::999999999999:role/service-role/AWSCodePipelineServiceRole-ap-northeast-1", "artifactStore": { "type": "S3", "location": "codepipeline-ap-northeast-1-artifactstore-20240914" }, "stages": [ { "name": "Source", "actions": [ { "name": "Source", "actionTypeId": { "category": "Source", "owner": "AWS", "provider": "CodeCommit", "version": "1" }, "runOrder": 1, "configuration": { "BranchName": "master", "OutputArtifactFormat": "CODE_ZIP", "PollForSourceChanges": "false", "RepositoryName": "h4b-hands-on" }, "outputArtifacts": [ { "name": "SourceArtifact" } ], "inputArtifacts": [], "region": "ap-northeast-1", "namespace": "SourceVariables" } ] }, { "name": "Deploy", "actions": [ { "name": "Deploy", "actionTypeId": { "category": "Deploy", "owner": "AWS", "provider": "S3", "version": "1" }, "runOrder": 1, "configuration": { "BucketName": "h4b-handson-20240914-bucket", "Extract": "true" }, "inputArtifacts": [ { "name": "SourceArtifact" } ], "region": "ap-northeast-1", "namespace": "DeployVariables" } ] } ], "version": 1, "executionMode": "QUEUED", "pipelineType": "V2" } }
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-132-76-170 ~]$ echo ${PIPELINE_JSON} | python -m json.tool
{
    "pipeline": {
        "name": "h4b-hands-on-s3",
        "roleArn": "arn:aws:iam::999999999999:role/service-role/AWSCodePipelineServiceRole-ap-northeast-1",
        "artifactStore": {
            "type": "S3",
            "location": "codepipeline-ap-northeast-1-artifactstore-20240914"
        },
        "stages": [
            {
                "name": "Source",
                "actions": [
                    {
                        "name": "Source",
                        "actionTypeId": {
                            "category": "Source",
                            "owner": "AWS",
                            "provider": "CodeCommit",
                            "version": "1"
                        },
                        "runOrder": 1,
                        "configuration": {
                            "BranchName": "master",
                            "OutputArtifactFormat": "CODE_ZIP",
                            "PollForSourceChanges": "false",
                            "RepositoryName": "h4b-hands-on"
                        },
                        "outputArtifacts": [
                            {
                                "name": "SourceArtifact"
                            }
                        ],
                        "inputArtifacts": [],
                        "region": "ap-northeast-1",
                        "namespace": "SourceVariables"
                    }
                ]
            },
            {
                "name": "Deploy",
                "actions": [
                    {
                        "name": "Deploy",
                        "actionTypeId": {
                            "category": "Deploy",
                            "owner": "AWS",
                            "provider": "S3",
                            "version": "1"
                        },
                        "runOrder": 1,
                        "configuration": {
                            "BucketName": "h4b-handson-20240914-bucket",
                            "Extract": "true"
                        },
                        "inputArtifacts": [
                            {
                                "name": "SourceArtifact"
                            }
                        ],
                        "region": "ap-northeast-1",
                        "namespace": "DeployVariables"
                    }
                ]
            }
        ],
        "version": 1,
        "executionMode": "QUEUED",
        "pipelineType": "V2"
    }
}

パイプラインの作成

コマンド
aws codepipeline create-pipeline \
    --cli-input-json "${PIPELINE_JSON}" \
    --no-cli-pager

# ARN取得
PIPELINE_ARN=$(
    aws codepipeline get-pipeline \
        --name ${PIPELINE_NAME} \
        --query metadata.pipelineArn \
        --output text
) \
&& echo ${PIPELINE_ARN}

出力
[cloudshell-user@ip-10-132-76-170 ~]$ aws codepipeline create-pipeline \
>     --cli-input-json "${PIPELINE_JSON}" \
>     --no-cli-pager
{
    "pipeline": {
        "name": "h4b-hands-on-s3",
        "roleArn": "arn:aws:iam::999999999999:role/service-role/AWSCodePipelineServiceRole-ap-northeast-1",
        "artifactStore": {
            "type": "S3",
            "location": "codepipeline-ap-northeast-1-artifactstore-20240914"
        },
        "stages": [
            {
                "name": "Source",
                "actions": [
                    {
                        "name": "Source",
                        "actionTypeId": {
                            "category": "Source",
                            "owner": "AWS",
                            "provider": "CodeCommit",
                            "version": "1"
                        },
                        "runOrder": 1,
                        "configuration": {
                            "BranchName": "master",
                            "OutputArtifactFormat": "CODE_ZIP",
                            "PollForSourceChanges": "false",
                            "RepositoryName": "h4b-hands-on"
                        },
                        "outputArtifacts": [
                            {
                                "name": "SourceArtifact"
                            }
                        ],
                        "inputArtifacts": [],
                        "region": "ap-northeast-1",
                        "namespace": "SourceVariables"
                    }
                ]
            },
            {
                "name": "Deploy",
                "actions": [
                    {
                        "name": "Deploy",
                        "actionTypeId": {
                            "category": "Deploy",
                            "owner": "AWS",
                            "provider": "S3",
                            "version": "1"
                        },
                        "runOrder": 1,
                        "configuration": {
                            "BucketName": "h4b-handson-20240914-bucket",
                            "Extract": "true"
                        },
                        "outputArtifacts": [],
                        "inputArtifacts": [
                            {
                                "name": "SourceArtifact"
                            }
                        ],
                        "region": "ap-northeast-1",
                        "namespace": "DeployVariables"
                    }
                ]
            }
        ],
        "version": 1,
        "executionMode": "QUEUED",
        "pipelineType": "V2"
    }
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # ARN取得
[cloudshell-user@ip-10-132-76-170 ~]$ PIPELINE_ARN=$(
>     aws codepipeline get-pipeline \
>         --name ${PIPELINE_NAME} \
>         --query metadata.pipelineArn \
>         --output text
> ) \
> && echo ${PIPELINE_ARN}
arn:aws:codepipeline:ap-northeast-1:999999999999:h4b-hands-on-s3

確認

コマンド
# 詳細確認
aws codepipeline get-pipeline \
    --name ${PIPELINE_NAME} \
    --no-cli-pager

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # 詳細確認
[cloudshell-user@ip-10-132-76-170 ~]$ aws codepipeline get-pipeline \
>     --name ${PIPELINE_NAME} \
>     --no-cli-pager
{
    "pipeline": {
        "name": "h4b-hands-on-s3",
        "roleArn": "arn:aws:iam::999999999999:role/service-role/AWSCodePipelineServiceRole-ap-northeast-1",
        "artifactStore": {
            "type": "S3",
            "location": "codepipeline-ap-northeast-1-artifactstore-20240914"
        },
        "stages": [
            {
                "name": "Source",
                "actions": [
                    {
                        "name": "Source",
                        "actionTypeId": {
                            "category": "Source",
                            "owner": "AWS",
                            "provider": "CodeCommit",
                            "version": "1"
                        },
                        "runOrder": 1,
                        "configuration": {
                            "BranchName": "master",
                            "OutputArtifactFormat": "CODE_ZIP",
                            "PollForSourceChanges": "false",
                            "RepositoryName": "h4b-hands-on"
                        },
                        "outputArtifacts": [
                            {
                                "name": "SourceArtifact"
                            }
                        ],
                        "inputArtifacts": [],
                        "region": "ap-northeast-1",
                        "namespace": "SourceVariables"
                    }
                ]
            },
            {
                "name": "Deploy",
                "actions": [
                    {
                        "name": "Deploy",
                        "actionTypeId": {
                            "category": "Deploy",
                            "owner": "AWS",
                            "provider": "S3",
                            "version": "1"
                        },
                        "runOrder": 1,
                        "configuration": {
                            "BucketName": "h4b-handson-20240914-bucket",
                            "Extract": "true"
                        },
                        "outputArtifacts": [],
                        "inputArtifacts": [
                            {
                                "name": "SourceArtifact"
                            }
                        ],
                        "region": "ap-northeast-1",
                        "namespace": "DeployVariables"
                    }
                ]
            }
        ],
        "version": 1,
        "executionMode": "QUEUED",
        "pipelineType": "V2"
    },
    "metadata": {
        "pipelineArn": "arn:aws:codepipeline:ap-northeast-1:999999999999:h4b-hands-on-s3",
        "created": "2024-09-14T06:20:28.718000+00:00",
        "updated": "2024-09-14T06:20:28.718000+00:00"
    }
}

EventBridge

AWS CLIでCodePipelineを作成する場合、EventBridgeを手動で作成する必要がある。管理コンソールでパイプラインを作成した場合は、EventBridgeは自動で作成される

IAM

コマンド
# ポリシー名
EVENT_IAM_POLICY_NAME="start-pipeline-execution-${REGION}-${PIPELINE_NAME}" \
&& echo ${EVENT_IAM_POLICY_NAME}

# ロール名
EVENT_IAM_ROLE_NAME="cwe-role-${REGION}-${PIPELINE_NAME}" \
&& echo ${EVENT_IAM_ROLE_NAME}

# IAMパス
IAM_PATH="/service-role/" \
&& echo ${IAM_PATH}

# IAMポリシー
POLICY_DOCUMENT_JSON=$(cat << EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "codepipeline:StartPipelineExecution"
            ],
            "Resource": [
                "${PIPELINE_ARN}"
            ]
        }
    ]
}
EOF
) \
&& echo ${POLICY_DOCUMENT_JSON}

# JSONフォーマットの確認
echo ${POLICY_DOCUMENT_JSON} | python -m json.tool

# ポリシーの作成
aws iam create-policy \
    --policy-name ${EVENT_IAM_POLICY_NAME} \
    --path ${IAM_PATH} \
    --policy-document "${POLICY_DOCUMENT_JSON}"

# ARN取得
EVENT_IAM_POLICY_ARN=$(
    aws iam list-policies \
        --query "Policies[?PolicyName=='${EVENT_IAM_POLICY_NAME}'].Arn" \
        --output text
) \
&& echo ${EVENT_IAM_POLICY_ARN}

# 信頼関係ポリシードキュメントの作成
ASSUME_ROLE_POLICY_DOCUMENT=$(cat << EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "events.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
EOF
) \
&& echo ${ASSUME_ROLE_POLICY_DOCUMENT}

# JSONフォーマットの確認
echo ${ASSUME_ROLE_POLICY_DOCUMENT} | python -m json.tool

# IAMロールの作成
aws iam create-role \
    --path ${IAM_PATH} \
    --role-name ${EVENT_IAM_ROLE_NAME} \
    --assume-role-policy-document "${ASSUME_ROLE_POLICY_DOCUMENT}"

# ARN取得
EVENT_IAM_ROLE_ARN=$(
    aws iam get-role \
        --role-name ${EVENT_IAM_ROLE_NAME} \
        --query 'Role.Arn' --output text
) \
&& echo ${EVENT_IAM_ROLE_ARN}

# IAMロールにポリシーをアタッチ
aws iam attach-role-policy \
    --role-name ${EVENT_IAM_ROLE_NAME} \
    --policy-arn ${EVENT_IAM_POLICY_ARN}

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # ポリシー名
[cloudshell-user@ip-10-132-76-170 ~]$ EVENT_IAM_POLICY_NAME="start-pipeline-execution-${REGION}-${PIPELINE_NAME}" \
> && echo ${EVENT_IAM_POLICY_NAME}
start-pipeline-execution-ap-northeast-1-h4b-hands-on-s3
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # ロール名
[cloudshell-user@ip-10-132-76-170 ~]$ EVENT_IAM_ROLE_NAME="cwe-role-${REGION}-${PIPELINE_NAME}" \
> && echo ${EVENT_IAM_ROLE_NAME}
cwe-role-ap-northeast-1-h4b-hands-on-s3
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # IAMパス
[cloudshell-user@ip-10-132-76-170 ~]$ IAM_PATH="/service-role/" \
> && echo ${IAM_PATH}
/service-role/
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # IAMポリシー
[cloudshell-user@ip-10-132-76-170 ~]$ POLICY_DOCUMENT_JSON=$(cat << EOF
> {
>     "Version": "2012-10-17",
>     "Statement": [
>         {
>             "Effect": "Allow",
>             "Action": [
>                 "codepipeline:StartPipelineExecution"
>             ],
>             "Resource": [
>                 "${PIPELINE_ARN}"
>             ]
>         }
>     ]
> }
> EOF
> ) \
> && echo ${POLICY_DOCUMENT_JSON}
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "codepipeline:StartPipelineExecution" ], "Resource": [ "arn:aws:codepipeline:ap-northeast-1:999999999999:h4b-hands-on-s3" ] } ] }
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-132-76-170 ~]$ echo ${POLICY_DOCUMENT_JSON} | python -m json.tool
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "codepipeline:StartPipelineExecution"
            ],
            "Resource": [
                "arn:aws:codepipeline:ap-northeast-1:999999999999:h4b-hands-on-s3"
            ]
        }
    ]
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # ポリシーの作成
[cloudshell-user@ip-10-132-76-170 ~]$ aws iam create-policy \
>     --policy-name ${EVENT_IAM_POLICY_NAME} \
>     --path ${IAM_PATH} \
>     --policy-document "${POLICY_DOCUMENT_JSON}"
{
    "Policy": {
        "PolicyName": "start-pipeline-execution-ap-northeast-1-h4b-hands-on-s3",
        "PolicyId": "ANPAWFKRCMKOTNWL4S6RT",
        "Arn": "arn:aws:iam::999999999999:policy/service-role/start-pipeline-execution-ap-northeast-1-h4b-hands-on-s3",
        "Path": "/service-role/",
        "DefaultVersionId": "v1",
        "AttachmentCount": 0,
        "PermissionsBoundaryUsageCount": 0,
        "IsAttachable": true,
        "CreateDate": "2024-09-14T06:21:18+00:00",
        "UpdateDate": "2024-09-14T06:21:18+00:00"
    }
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # ARN取得
[cloudshell-user@ip-10-132-76-170 ~]$ EVENT_IAM_POLICY_ARN=$(
>     aws iam list-policies \
>         --query "Policies[?PolicyName=='${EVENT_IAM_POLICY_NAME}'].Arn" \
>         --output text
> ) \
> && echo ${EVENT_IAM_POLICY_ARN}
arn:aws:iam::999999999999:policy/service-role/start-pipeline-execution-ap-northeast-1-h4b-hands-on-s3
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # 信頼関係ポリシードキュメントの作成
[cloudshell-user@ip-10-132-76-170 ~]$ ASSUME_ROLE_POLICY_DOCUMENT=$(cat << EOF
> {
>     "Version": "2012-10-17",
>     "Statement": [
>         {
>             "Effect": "Allow",
>             "Principal": {
>                 "Service": "events.amazonaws.com"
>             },
>             "Action": "sts:AssumeRole"
>         }
>     ]
> }
> EOF
> ) \
> && echo ${ASSUME_ROLE_POLICY_DOCUMENT}
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "events.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-132-76-170 ~]$ echo ${ASSUME_ROLE_POLICY_DOCUMENT} | python -m json.tool
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "events.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # IAMロールの作成
[cloudshell-user@ip-10-132-76-170 ~]$ aws iam create-role \
>     --path ${IAM_PATH} \
>     --role-name ${EVENT_IAM_ROLE_NAME} \
>     --assume-role-policy-document "${ASSUME_ROLE_POLICY_DOCUMENT}"
{
    "Role": {
        "Path": "/service-role/",
        "RoleName": "cwe-role-ap-northeast-1-h4b-hands-on-s3",
        "RoleId": "AROAWFKRCMKOSYKF4ZBCX",
        "Arn": "arn:aws:iam::999999999999:role/service-role/cwe-role-ap-northeast-1-h4b-hands-on-s3",
        "CreateDate": "2024-09-14T06:21:24+00:00",
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Effect": "Allow",
                    "Principal": {
                        "Service": "events.amazonaws.com"
                    },
                    "Action": "sts:AssumeRole"
                }
            ]
        }
    }
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # ARN取得
[cloudshell-user@ip-10-132-76-170 ~]$ EVENT_IAM_ROLE_ARN=$(
>     aws iam get-role \
>         --role-name ${EVENT_IAM_ROLE_NAME} \
>         --query 'Role.Arn' --output text
> ) \
> && echo ${EVENT_IAM_ROLE_ARN}
arn:aws:iam::999999999999:role/service-role/cwe-role-ap-northeast-1-h4b-hands-on-s3
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # IAMロールにポリシーをアタッチ
[cloudshell-user@ip-10-132-76-170 ~]$ aws iam attach-role-policy \
>     --role-name ${EVENT_IAM_ROLE_NAME} \
>     --policy-arn ${EVENT_IAM_POLICY_ARN}

イベントパターン

コマンド
# イベントパターンJSON
EVENT_PATTERN_JSON=$(cat << EOF
{
    "source": [
        "aws.codecommit"
    ],
    "detail-type": [
        "CodeCommit Repository State Change"
    ],
    "resources": [
        "${CODECOMMIT_ARN}"
    ],
    "detail": {
        "event": [
            "referenceCreated",
            "referenceUpdated"
        ],
        "referenceType": [
            "branch"
        ],
        "referenceName": [
            "master"
        ]
    }
}
EOF
) \
&& echo ${EVENT_PATTERN_JSON}

# JSONフォーマットの確認
echo ${EVENT_PATTERN_JSON} | python -m json.tool

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # イベントパターンJSON
[cloudshell-user@ip-10-132-76-170 ~]$ EVENT_PATTERN_JSON=$(cat << EOF
> {
>     "source": [
>         "aws.codecommit"
>     ],
>     "detail-type": [
>         "CodeCommit Repository State Change"
>     ],
>     "resources": [
>         "${CODECOMMIT_ARN}"
>     ],
>     "detail": {
>         "event": [
>             "referenceCreated",
>             "referenceUpdated"
>         ],
>         "referenceType": [
>             "branch"
>         ],
>         "referenceName": [
>             "master"
>         ]
>     }
> }
> EOF
> ) \
> && echo ${EVENT_PATTERN_JSON}
{ "source": [ "aws.codecommit" ], "detail-type": [ "CodeCommit Repository State Change" ], "resources": [ "arn:aws:codecommit:ap-northeast-1:999999999999:h4b-hands-on" ], "detail": { "event": [ "referenceCreated", "referenceUpdated" ], "referenceType": [ "branch" ], "referenceName": [ "master" ] } }
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-132-76-170 ~]$ echo ${EVENT_PATTERN_JSON} | python -m json.tool
{
    "source": [
        "aws.codecommit"
    ],
    "detail-type": [
        "CodeCommit Repository State Change"
    ],
    "resources": [
        "arn:aws:codecommit:ap-northeast-1:999999999999:h4b-hands-on"
    ],
    "detail": {
        "event": [
            "referenceCreated",
            "referenceUpdated"
        ],
        "referenceType": [
            "branch"
        ],
        "referenceName": [
            "master"
        ]
    }
}

作成

コマンド
# ルール名
EVENTS_RULE_NAME="codepipeline-${PIPELINE_NAME}-rule" \
&& echo ${EVENTS_RULE_NAME}

# ルール
aws events put-rule \
    --name "${EVENTS_RULE_NAME}" \
    --event-pattern "${EVENT_PATTERN_JSON}" \
    --role-arn "${EVENT_IAM_ROLE_ARN}"

# ターゲット
aws events put-targets \
    --rule ${EVENTS_RULE_NAME} \
    --targets Id="codepipeline-${PIPELINE_NAME}",Arn="${PIPELINE_ARN}",RoleArn="${EVENT_IAM_ROLE_ARN}"

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # ルール名
[cloudshell-user@ip-10-132-76-170 ~]$ EVENTS_RULE_NAME="codepipeline-${PIPELINE_NAME}-rule" \
> && echo ${EVENTS_RULE_NAME}
codepipeline-h4b-hands-on-s3-rule
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # ルール
[cloudshell-user@ip-10-132-76-170 ~]$ aws events put-rule \
>     --name "${EVENTS_RULE_NAME}" \
>     --event-pattern "${EVENT_PATTERN_JSON}" \
>     --role-arn "${EVENT_IAM_ROLE_ARN}"
{
    "RuleArn": "arn:aws:events:ap-northeast-1:999999999999:rule/codepipeline-h4b-hands-on-s3-rule"
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # ターゲット
[cloudshell-user@ip-10-132-76-170 ~]$ aws events put-targets \
>     --rule ${EVENTS_RULE_NAME} \
>     --targets Id="codepipeline-${PIPELINE_NAME}",Arn="${PIPELINE_ARN}",RoleArn="${EVENT_IAM_ROLE_ARN}"
{
    "FailedEntryCount": 0,
    "FailedEntries": []
}

確認

コマンド
# ルール確認
aws events describe-rule \
    --name ${EVENTS_RULE_NAME}

# ターゲット確認
aws events list-targets-by-rule \
    --rule ${EVENTS_RULE_NAME}

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # ルール確認
[cloudshell-user@ip-10-132-76-170 ~]$ aws events describe-rule \
>     --name ${EVENTS_RULE_NAME}
{
    "Name": "codepipeline-h4b-hands-on-s3-rule",
    "Arn": "arn:aws:events:ap-northeast-1:999999999999:rule/codepipeline-h4b-hands-on-s3-rule",
    "EventPattern": "{\n    \"source\": [\n        \"aws.codecommit\"\n    ],\n    \"detail-type\": [\n        \"CodeCommit Repository State Change\"\n    ],\n    \"resources\": [\n        \"arn:aws:codecommit:ap-northeast-1:999999999999:h4b-hands-on\"\n    ],\n    \"detail\": {\n        \"event\": [\n            \"referenceCreated\",\n            \"referenceUpdated\"\n        ],\n        \"referenceType\": [\n            \"branch\"\n        ],\n        \"referenceName\": [\n            \"master\"\n        ]\n    }\n}",
    "State": "ENABLED",
    "RoleArn": "arn:aws:iam::999999999999:role/service-role/cwe-role-ap-northeast-1-h4b-hands-on-s3",
    "EventBusName": "default",
    "CreatedBy": "999999999999"
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # ターゲット確認
[cloudshell-user@ip-10-132-76-170 ~]$ aws events list-targets-by-rule \
>     --rule ${EVENTS_RULE_NAME}
{
    "Targets": [
        {
            "Id": "codepipeline-h4b-hands-on-s3",
            "Arn": "arn:aws:codepipeline:ap-northeast-1:999999999999:h4b-hands-on-s3",
            "RoleArn": "arn:aws:iam::999999999999:role/service-role/cwe-role-ap-northeast-1-h4b-hands-on-s3"
        }
    ]
}

以降、Cloud9で実施

index.htmlの更新

コマンド
cat << EOF > index.html
<!DOCTYPE html>

<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>S3 Static Web Hosting</title>
</head>
<body>
  Hello, AWS Code* World!!
</body>
</html>
EOF

出力
admin:~/environment/h4b-hands-on (master) $ cat << EOF > index.html
> <!DOCTYPE html>
> 
> <html lang="ja">
> <head>
>   <meta charset="utf-8">
>   <title>S3 Static Web Hosting</title>
> </head>
> <body>
>   Hello, AWS Code* World!!
> </body>
> </html>
> EOF

リポジトリの更新

コマンド
git add -A
git commit -m "fix."
git push origin master

出力
admin:~/environment/h4b-hands-on (master) $ git add -A
admin:~/environment/h4b-hands-on (master) $ git commit -m "fix."
[master 8cb8648] fix.
 1 file changed, 1 insertion(+), 1 deletion(-)
admin:~/environment/h4b-hands-on (master) $ git push origin master
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 290 bytes | 290.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0), pack-reused 0
remote: Validating objects: 100%
To https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/h4b-hands-on
   1c189c5..8cb8648  master -> master

以降、CloudShellで実施

アクセス確認

コマンド
curl http://${S3_BUCKET_NAME}.s3-website-${REGION}.amazonaws.com

出力
[cloudshell-user@ip-10-132-76-170 ~]$ curl http://${S3_BUCKET_NAME}.s3-website-${REGION}.amazonaws.com
<!DOCTYPE html>

<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>S3 Static Web Hosting</title>
</head>
<body>
  Hello, AWS Code* World!!
</body>
</html>

04 EC2 インスタンスをデプロイ先とした、CI/CD 環境を構築する【事前準備編】

IAM

コマンド
# 変数
EC2_IAM_ROLE_NAME="EC2WebRole" \
&& echo ${EC2_IAM_ROLE_NAME}

# AWS管理ポリシー
AWS_POLICY_NAME="AmazonS3FullAccess" \
&& echo ${AWS_POLICY_NAME}

# 信頼関係ポリシードキュメントの作成
ASSUME_ROLE_POLICY_DOCUMENT=$(cat << EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "ec2.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
EOF
) \
&& echo ${ASSUME_ROLE_POLICY_DOCUMENT}

# JSONフォーマットの確認
echo ${ASSUME_ROLE_POLICY_DOCUMENT} | python -m json.tool

# IAMロールの作成
aws iam create-role \
    --role-name ${EC2_IAM_ROLE_NAME} \
    --assume-role-policy-document "${ASSUME_ROLE_POLICY_DOCUMENT}"

# ARN取得
EC2_IAM_ROLE_ARN=$(
    aws iam get-role \
        --role-name ${EC2_IAM_ROLE_NAME} \
        --query 'Role.Arn' --output text
) \
&& echo ${EC2_IAM_ROLE_ARN}

# IAMロールにポリシーをアタッチ
aws iam attach-role-policy \
    --role-name ${EC2_IAM_ROLE_NAME} \
    --policy-arn arn:aws:iam::aws:policy/${AWS_POLICY_NAME}

# インスタンスプロファイル作成
aws iam create-instance-profile \
    --instance-profile-name ${EC2_IAM_ROLE_NAME}

# インスタンスプロファイルへのロールのアタッチ
aws iam add-role-to-instance-profile \
    --instance-profile-name ${EC2_IAM_ROLE_NAME} \
    --role-name ${EC2_IAM_ROLE_NAME}

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # 変数
[cloudshell-user@ip-10-132-76-170 ~]$ EC2_IAM_ROLE_NAME="EC2WebRole" \
> && echo ${EC2_IAM_ROLE_NAME}
EC2WebRole
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # AWS管理ポリシー
[cloudshell-user@ip-10-132-76-170 ~]$ AWS_POLICY_NAME="AmazonS3FullAccess" \
> && echo ${AWS_POLICY_NAME}
AmazonS3FullAccess
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # 信頼関係ポリシードキュメントの作成
[cloudshell-user@ip-10-132-76-170 ~]$ ASSUME_ROLE_POLICY_DOCUMENT=$(cat << EOF
> {
>     "Version": "2012-10-17",
>     "Statement": [
>         {
>             "Effect": "Allow",
>             "Principal": {
>                 "Service": "ec2.amazonaws.com"
>             },
>             "Action": "sts:AssumeRole"
>         }
>     ]
> }
> EOF
> ) \
> && echo ${ASSUME_ROLE_POLICY_DOCUMENT}
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-132-76-170 ~]$ echo ${ASSUME_ROLE_POLICY_DOCUMENT} | python -m json.tool
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "ec2.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # IAMロールの作成
[cloudshell-user@ip-10-132-76-170 ~]$ aws iam create-role \
>     --role-name ${EC2_IAM_ROLE_NAME} \
>     --assume-role-policy-document "${ASSUME_ROLE_POLICY_DOCUMENT}"
{
    "Role": {
        "Path": "/",
        "RoleName": "EC2WebRole",
        "RoleId": "AROAWFKRCMKO43YOGO2AX",
        "Arn": "arn:aws:iam::999999999999:role/EC2WebRole",
        "CreateDate": "2024-09-14T06:24:26+00:00",
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Effect": "Allow",
                    "Principal": {
                        "Service": "ec2.amazonaws.com"
                    },
                    "Action": "sts:AssumeRole"
                }
            ]
        }
    }
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # ARN取得
[cloudshell-user@ip-10-132-76-170 ~]$ EC2_IAM_ROLE_ARN=$(
>     aws iam get-role \
>         --role-name ${EC2_IAM_ROLE_NAME} \
>         --query 'Role.Arn' --output text
> ) \
> && echo ${EC2_IAM_ROLE_ARN}
arn:aws:iam::999999999999:role/EC2WebRole
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # IAMロールにポリシーをアタッチ
[cloudshell-user@ip-10-132-76-170 ~]$ aws iam attach-role-policy \
>     --role-name ${EC2_IAM_ROLE_NAME} \
>     --policy-arn arn:aws:iam::aws:policy/${AWS_POLICY_NAME}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # インスタンスプロファイル作成
[cloudshell-user@ip-10-132-76-170 ~]$ aws iam create-instance-profile \
>     --instance-profile-name ${EC2_IAM_ROLE_NAME}
{
    "InstanceProfile": {
        "Path": "/",
        "InstanceProfileName": "EC2WebRole",
        "InstanceProfileId": "AIPAWFKRCMKO4WKPDIQTM",
        "Arn": "arn:aws:iam::999999999999:instance-profile/EC2WebRole",
        "CreateDate": "2024-09-14T06:24:32+00:00",
        "Roles": []
    }
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # インスタンスプロファイルへのロールのアタッチ
[cloudshell-user@ip-10-132-76-170 ~]$ aws iam add-role-to-instance-profile \
>     --instance-profile-name ${EC2_IAM_ROLE_NAME} \
>     --role-name ${EC2_IAM_ROLE_NAME}

EC2

セキュリティグループ

コマンド
# セキュリティグループ名
EC2_SG_NAME='h4b-handson-ec2' \
&& echo ${EC2_SG_NAME}

# セキュリティグループ説明
EC2_SG_DESC='h4b-handson-ec2' \
&& echo ${EC2_SG_DESC}

# デフォルトVPC ID取得
VPC_ID=$( \
  aws ec2 describe-vpcs \
    --region ap-northeast-1 \
    --filters Name=is-default,Values=true \
    --query 'Vpcs[].VpcId' \
    --output text
) \
&& echo ${VPC_ID}

# 作成
aws ec2 create-security-group \
    --group-name ${EC2_SG_NAME} \
    --description "${EC2_SG_DESC}" \
    --vpc-id ${VPC_ID}

# ID取得
EC2_SG_ID=$( \
    aws ec2 describe-security-groups \
        --filters Name=vpc-id,Values=${VPC_ID} \
                  Name=group-name,Values=${EC2_SG_NAME} \
        --query "SecurityGroups[].GroupId" \
        --output text
) \
&& echo ${EC2_SG_ID}

# ルール追加 (SSH)
aws ec2 authorize-security-group-ingress \
    --group-id ${EC2_SG_ID} \
    --protocol tcp \
    --port 22 \
    --cidr 0.0.0.0/0

# ルール追加 (HTTP)
aws ec2 authorize-security-group-ingress \
    --group-id ${EC2_SG_ID} \
    --protocol tcp \
    --port 80 \
    --cidr 0.0.0.0/0

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # セキュリティグループ名
[cloudshell-user@ip-10-132-76-170 ~]$ EC2_SG_NAME='h4b-handson-ec2' \
> && echo ${EC2_SG_NAME}
h4b-handson-ec2
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # セキュリティグループ説明
[cloudshell-user@ip-10-132-76-170 ~]$ EC2_SG_DESC='h4b-handson-ec2' \
> && echo ${EC2_SG_DESC}
h4b-handson-ec2
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # デフォルトVPC ID取得
[cloudshell-user@ip-10-132-76-170 ~]$ VPC_ID=$( \
>   aws ec2 describe-vpcs \
>     --region ap-northeast-1 \
>     --filters Name=is-default,Values=true \
>     --query 'Vpcs[].VpcId' \
>     --output text
> ) \
> && echo ${VPC_ID}
vpc-090c14ab4d18c8e0b
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # 作成
[cloudshell-user@ip-10-132-76-170 ~]$ aws ec2 create-security-group \
>     --group-name ${EC2_SG_NAME} \
>     --description "${EC2_SG_DESC}" \
>     --vpc-id ${VPC_ID}
{
    "GroupId": "sg-08f573a025db109f9"
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # ID取得
[cloudshell-user@ip-10-132-76-170 ~]$ EC2_SG_ID=$( \
>     aws ec2 describe-security-groups \
>         --filters Name=vpc-id,Values=${VPC_ID} \
>                   Name=group-name,Values=${EC2_SG_NAME} \
>         --query "SecurityGroups[].GroupId" \
>         --output text
> ) \
> && echo ${EC2_SG_ID}
sg-08f573a025db109f9
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # ルール追加 (SSH)
[cloudshell-user@ip-10-132-76-170 ~]$ aws ec2 authorize-security-group-ingress \
>     --group-id ${EC2_SG_ID} \
>     --protocol tcp \
>     --port 22 \
>     --cidr 0.0.0.0/0
{
    "Return": true,
    "SecurityGroupRules": [
        {
            "SecurityGroupRuleId": "sgr-0159dda818117c090",
            "GroupId": "sg-08f573a025db109f9",
            "GroupOwnerId": "999999999999",
            "IsEgress": false,
            "IpProtocol": "tcp",
            "FromPort": 22,
            "ToPort": 22,
            "CidrIpv4": "0.0.0.0/0"
        }
    ]
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # ルール追加 (HTTP)
[cloudshell-user@ip-10-132-76-170 ~]$ aws ec2 authorize-security-group-ingress \
>     --group-id ${EC2_SG_ID} \
>     --protocol tcp \
>     --port 80 \
>     --cidr 0.0.0.0/0
{
    "Return": true,
    "SecurityGroupRules": [
        {
            "SecurityGroupRuleId": "sgr-04a20a5b3d410a8aa",
            "GroupId": "sg-08f573a025db109f9",
            "GroupOwnerId": "999999999999",
            "IsEgress": false,
            "IpProtocol": "tcp",
            "FromPort": 80,
            "ToPort": 80,
            "CidrIpv4": "0.0.0.0/0"
        }
    ]
}

インスタンス

コマンド
# 名前
EC2_NAME="Web" \
&& echo ${EC2_NAME}

# インスタンスタイプ
EC2_INSTANCE_TYPE="t2.micro" \
&& echo ${EC2_INSTANCE_TYPE}

# Amazon マシンイメージ (AMI)
EC2_IMAGE_ID="resolve:ssm:/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2" \
&& echo ${EC2_IMAGE_ID}

# EC2インスタンス作成
aws ec2 run-instances \
    --image-id ${EC2_IMAGE_ID} \
    --security-group-ids ${EC2_SG_ID} \
    --instance-type ${EC2_INSTANCE_TYPE} \
    --iam-instance-profile Name=${EC2_IAM_ROLE_NAME} \
    --tag-specifications "ResourceType=instance,Tags=[{Key=Name,Value=${EC2_NAME}}]" \
    --no-cli-pager

# ID取得
EC2_INSTANCE_ID=$( \
    aws ec2 describe-instances \
        --filters Name=tag:Name,Values=${EC2_NAME}  \
        --query "Reservations[*].Instances[*].[InstanceId]" \
        --output text
) \
&& echo ${EC2_INSTANCE_ID} 

# パブリックIP確認
EC2_PUBLIC_IP=$(
    aws ec2 describe-instances \
        --instance-ids ${EC2_INSTANCE_ID} \
        --query "Reservations[*].Instances[*].PublicIpAddress" \
        --output text
) \
&& echo ${EC2_PUBLIC_IP}

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # 名前
[cloudshell-user@ip-10-132-76-170 ~]$ EC2_NAME="Web" \
> && echo ${EC2_NAME}
Web
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # インスタンスタイプ
[cloudshell-user@ip-10-132-76-170 ~]$ EC2_INSTANCE_TYPE="t2.micro" \
> && echo ${EC2_INSTANCE_TYPE}
t2.micro
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # Amazon マシンイメージ (AMI)
[cloudshell-user@ip-10-132-76-170 ~]$ EC2_IMAGE_ID="resolve:ssm:/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2" \
> && echo ${EC2_IMAGE_ID}
resolve:ssm:/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # EC2インスタンス作成
[cloudshell-user@ip-10-132-76-170 ~]$ aws ec2 run-instances \
>     --image-id ${EC2_IMAGE_ID} \
>     --security-group-ids ${EC2_SG_ID} \
>     --instance-type ${EC2_INSTANCE_TYPE} \
>     --iam-instance-profile Name=${EC2_IAM_ROLE_NAME} \
>     --tag-specifications "ResourceType=instance,Tags=[{Key=Name,Value=${EC2_NAME}}]" \
>     --no-cli-pager
{
    "Groups": [],
    "Instances": [
        {
            "AmiLaunchIndex": 0,
            "ImageId": "ami-06aa91d03bbe9eed7",
            "InstanceId": "i-02a25fbe53f00866b",
            "InstanceType": "t2.micro",
            "LaunchTime": "2024-09-14T06:27:00+00:00",
            "Monitoring": {
                "State": "disabled"
            },
            "Placement": {
                "AvailabilityZone": "ap-northeast-1a",
                "GroupName": "",
                "Tenancy": "default"
            },
            "PrivateDnsName": "ip-172-31-38-107.ap-northeast-1.compute.internal",
            "PrivateIpAddress": "172.31.38.107",
            "ProductCodes": [],
            "PublicDnsName": "",
            "State": {
                "Code": 0,
                "Name": "pending"
            },
            "StateTransitionReason": "",
            "SubnetId": "subnet-0e58505daeffcca69",
            "VpcId": "vpc-090c14ab4d18c8e0b",
            "Architecture": "x86_64",
            "BlockDeviceMappings": [],
            "ClientToken": "f0d2d312-4cab-4d3a-a1ac-fb19114b69d8",
            "EbsOptimized": false,
            "EnaSupport": true,
            "Hypervisor": "xen",
            "IamInstanceProfile": {
                "Arn": "arn:aws:iam::999999999999:instance-profile/EC2WebRole",
                "Id": "AIPAWFKRCMKO4WKPDIQTM"
            },
            "NetworkInterfaces": [
                {
                    "Attachment": {
                        "AttachTime": "2024-09-14T06:27:00+00:00",
                        "AttachmentId": "eni-attach-012f406cae9a111c3",
                        "DeleteOnTermination": true,
                        "DeviceIndex": 0,
                        "Status": "attaching",
                        "NetworkCardIndex": 0
                    },
                    "Description": "",
                    "Groups": [
                        {
                            "GroupName": "h4b-handson-ec2",
                            "GroupId": "sg-08f573a025db109f9"
                        }
                    ],
                    "Ipv6Addresses": [],
                    "MacAddress": "06:b8:da:b5:79:8b",
                    "NetworkInterfaceId": "eni-044acc18ae3c3a08c",
                    "OwnerId": "999999999999",
                    "PrivateDnsName": "ip-172-31-38-107.ap-northeast-1.compute.internal",
                    "PrivateIpAddress": "172.31.38.107",
                    "PrivateIpAddresses": [
                        {
                            "Primary": true,
                            "PrivateDnsName": "ip-172-31-38-107.ap-northeast-1.compute.internal",
                            "PrivateIpAddress": "172.31.38.107"
                        }
                    ],
                    "SourceDestCheck": true,
                    "Status": "in-use",
                    "SubnetId": "subnet-0e58505daeffcca69",
                    "VpcId": "vpc-090c14ab4d18c8e0b",
                    "InterfaceType": "interface"
                }
            ],
            "RootDeviceName": "/dev/xvda",
            "RootDeviceType": "ebs",
            "SecurityGroups": [
                {
                    "GroupName": "h4b-handson-ec2",
                    "GroupId": "sg-08f573a025db109f9"
                }
            ],
            "SourceDestCheck": true,
            "StateReason": {
                "Code": "pending",
                "Message": "pending"
            },
            "Tags": [
                {
                    "Key": "Name",
                    "Value": "Web"
                }
            ],
            "VirtualizationType": "hvm",
            "CpuOptions": {
                "CoreCount": 1,
                "ThreadsPerCore": 1
            },
            "CapacityReservationSpecification": {
                "CapacityReservationPreference": "open"
            },
            "MetadataOptions": {
                "State": "pending",
                "HttpTokens": "optional",
                "HttpPutResponseHopLimit": 1,
                "HttpEndpoint": "enabled",
                "HttpProtocolIpv6": "disabled",
                "InstanceMetadataTags": "disabled"
            },
            "EnclaveOptions": {
                "Enabled": false
            },
            "PrivateDnsNameOptions": {
                "HostnameType": "ip-name",
                "EnableResourceNameDnsARecord": false,
                "EnableResourceNameDnsAAAARecord": false
            },
            "MaintenanceOptions": {
                "AutoRecovery": "default"
            },
            "CurrentInstanceBootMode": "legacy-bios"
        }
    ],
    "OwnerId": "999999999999",
    "ReservationId": "r-0528cf4ab9536c07f"
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # ID取得
[cloudshell-user@ip-10-132-76-170 ~]$ EC2_INSTANCE_ID=$( \
>     aws ec2 describe-instances \
>         --filters Name=tag:Name,Values=${EC2_NAME}  \
>         --query "Reservations[*].Instances[*].[InstanceId]" \
>         --output text
> ) \
> && echo ${EC2_INSTANCE_ID} 
i-02a25fbe53f00866b
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # パブリックIP確認
[cloudshell-user@ip-10-132-76-170 ~]$ EC2_PUBLIC_IP=$(
>     aws ec2 describe-instances \
>         --instance-ids ${EC2_INSTANCE_ID} \
>         --query "Reservations[*].Instances[*].PublicIpAddress" \
>         --output text
> ) \
> && echo ${EC2_PUBLIC_IP}
13.113.212.231

EC2 Instance Connect を使用して接続

コマンド
aws ec2-instance-connect ssh --instance-id ${EC2_INSTANCE_ID}

出力
[cloudshell-user@ip-10-132-76-170 ~]$ aws ec2-instance-connect ssh --instance-id ${EC2_INSTANCE_ID}
The authenticity of host '13.113.212.231 (13.113.212.231)' can't be established.
ED25519 key fingerprint is SHA256:owWbRMWyGWhhNciF1C+XwTI7xfhS6Wn63NfRXT2dRXI.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '13.113.212.231' (ED25519) to the list of known hosts.
   ,     #_
   ~\_  ####_        Amazon Linux 2
  ~~  \_#####\
  ~~     \###|       AL2 End of Life is 2025-06-30.
  ~~       \#/ ___
   ~~       V~' '->
    ~~~         /    A newer version of Amazon Linux is available!
      ~~._.   _/
         _/ _/       Amazon Linux 2023, GA and supported until 2028-03-15.
       _/m/'           https://aws.amazon.com/linux/amazon-linux-2023/

[ec2-user@ip-172-31-38-107 ~]$ 

EC2初期設定

コマンド
sudo yum update -y
sudo yum install httpd -y
sudo systemctl start httpd.service
sudo systemctl enable httpd.service

出力
[ec2-user@ip-172-31-38-107 ~]$ sudo yum update -y
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
No packages marked for update
[ec2-user@ip-172-31-38-107 ~]$ sudo yum install httpd -y
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
Resolving Dependencies
--> Running transaction check
---> Package httpd.x86_64 0:2.4.62-1.amzn2.0.2 will be installed
--> Processing Dependency: httpd-filesystem = 2.4.62-1.amzn2.0.2 for package: httpd-2.4.62-1.amzn2.0.2.x86_64
--> Processing Dependency: httpd-tools = 2.4.62-1.amzn2.0.2 for package: httpd-2.4.62-1.amzn2.0.2.x86_64
--> Processing Dependency: /etc/mime.types for package: httpd-2.4.62-1.amzn2.0.2.x86_64
--> Processing Dependency: httpd-filesystem for package: httpd-2.4.62-1.amzn2.0.2.x86_64
--> Processing Dependency: mod_http2 for package: httpd-2.4.62-1.amzn2.0.2.x86_64
--> Processing Dependency: system-logos-httpd for package: httpd-2.4.62-1.amzn2.0.2.x86_64
--> Processing Dependency: libapr-1.so.0()(64bit) for package: httpd-2.4.62-1.amzn2.0.2.x86_64
--> Processing Dependency: libaprutil-1.so.0()(64bit) for package: httpd-2.4.62-1.amzn2.0.2.x86_64
--> Running transaction check
---> Package apr.x86_64 0:1.7.2-1.amzn2 will be installed
---> Package apr-util.x86_64 0:1.6.3-1.amzn2.0.1 will be installed
--> Processing Dependency: apr-util-bdb(x86-64) = 1.6.3-1.amzn2.0.1 for package: apr-util-1.6.3-1.amzn2.0.1.x86_64
---> Package generic-logos-httpd.noarch 0:18.0.0-4.amzn2 will be installed
---> Package httpd-filesystem.noarch 0:2.4.62-1.amzn2.0.2 will be installed
---> Package httpd-tools.x86_64 0:2.4.62-1.amzn2.0.2 will be installed
---> Package mailcap.noarch 0:2.1.41-2.amzn2 will be installed
---> Package mod_http2.x86_64 0:1.15.19-1.amzn2.0.2 will be installed
--> Running transaction check
---> Package apr-util-bdb.x86_64 0:1.6.3-1.amzn2.0.1 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

===========================================================================================================================================================================================================================================================================================
 Package                                                                   Arch                                                         Version                                                                     Repository                                                        Size
===========================================================================================================================================================================================================================================================================================
Installing:
 httpd                                                                     x86_64                                                       2.4.62-1.amzn2.0.2                                                          amzn2-core                                                       1.4 M
Installing for dependencies:
 apr                                                                       x86_64                                                       1.7.2-1.amzn2                                                               amzn2-core                                                       130 k
 apr-util                                                                  x86_64                                                       1.6.3-1.amzn2.0.1                                                           amzn2-core                                                       101 k
 apr-util-bdb                                                              x86_64                                                       1.6.3-1.amzn2.0.1                                                           amzn2-core                                                        22 k
 generic-logos-httpd                                                       noarch                                                       18.0.0-4.amzn2                                                              amzn2-core                                                        19 k
 httpd-filesystem                                                          noarch                                                       2.4.62-1.amzn2.0.2                                                          amzn2-core                                                        25 k
 httpd-tools                                                               x86_64                                                       2.4.62-1.amzn2.0.2                                                          amzn2-core                                                        89 k
 mailcap                                                                   noarch                                                       2.1.41-2.amzn2                                                              amzn2-core                                                        31 k
 mod_http2                                                                 x86_64                                                       1.15.19-1.amzn2.0.2                                                         amzn2-core                                                       149 k

Transaction Summary
===========================================================================================================================================================================================================================================================================================
Install  1 Package (+8 Dependent packages)

Total download size: 1.9 M
Installed size: 5.3 M
Downloading packages:
(1/9): apr-1.7.2-1.amzn2.x86_64.rpm                                                                                                                                                                                                                                 | 130 kB  00:00:00     
(2/9): apr-util-1.6.3-1.amzn2.0.1.x86_64.rpm                                                                                                                                                                                                                        | 101 kB  00:00:00     
(3/9): apr-util-bdb-1.6.3-1.amzn2.0.1.x86_64.rpm                                                                                                                                                                                                                    |  22 kB  00:00:00     
(4/9): generic-logos-httpd-18.0.0-4.amzn2.noarch.rpm                                                                                                                                                                                                                |  19 kB  00:00:00     
(5/9): httpd-filesystem-2.4.62-1.amzn2.0.2.noarch.rpm                                                                                                                                                                                                               |  25 kB  00:00:00     
(6/9): httpd-2.4.62-1.amzn2.0.2.x86_64.rpm                                                                                                                                                                                                                          | 1.4 MB  00:00:00     
(7/9): httpd-tools-2.4.62-1.amzn2.0.2.x86_64.rpm                                                                                                                                                                                                                    |  89 kB  00:00:00     
(8/9): mailcap-2.1.41-2.amzn2.noarch.rpm                                                                                                                                                                                                                            |  31 kB  00:00:00     
(9/9): mod_http2-1.15.19-1.amzn2.0.2.x86_64.rpm                                                                                                                                                                                                                     | 149 kB  00:00:00     
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Total                                                                                                                                                                                                                                                      8.5 MB/s | 1.9 MB  00:00:00     
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : apr-1.7.2-1.amzn2.x86_64                                                                                                                                                                                                                                                1/9 
  Installing : apr-util-1.6.3-1.amzn2.0.1.x86_64                                                                                                                                                                                                                                       2/9 
  Installing : apr-util-bdb-1.6.3-1.amzn2.0.1.x86_64                                                                                                                                                                                                                                   3/9 
  Installing : httpd-tools-2.4.62-1.amzn2.0.2.x86_64                                                                                                                                                                                                                                   4/9 
  Installing : httpd-filesystem-2.4.62-1.amzn2.0.2.noarch                                                                                                                                                                                                                              5/9 
  Installing : generic-logos-httpd-18.0.0-4.amzn2.noarch                                                                                                                                                                                                                               6/9 
  Installing : mailcap-2.1.41-2.amzn2.noarch                                                                                                                                                                                                                                           7/9 
  Installing : mod_http2-1.15.19-1.amzn2.0.2.x86_64                                                                                                                                                                                                                                    8/9 
  Installing : httpd-2.4.62-1.amzn2.0.2.x86_64                                                                                                                                                                                                                                         9/9 
  Verifying  : apr-util-bdb-1.6.3-1.amzn2.0.1.x86_64                                                                                                                                                                                                                                   1/9 
  Verifying  : httpd-2.4.62-1.amzn2.0.2.x86_64                                                                                                                                                                                                                                         2/9 
  Verifying  : apr-1.7.2-1.amzn2.x86_64                                                                                                                                                                                                                                                3/9 
  Verifying  : mod_http2-1.15.19-1.amzn2.0.2.x86_64                                                                                                                                                                                                                                    4/9 
  Verifying  : apr-util-1.6.3-1.amzn2.0.1.x86_64                                                                                                                                                                                                                                       5/9 
  Verifying  : mailcap-2.1.41-2.amzn2.noarch                                                                                                                                                                                                                                           6/9 
  Verifying  : generic-logos-httpd-18.0.0-4.amzn2.noarch                                                                                                                                                                                                                               7/9 
  Verifying  : httpd-tools-2.4.62-1.amzn2.0.2.x86_64                                                                                                                                                                                                                                   8/9 
  Verifying  : httpd-filesystem-2.4.62-1.amzn2.0.2.noarch                                                                                                                                                                                                                              9/9 

Installed:
  httpd.x86_64 0:2.4.62-1.amzn2.0.2                                                                                                                                                                                                                                                        

Dependency Installed:
  apr.x86_64 0:1.7.2-1.amzn2             apr-util.x86_64 0:1.6.3-1.amzn2.0.1 apr-util-bdb.x86_64 0:1.6.3-1.amzn2.0.1 generic-logos-httpd.noarch 0:18.0.0-4.amzn2 httpd-filesystem.noarch 0:2.4.62-1.amzn2.0.2 httpd-tools.x86_64 0:2.4.62-1.amzn2.0.2 mailcap.noarch 0:2.1.41-2.amzn2
  mod_http2.x86_64 0:1.15.19-1.amzn2.0.2

Complete!
[ec2-user@ip-172-31-38-107 ~]$ sudo systemctl start httpd.service
[ec2-user@ip-172-31-38-107 ~]$ sudo systemctl enable httpd.service
Created symlink from /etc/systemd/system/multi-user.target.wants/httpd.service to /usr/lib/systemd/system/httpd.service.

アクセス確認

EC2_PUBLIC_IPは適宜変更

コマンド
EC2_PUBLIC_IP="13.113.212.231" \
&& echo ${EC2_PUBLIC_IP}

curl ${EC2_PUBLIC_IP}

出力
[ec2-user@ip-172-31-38-107 ~]$ EC2_PUBLIC_IP="13.113.212.231" \
> && echo ${EC2_PUBLIC_IP}
13.113.212.231
[ec2-user@ip-172-31-38-107 ~]$ 
[ec2-user@ip-172-31-38-107 ~]$ curl ${EC2_PUBLIC_IP}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
        <head>
                <title>Test Page for the Apache HTTP Server</title>
                <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
                <style type="text/css">
                        /*<![CDATA[*/
                        body {
                                background-color: #fff;
                                color: #000;
                                font-size: 0.9em;
                                font-family: sans-serif,helvetica;
                                margin: 0;
                                padding: 0;
                        }
                        :link {
                                color: #c00;
                        }
                        :visited {
                                color: #c00;
                        }
                        a:hover {
                                color: #f50;
                        }
                        h1 {
                                text-align: center;
                                margin: 0;
                                padding: 0.6em 2em 0.4em;
                                background-color: #900;
                                color: #fff;
                                font-weight: normal;
                                font-size: 1.75em;
                                border-bottom: 2px solid #000;
                        }
                        h1 strong {
                                font-weight: bold;
                        }
                        h2 {
                                font-size: 1.1em;
                                font-weight: bold;
                        }
                        hr {
                                display: none;
                        }
                        .content {
                                padding: 1em 5em;
                        }
                        .content-columns {
                                /* Setting relative positioning allows for 
                                absolute positioning for sub-classes */
                                position: relative;
                                padding-top: 1em;
                        }
                        .content-column-left {
                                /* Value for IE/Win; will be overwritten for other browsers */
                                width: 47%;
                                padding-right: 3%;
                                float: left;
                                padding-bottom: 2em;
                        }
                        .content-column-left hr {
                                display: none;
                        }
                        .content-column-right {
                                /* Values for IE/Win; will be overwritten for other browsers */
                                width: 47%;
                                padding-left: 3%;
                                float: left;
                                padding-bottom: 2em;
                        }
                        .content-columns>.content-column-left, .content-columns>.content-column-right {
                                /* Non-IE/Win */
                        }
                        img {
                                border: 2px solid #fff;
                                padding: 2px;
                                margin: 2px;
                        }
                        a:hover img {
                                border: 2px solid #f50;
                        }
                        /*]]>*/
                </style>
        </head>

        <body>
                <h1>Test Page</h1>

                <div class="content">
                        <div class="content-middle">
                                <p>This page is used to test the proper operation of the Apache HTTP server after it has been installed. If you can read this page, it means that the Apache HTTP server installed at this site is working properly.</p>
                        </div>
                        <hr />

                        <div class="content-columns">
                                <div class="content-column-left">
                                        <h2>If you are a member of the general public:</h2>

                                        <p>The fact that you are seeing this page indicates that the website you just visited is either experiencing problems, or is undergoing routine maintenance.</p>

                                        <p>If you would like to let the administrators of this website know that you've seen this page instead of the page you expected, you should send them e-mail. In general, mail sent to the name "webmaster" and directed to the website's domain should reach the appropriate person.</p>

                                        <p>For example, if you experienced problems while visiting www.example.com, you should send e-mail to "webmaster@example.com".</p>

                                        <hr />
                                </div>

                                <div class="content-column-right">
                                        <h2>If you are the website administrator:</h2>

                                        <p>You may now add content to the directory <tt>/var/www/html/</tt>. Note that until you do so, people visiting your website will see this page, and not your content. To prevent this page from ever being used, follow the instructions in the file <tt>/etc/httpd/conf.d/welcome.conf</tt>.</p>

                                        <p>You are free to use the image below on web sites powered by the Apache HTTP Server:</p>

                                        <p align="center"><a href="http://httpd.apache.org/"><img src="/icons/apache_pb2.gif" alt="[ Powered by Apache ]"/></a></p>

                                </div>
                        </div>
                </div>
        </body>
</html>

CodeDeploy エージェントをインストール

コマンド
sudo yum install ruby -y
sudo yum install wget -y
cd /home/ec2-user
wget https://aws-codedeploy-ap-northeast-1.s3.ap-northeast-1.amazonaws.com/latest/install
chmod +x ./install
sudo ./install auto
systemctl status codedeploy-agent

出力
[ec2-user@ip-172-31-38-107 ~]$ sudo yum install ruby -y
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
Resolving Dependencies
--> Running transaction check
---> Package ruby.x86_64 0:2.0.0.648-36.amzn2.0.10 will be installed
--> Processing Dependency: ruby-libs(x86-64) = 2.0.0.648-36.amzn2.0.10 for package: ruby-2.0.0.648-36.amzn2.0.10.x86_64
--> Processing Dependency: ruby(rubygems) >= 2.0.14.1 for package: ruby-2.0.0.648-36.amzn2.0.10.x86_64
--> Processing Dependency: rubygem(bigdecimal) >= 1.2.0 for package: ruby-2.0.0.648-36.amzn2.0.10.x86_64
--> Processing Dependency: libruby.so.2.0()(64bit) for package: ruby-2.0.0.648-36.amzn2.0.10.x86_64
--> Running transaction check
---> Package ruby-libs.x86_64 0:2.0.0.648-36.amzn2.0.10 will be installed
---> Package rubygem-bigdecimal.x86_64 0:1.2.0-36.amzn2.0.10 will be installed
---> Package rubygems.noarch 0:2.0.14.1-36.amzn2.0.10 will be installed
--> Processing Dependency: rubygem(io-console) >= 0.4.2 for package: rubygems-2.0.14.1-36.amzn2.0.10.noarch
--> Processing Dependency: rubygem(psych) >= 2.0.0 for package: rubygems-2.0.14.1-36.amzn2.0.10.noarch
--> Processing Dependency: rubygem(rdoc) >= 4.0.0 for package: rubygems-2.0.14.1-36.amzn2.0.10.noarch
--> Running transaction check
---> Package rubygem-io-console.x86_64 0:0.4.2-36.amzn2.0.10 will be installed
---> Package rubygem-psych.x86_64 0:2.0.0-36.amzn2.0.10 will be installed
---> Package rubygem-rdoc.noarch 0:4.0.0-36.amzn2.0.10 will be installed
--> Processing Dependency: ruby(irb) = 2.0.0.648 for package: rubygem-rdoc-4.0.0-36.amzn2.0.10.noarch
--> Processing Dependency: rubygem(json) >= 1.7.7 for package: rubygem-rdoc-4.0.0-36.amzn2.0.10.noarch
--> Running transaction check
---> Package ruby-irb.noarch 0:2.0.0.648-36.amzn2.0.10 will be installed
---> Package rubygem-json.x86_64 0:1.7.7-36.amzn2.0.10 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

===========================================================================================================================================================================================================================================================================================
 Package                                                                 Arch                                                        Version                                                                         Repository                                                       Size
===========================================================================================================================================================================================================================================================================================
Installing:
 ruby                                                                    x86_64                                                      2.0.0.648-36.amzn2.0.10                                                         amzn2-core                                                       75 k
Installing for dependencies:
 ruby-irb                                                                noarch                                                      2.0.0.648-36.amzn2.0.10                                                         amzn2-core                                                       97 k
 ruby-libs                                                               x86_64                                                      2.0.0.648-36.amzn2.0.10                                                         amzn2-core                                                      2.8 M
 rubygem-bigdecimal                                                      x86_64                                                      1.2.0-36.amzn2.0.10                                                             amzn2-core                                                       87 k
 rubygem-io-console                                                      x86_64                                                      0.4.2-36.amzn2.0.10                                                             amzn2-core                                                       58 k
 rubygem-json                                                            x86_64                                                      1.7.7-36.amzn2.0.10                                                             amzn2-core                                                       83 k
 rubygem-psych                                                           x86_64                                                      2.0.0-36.amzn2.0.10                                                             amzn2-core                                                       87 k
 rubygem-rdoc                                                            noarch                                                      4.0.0-36.amzn2.0.10                                                             amzn2-core                                                      326 k
 rubygems                                                                noarch                                                      2.0.14.1-36.amzn2.0.10                                                          amzn2-core                                                      218 k

Transaction Summary
===========================================================================================================================================================================================================================================================================================
Install  1 Package (+8 Dependent packages)

Total download size: 3.8 M
Installed size: 12 M
Downloading packages:
(1/9): ruby-2.0.0.648-36.amzn2.0.10.x86_64.rpm                                                                                                                                                                                                                      |  75 kB  00:00:00     
(2/9): ruby-irb-2.0.0.648-36.amzn2.0.10.noarch.rpm                                                                                                                                                                                                                  |  97 kB  00:00:00     
(3/9): rubygem-bigdecimal-1.2.0-36.amzn2.0.10.x86_64.rpm                                                                                                                                                                                                            |  87 kB  00:00:00     
(4/9): rubygem-io-console-0.4.2-36.amzn2.0.10.x86_64.rpm                                                                                                                                                                                                            |  58 kB  00:00:00     
(5/9): rubygem-json-1.7.7-36.amzn2.0.10.x86_64.rpm                                                                                                                                                                                                                  |  83 kB  00:00:00     
(6/9): ruby-libs-2.0.0.648-36.amzn2.0.10.x86_64.rpm                                                                                                                                                                                                                 | 2.8 MB  00:00:00     
(7/9): rubygem-psych-2.0.0-36.amzn2.0.10.x86_64.rpm                                                                                                                                                                                                                 |  87 kB  00:00:00     
(8/9): rubygem-rdoc-4.0.0-36.amzn2.0.10.noarch.rpm                                                                                                                                                                                                                  | 326 kB  00:00:00     
(9/9): rubygems-2.0.14.1-36.amzn2.0.10.noarch.rpm                                                                                                                                                                                                                   | 218 kB  00:00:00     
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Total                                                                                                                                                                                                                                                       15 MB/s | 3.8 MB  00:00:00     
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : ruby-libs-2.0.0.648-36.amzn2.0.10.x86_64                                                                                                                                                                                                                                1/9 
  Installing : ruby-irb-2.0.0.648-36.amzn2.0.10.noarch                                                                                                                                                                                                                                 2/9 
  Installing : rubygem-json-1.7.7-36.amzn2.0.10.x86_64                                                                                                                                                                                                                                 3/9 
  Installing : rubygem-io-console-0.4.2-36.amzn2.0.10.x86_64                                                                                                                                                                                                                           4/9 
  Installing : rubygem-psych-2.0.0-36.amzn2.0.10.x86_64                                                                                                                                                                                                                                5/9 
  Installing : rubygems-2.0.14.1-36.amzn2.0.10.noarch                                                                                                                                                                                                                                  6/9 
  Installing : rubygem-bigdecimal-1.2.0-36.amzn2.0.10.x86_64                                                                                                                                                                                                                           7/9 
  Installing : ruby-2.0.0.648-36.amzn2.0.10.x86_64                                                                                                                                                                                                                                     8/9 
  Installing : rubygem-rdoc-4.0.0-36.amzn2.0.10.noarch                                                                                                                                                                                                                                 9/9 
  Verifying  : rubygem-bigdecimal-1.2.0-36.amzn2.0.10.x86_64                                                                                                                                                                                                                           1/9 
  Verifying  : ruby-irb-2.0.0.648-36.amzn2.0.10.noarch                                                                                                                                                                                                                                 2/9 
  Verifying  : ruby-libs-2.0.0.648-36.amzn2.0.10.x86_64                                                                                                                                                                                                                                3/9 
  Verifying  : rubygem-json-1.7.7-36.amzn2.0.10.x86_64                                                                                                                                                                                                                                 4/9 
  Verifying  : rubygem-io-console-0.4.2-36.amzn2.0.10.x86_64                                                                                                                                                                                                                           5/9 
  Verifying  : rubygems-2.0.14.1-36.amzn2.0.10.noarch                                                                                                                                                                                                                                  6/9 
  Verifying  : rubygem-rdoc-4.0.0-36.amzn2.0.10.noarch                                                                                                                                                                                                                                 7/9 
  Verifying  : ruby-2.0.0.648-36.amzn2.0.10.x86_64                                                                                                                                                                                                                                     8/9 
  Verifying  : rubygem-psych-2.0.0-36.amzn2.0.10.x86_64                                                                                                                                                                                                                                9/9 

Installed:
  ruby.x86_64 0:2.0.0.648-36.amzn2.0.10                                                                                                                                                                                                                                                    

Dependency Installed:
  ruby-irb.noarch 0:2.0.0.648-36.amzn2.0.10   ruby-libs.x86_64 0:2.0.0.648-36.amzn2.0.10   rubygem-bigdecimal.x86_64 0:1.2.0-36.amzn2.0.10   rubygem-io-console.x86_64 0:0.4.2-36.amzn2.0.10   rubygem-json.x86_64 0:1.7.7-36.amzn2.0.10   rubygem-psych.x86_64 0:2.0.0-36.amzn2.0.10  
  rubygem-rdoc.noarch 0:4.0.0-36.amzn2.0.10   rubygems.noarch 0:2.0.14.1-36.amzn2.0.10    

Complete!
[ec2-user@ip-172-31-38-107 ~]$ sudo yum install wget -y
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
Package wget-1.14-18.amzn2.1.x86_64 already installed and latest version
Nothing to do
[ec2-user@ip-172-31-38-107 ~]$ cd /home/ec2-user
[ec2-user@ip-172-31-38-107 ~]$ wget https://aws-codedeploy-ap-northeast-1.s3.ap-northeast-1.amazonaws.com/latest/install
--2024-09-14 06:32:11--  https://aws-codedeploy-ap-northeast-1.s3.ap-northeast-1.amazonaws.com/latest/install
Resolving aws-codedeploy-ap-northeast-1.s3.ap-northeast-1.amazonaws.com (aws-codedeploy-ap-northeast-1.s3.ap-northeast-1.amazonaws.com)... 52.219.199.26, 52.219.151.66, 52.219.16.191, ...
Connecting to aws-codedeploy-ap-northeast-1.s3.ap-northeast-1.amazonaws.com (aws-codedeploy-ap-northeast-1.s3.ap-northeast-1.amazonaws.com)|52.219.199.26|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 19045 (19K) []
Saving to: ‘install’

100%[=================================================================================================================================================================================================================================================>] 19,045      --.-K/s   in 0.002s  

2024-09-14 06:32:11 (10.9 MB/s) - ‘install’ saved [19045/19045]

[ec2-user@ip-172-31-38-107 ~]$ chmod +x ./install
[ec2-user@ip-172-31-38-107 ~]$ sudo ./install auto
I, [2024-09-14T06:32:11.448807 #3803]  INFO -- : Starting Ruby version check.
I, [2024-09-14T06:32:11.450004 #3803]  INFO -- : Starting update check.
I, [2024-09-14T06:32:11.450101 #3803]  INFO -- : Attempting to automatically detect supported package manager type for system...
I, [2024-09-14T06:32:11.479127 #3803]  INFO -- : Checking AWS_REGION environment variable for region information...
I, [2024-09-14T06:32:11.479176 #3803]  INFO -- : Checking EC2 metadata service for region information...
I, [2024-09-14T06:32:11.493693 #3803]  INFO -- : Checking AWS_DOMAIN environment variable for domain information...
I, [2024-09-14T06:32:11.493846 #3803]  INFO -- : Checking EC2 metadata service for domain information...
I, [2024-09-14T06:32:11.506796 #3803]  INFO -- : Downloading version file from bucket aws-codedeploy-ap-northeast-1 and key latest/LATEST_VERSION...
I, [2024-09-14T06:32:11.507165 #3803]  INFO -- : Endpoint: https://aws-codedeploy-ap-northeast-1.s3.ap-northeast-1.amazonaws.com/latest/LATEST_VERSION
I, [2024-09-14T06:32:11.600389 #3803]  INFO -- : Downloading package from bucket aws-codedeploy-ap-northeast-1 and key releases/codedeploy-agent-1.7.0-92.noarch.rpm...
I, [2024-09-14T06:32:11.600526 #3803]  INFO -- : Endpoint: https://aws-codedeploy-ap-northeast-1.s3.ap-northeast-1.amazonaws.com/releases/codedeploy-agent-1.7.0-92.noarch.rpm
I, [2024-09-14T06:32:11.730397 #3803]  INFO -- : Executing `/usr/bin/yum -y localinstall /tmp/codedeploy-agent-1.7.0-92.noarch.tmp-20240914-3803-depiy5.rpm`...
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
Existing lock /var/run/yum.pid: another copy is running as pid 3798.
Another app is currently holding the yum lock; waiting for it to exit...
  The other application is: yum
    Memory : 123 M RSS (343 MB VSZ)
    Started: Sat Sep 14 06:32:10 2024 - 00:02 ago
    State  : Running, pid: 3798
Another app is currently holding the yum lock; waiting for it to exit...
  The other application is: yum
    Memory : 207 M RSS (428 MB VSZ)
    Started: Sat Sep 14 06:32:10 2024 - 00:04 ago
    State  : Running, pid: 3798
Examining /tmp/codedeploy-agent-1.7.0-92.noarch.tmp-20240914-3803-depiy5.rpm: codedeploy-agent-1.7.0-92.noarch
Marking /tmp/codedeploy-agent-1.7.0-92.noarch.tmp-20240914-3803-depiy5.rpm to be installed
Resolving Dependencies
--> Running transaction check
---> Package codedeploy-agent.noarch 0:1.7.0-92 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

===========================================================================================================================================================================================================================================================================================
 Package                                                        Arch                                                 Version                                                Repository                                                                                                Size
===========================================================================================================================================================================================================================================================================================
Installing:
 codedeploy-agent                                               noarch                                               1.7.0-92                                               /codedeploy-agent-1.7.0-92.noarch.tmp-20240914-3803-depiy5                                                13 M

Transaction Summary
===========================================================================================================================================================================================================================================================================================
Install  1 Package

Total size: 13 M
Installed size: 13 M
Downloading packages:
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
 
pre hook : 1
Checking if there is already a process named codedeploy-agent running.
  Installing : codedeploy-agent-1.7.0-92.noarch                                                                                                                                                                                                                                        1/1 
 
post hook : 1
Check if there is a codedeployagent config file.
Start codedeploy-agent in post hook if this is a first install.
  Verifying  : codedeploy-agent-1.7.0-92.noarch                                                                                                                                                                                                                                        1/1 

Installed:
  codedeploy-agent.noarch 0:1.7.0-92                                                                                                                                                                                                                                                       

Complete!
I, [2024-09-14T06:32:17.596613 #3803]  INFO -- : Update check complete.
I, [2024-09-14T06:32:17.596657 #3803]  INFO -- : Stopping updater.
[ec2-user@ip-172-31-38-107 ~]$ systemctl status codedeploy-agent
● codedeploy-agent.service - AWS CodeDeploy Host Agent
   Loaded: loaded (/usr/lib/systemd/system/codedeploy-agent.service; enabled; vendor preset: disabled)
   Active: active (running) since Sat 2024-09-14 06:32:17 UTC; 197ms ago
  Process: 3873 ExecStart=/bin/bash -a -c [ -f /etc/profile ] && source /etc/profile; /opt/codedeploy-agent/bin/codedeploy-agent start (code=exited, status=0/SUCCESS)
 Main PID: 3885 (ruby)
   CGroup: /system.slice/codedeploy-agent.service
           ├─3885 codedeploy-agent: master 3885
           └─3889 codedeploy-agent: booting child

Sep 14 06:32:17 ip-172-31-38-107.ap-northeast-1.compute.internal systemd[1]: Starting AWS CodeDeploy Host Agent...
Sep 14 06:32:17 ip-172-31-38-107.ap-northeast-1.compute.internal systemd[1]: Started AWS CodeDeploy Host Agent.

EC2 Instance Connect を切断

コマンド
exit

出力
[ec2-user@ip-172-31-38-107 ~]$ exit
logout
Connection to 13.113.212.231 closed.

05 EC2 インスタンスをデプロイ先とした、CI/CD 環境を構築する【CodeBuild 編】

IAM

コマンド
# 変数
CODEBUILD_NAME="h4b-hands-on" \
&& echo ${CODEBUILD_NAME}

# CODEBUILDアーティファクト用のS3バケット名
CODEBUILD_ARTIFACTSTORE_BUCKET_NAME="codebuild-${CODEBUILD_NAME}-artifactstore" \
&& echo ${CODEBUILD_ARTIFACTSTORE_BUCKET_NAME}

# ポリシー名
CODEBUILD_IAM_POLICY_NAME="CodeBuildBasePolicy-${CODEBUILD_NAME}-${REGION}" \
&& echo ${CODEBUILD_IAM_POLICY_NAME}

# ロール名
CODEBUILD_IAM_ROLE_NAME="codebuild-${CODEBUILD_NAME}-service-role" \
&& echo ${CODEBUILD_IAM_ROLE_NAME}

# AWS管理ポリシー
AWS_POLICY_NAME="AWSCodeDeployDeployerAccess" \
&& echo ${AWS_POLICY_NAME}

# IAMパス
IAM_PATH="/service-role/" \
&& echo ${IAM_PATH}

# IAMポリシー
POLICY_DOCUMENT_JSON=$(cat << EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Resource": [
                "arn:aws:logs:ap-northeast-1:999999999999:log-group:/aws/codebuild/h4b-hands-on",
                "arn:aws:logs:ap-northeast-1:999999999999:log-group:/aws/codebuild/h4b-hands-on:*"
            ],
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ]
        },
        {
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::codepipeline-ap-northeast-1-*"
            ],
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:GetObjectVersion",
                "s3:GetBucketAcl",
                "s3:GetBucketLocation"
            ]
        },
        {
            "Effect": "Allow",
            "Resource": [
                "arn:aws:codecommit:ap-northeast-1:999999999999:h4b-hands-on"
            ],
            "Action": [
                "codecommit:GitPull"
            ]
        },
        {
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::${CODEBUILD_ARTIFACTSTORE_BUCKET_NAME}",
                "arn:aws:s3:::${CODEBUILD_ARTIFACTSTORE_BUCKET_NAME}/*"
            ],
            "Action": [
                "s3:PutObject",
                "s3:GetBucketAcl",
                "s3:GetBucketLocation"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "codebuild:CreateReportGroup",
                "codebuild:CreateReport",
                "codebuild:UpdateReport",
                "codebuild:BatchPutTestCases",
                "codebuild:BatchPutCodeCoverages"
            ],
            "Resource": [
                "arn:aws:codebuild:ap-northeast-1:999999999999:report-group/h4b-hands-on-*"
            ]
        }
    ]
}
EOF
) \
&& echo ${POLICY_DOCUMENT_JSON}

# JSONフォーマットの確認
echo ${POLICY_DOCUMENT_JSON} | python -m json.tool

# ポリシーの作成
aws iam create-policy \
    --policy-name ${CODEBUILD_IAM_POLICY_NAME} \
    --path ${IAM_PATH} \
    --policy-document "${POLICY_DOCUMENT_JSON}"

# ARN取得
CODEBUILD_IAM_POLICY_ARN=$(
    aws iam list-policies \
        --query "Policies[?PolicyName=='${CODEBUILD_IAM_POLICY_NAME}'].Arn" \
        --output text
) \
&& echo ${CODEBUILD_IAM_POLICY_ARN}

# 信頼関係ポリシードキュメントの作成
ASSUME_ROLE_POLICY_DOCUMENT=$(cat << EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "codebuild.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
EOF
) \
&& echo ${ASSUME_ROLE_POLICY_DOCUMENT}

# JSONフォーマットの確認
echo ${ASSUME_ROLE_POLICY_DOCUMENT} | python -m json.tool

# IAMロールの作成
aws iam create-role \
    --path ${IAM_PATH} \
    --role-name ${CODEBUILD_IAM_ROLE_NAME} \
    --assume-role-policy-document "${ASSUME_ROLE_POLICY_DOCUMENT}"

# ARN取得
CODEBUILD_IAM_ROLE_ARN=$(
    aws iam get-role \
        --role-name ${CODEBUILD_IAM_ROLE_NAME} \
        --query 'Role.Arn' --output text
) \
&& echo ${CODEBUILD_IAM_ROLE_ARN}

# IAMロールにポリシーをアタッチ
aws iam attach-role-policy \
    --role-name ${CODEBUILD_IAM_ROLE_NAME} \
    --policy-arn ${CODEBUILD_IAM_POLICY_ARN}

aws iam attach-role-policy \
    --role-name ${CODEBUILD_IAM_ROLE_NAME} \
    --policy-arn arn:aws:iam::aws:policy/${AWS_POLICY_NAME}

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # 変数
[cloudshell-user@ip-10-132-76-170 ~]$ CODEBUILD_NAME="h4b-hands-on" \
> && echo ${CODEBUILD_NAME}
h4b-hands-on
[cloudshell-user@ip-10-132-76-170 ~]$ 
a[cloudshell-user@ip-10-132-76-170 ~]$ # CODEBUILDアーティファクト用のS3バケット名
[cloudshell-user@ip-10-132-76-170 ~]$ CODEBUILD_ARTIFACTSTORE_BUCKET_NAME="codebuild-${CODEBUILD_NAME}-artifactstore" \
> && echo ${CODEBUILD_ARTIFACTSTORE_BUCKET_NAME}
codebuild-h4b-hands-on-artifactstore
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # ポリシー名
[cloudshell-user@ip-10-132-76-170 ~]$ CODEBUILD_IAM_POLICY_NAME="CodeBuildBasePolicy-${CODEBUILD_NAME}-${REGION}" \
> && echo ${CODEBUILD_IAM_POLICY_NAME}
CodeBuildBasePolicy-h4b-hands-on-ap-northeast-1
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # ロール名
[cloudshell-user@ip-10-132-76-170 ~]$ CODEBUILD_IAM_ROLE_NAME="codebuild-${CODEBUILD_NAME}-service-role" \
> && echo ${CODEBUILD_IAM_ROLE_NAME}
codebuild-h4b-hands-on-service-role
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # AWS管理ポリシー
[cloudshell-user@ip-10-132-76-170 ~]$ AWS_POLICY_NAME="AWSCodeDeployDeployerAccess" \
> && echo ${AWS_POLICY_NAME}
AWSCodeDeployDeployerAccess
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # IAMパス
[cloudshell-user@ip-10-132-76-170 ~]$ IAM_PATH="/service-role/" \
> && echo ${IAM_PATH}
/service-role/
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # IAMポリシー
[cloudshell-user@ip-10-132-76-170 ~]$ POLICY_DOCUMENT_JSON=$(cat << EOF
> {
>     "Version": "2012-10-17",
>     "Statement": [
>         {
>             "Effect": "Allow",
>             "Resource": [
>                 "arn:aws:logs:ap-northeast-1:999999999999:log-group:/aws/codebuild/h4b-hands-on",
>                 "arn:aws:logs:ap-northeast-1:999999999999:log-group:/aws/codebuild/h4b-hands-on:*"
>             ],
>             "Action": [
>                 "logs:CreateLogGroup",
>                 "logs:CreateLogStream",
>                 "logs:PutLogEvents"
>             ]
>         },
>         {
>             "Effect": "Allow",
>             "Resource": [
>                 "arn:aws:s3:::codepipeline-ap-northeast-1-*"
>             ],
>             "Action": [
>                 "s3:PutObject",
>                 "s3:GetObject",
>                 "s3:GetObjectVersion",
>                 "s3:GetBucketAcl",
>                 "s3:GetBucketLocation"
>             ]
>         },
>         {
>             "Effect": "Allow",
>             "Resource": [
>                 "arn:aws:codecommit:ap-northeast-1:999999999999:h4b-hands-on"
>             ],
>             "Action": [
>                 "codecommit:GitPull"
>             ]
>         },
>         {
>             "Effect": "Allow",
>             "Resource": [
>                 "arn:aws:s3:::${CODEBUILD_ARTIFACTSTORE_BUCKET_NAME}",
>                 "arn:aws:s3:::${CODEBUILD_ARTIFACTSTORE_BUCKET_NAME}/*"
>             ],
>             "Action": [
>                 "s3:PutObject",
>                 "s3:GetBucketAcl",
>                 "s3:GetBucketLocation"
>             ]
>         },
>         {
>             "Effect": "Allow",
>             "Action": [
>                 "codebuild:CreateReportGroup",
>                 "codebuild:CreateReport",
>                 "codebuild:UpdateReport",
>                 "codebuild:BatchPutTestCases",
>                 "codebuild:BatchPutCodeCoverages"
>             ],
>             "Resource": [
>                 "arn:aws:codebuild:ap-northeast-1:999999999999:report-group/h4b-hands-on-*"
>             ]
>         }
>     ]
> }
> EOF
> ) \
> && echo ${POLICY_DOCUMENT_JSON}
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Resource": [ "arn:aws:logs:ap-northeast-1:999999999999:log-group:/aws/codebuild/h4b-hands-on", "arn:aws:logs:ap-northeast-1:999999999999:log-group:/aws/codebuild/h4b-hands-on:*" ], "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ] }, { "Effect": "Allow", "Resource": [ "arn:aws:s3:::codepipeline-ap-northeast-1-*" ], "Action": [ "s3:PutObject", "s3:GetObject", "s3:GetObjectVersion", "s3:GetBucketAcl", "s3:GetBucketLocation" ] }, { "Effect": "Allow", "Resource": [ "arn:aws:codecommit:ap-northeast-1:999999999999:h4b-hands-on" ], "Action": [ "codecommit:GitPull" ] }, { "Effect": "Allow", "Resource": [ "arn:aws:s3:::codebuild-h4b-hands-on-artifactstore", "arn:aws:s3:::codebuild-h4b-hands-on-artifactstore/*" ], "Action": [ "s3:PutObject", "s3:GetBucketAcl", "s3:GetBucketLocation" ] }, { "Effect": "Allow", "Action": [ "codebuild:CreateReportGroup", "codebuild:CreateReport", "codebuild:UpdateReport", "codebuild:BatchPutTestCases", "codebuild:BatchPutCodeCoverages" ], "Resource": [ "arn:aws:codebuild:ap-northeast-1:999999999999:report-group/h4b-hands-on-*" ] } ] }
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-132-76-170 ~]$ echo ${POLICY_DOCUMENT_JSON} | python -m json.tool
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Resource": [
                "arn:aws:logs:ap-northeast-1:999999999999:log-group:/aws/codebuild/h4b-hands-on",
                "arn:aws:logs:ap-northeast-1:999999999999:log-group:/aws/codebuild/h4b-hands-on:*"
            ],
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ]
        },
        {
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::codepipeline-ap-northeast-1-*"
            ],
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:GetObjectVersion",
                "s3:GetBucketAcl",
                "s3:GetBucketLocation"
            ]
        },
        {
            "Effect": "Allow",
            "Resource": [
                "arn:aws:codecommit:ap-northeast-1:999999999999:h4b-hands-on"
            ],
            "Action": [
                "codecommit:GitPull"
            ]
        },
        {
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::codebuild-h4b-hands-on-artifactstore",
                "arn:aws:s3:::codebuild-h4b-hands-on-artifactstore/*"
            ],
            "Action": [
                "s3:PutObject",
                "s3:GetBucketAcl",
                "s3:GetBucketLocation"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "codebuild:CreateReportGroup",
                "codebuild:CreateReport",
                "codebuild:UpdateReport",
                "codebuild:BatchPutTestCases",
                "codebuild:BatchPutCodeCoverages"
            ],
            "Resource": [
                "arn:aws:codebuild:ap-northeast-1:999999999999:report-group/h4b-hands-on-*"
            ]
        }
    ]
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # ポリシーの作成
[cloudshell-user@ip-10-132-76-170 ~]$ aws iam create-policy \
>     --policy-name ${CODEBUILD_IAM_POLICY_NAME} \
>     --path ${IAM_PATH} \
>     --policy-document "${POLICY_DOCUMENT_JSON}"
{
    "Policy": {
        "PolicyName": "CodeBuildBasePolicy-h4b-hands-on-ap-northeast-1",
        "PolicyId": "ANPAWFKRCMKOZJ4SXYWZP",
        "Arn": "arn:aws:iam::999999999999:policy/service-role/CodeBuildBasePolicy-h4b-hands-on-ap-northeast-1",
        "Path": "/service-role/",
        "DefaultVersionId": "v1",
        "AttachmentCount": 0,
        "PermissionsBoundaryUsageCount": 0,
        "IsAttachable": true,
        "CreateDate": "2024-09-14T06:33:09+00:00",
        "UpdateDate": "2024-09-14T06:33:09+00:00"
    }
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # ARN取得
[cloudshell-user@ip-10-132-76-170 ~]$ CODEBUILD_IAM_POLICY_ARN=$(
>     aws iam list-policies \
>         --query "Policies[?PolicyName=='${CODEBUILD_IAM_POLICY_NAME}'].Arn" \
>         --output text
> ) \
> && echo ${CODEBUILD_IAM_POLICY_ARN}
arn:aws:iam::999999999999:policy/service-role/CodeBuildBasePolicy-h4b-hands-on-ap-northeast-1
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # 信頼関係ポリシードキュメントの作成
[cloudshell-user@ip-10-132-76-170 ~]$ ASSUME_ROLE_POLICY_DOCUMENT=$(cat << EOF
> {
>     "Version": "2012-10-17",
>     "Statement": [
>         {
>             "Effect": "Allow",
>             "Principal": {
>                 "Service": "codebuild.amazonaws.com"
>             },
>             "Action": "sts:AssumeRole"
>         }
>     ]
> }
> EOF
> ) \
> && echo ${ASSUME_ROLE_POLICY_DOCUMENT}
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "codebuild.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-132-76-170 ~]$ echo ${ASSUME_ROLE_POLICY_DOCUMENT} | python -m json.tool
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "codebuild.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # IAMロールの作成
[cloudshell-user@ip-10-132-76-170 ~]$ aws iam create-role \
>     --path ${IAM_PATH} \
>     --role-name ${CODEBUILD_IAM_ROLE_NAME} \
>     --assume-role-policy-document "${ASSUME_ROLE_POLICY_DOCUMENT}"
{
    "Role": {
        "Path": "/service-role/",
        "RoleName": "codebuild-h4b-hands-on-service-role",
        "RoleId": "AROAWFKRCMKO3C47DZRRL",
        "Arn": "arn:aws:iam::999999999999:role/service-role/codebuild-h4b-hands-on-service-role",
        "CreateDate": "2024-09-14T06:33:16+00:00",
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Effect": "Allow",
                    "Principal": {
                        "Service": "codebuild.amazonaws.com"
                    },
                    "Action": "sts:AssumeRole"
                }
            ]
        }
    }
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # ARN取得
[cloudshell-user@ip-10-132-76-170 ~]$ CODEBUILD_IAM_ROLE_ARN=$(
>     aws iam get-role \
>         --role-name ${CODEBUILD_IAM_ROLE_NAME} \
>         --query 'Role.Arn' --output text
> ) \
> && echo ${CODEBUILD_IAM_ROLE_ARN}
arn:aws:iam::999999999999:role/service-role/codebuild-h4b-hands-on-service-role
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # IAMロールにポリシーをアタッチ
[cloudshell-user@ip-10-132-76-170 ~]$ aws iam attach-role-policy \
>     --role-name ${CODEBUILD_IAM_ROLE_NAME} \
>     --policy-arn ${CODEBUILD_IAM_POLICY_ARN}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ aws iam attach-role-policy \
>     --role-name ${CODEBUILD_IAM_ROLE_NAME} \
>     --policy-arn arn:aws:iam::aws:policy/${AWS_POLICY_NAME}

作成

コマンド
# バケット作成
aws s3api create-bucket \
    --bucket ${CODEBUILD_ARTIFACTSTORE_BUCKET_NAME} \
    --create-bucket-configuration LocationConstraint=${REGION}

# 作成
aws codebuild create-project \
    --name "${CODEBUILD_NAME}" \
    --source "type=CODECOMMIT,location=${CLONEURLHTTP},gitCloneDepth=1,insecureSsl=false,gitSubmodulesConfig={fetchSubmodules=false}" \
    --source-version "refs/heads/master" \
    --artifacts "type=S3,location=${CODEBUILD_ARTIFACTSTORE_BUCKET_NAME},namespaceType=NONE,name=${CODEBUILD_NAME},packaging=NONE,overrideArtifactName=false,encryptionDisabled=false" \
    --environment "type=LINUX_CONTAINER,image=aws/codebuild/amazonlinux2-x86_64-standard:5.0,computeType=BUILD_GENERAL1_SMALL,privilegedMode=false,imagePullCredentialsType=CODEBUILD" \
    --service-role "arn:aws:iam::999999999999:role/service-role/codebuild-h4b-hands-on-service-role" \
    --logs-config "cloudWatchLogs={status=ENABLED},s3Logs={status=DISABLED,encryptionDisabled=false}" \
    --no-cli-pager

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # バケット作成
[cloudshell-user@ip-10-132-76-170 ~]$ aws s3api create-bucket \
>     --bucket ${CODEBUILD_ARTIFACTSTORE_BUCKET_NAME} \
>     --create-bucket-configuration LocationConstraint=${REGION}
{
    "Location": "http://codebuild-h4b-hands-on-artifactstore.s3.amazonaws.com/"
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # 作成
[cloudshell-user@ip-10-132-76-170 ~]$ aws codebuild create-project \
>     --name "${CODEBUILD_NAME}" \
>     --source "type=CODECOMMIT,location=${CLONEURLHTTP},gitCloneDepth=1,insecureSsl=false,gitSubmodulesConfig={fetchSubmodules=false}" \
>     --source-version "refs/heads/master" \
>     --artifacts "type=S3,location=${CODEBUILD_ARTIFACTSTORE_BUCKET_NAME},namespaceType=NONE,name=${CODEBUILD_NAME},packaging=NONE,overrideArtifactName=false,encryptionDisabled=false" \
>     --environment "type=LINUX_CONTAINER,image=aws/codebuild/amazonlinux2-x86_64-standard:5.0,computeType=BUILD_GENERAL1_SMALL,privilegedMode=false,imagePullCredentialsType=CODEBUILD" \
>     --service-role "arn:aws:iam::999999999999:role/service-role/codebuild-h4b-hands-on-service-role" \
>     --logs-config "cloudWatchLogs={status=ENABLED},s3Logs={status=DISABLED,encryptionDisabled=false}" \
>     --no-cli-pager
{
    "project": {
        "name": "h4b-hands-on",
        "arn": "arn:aws:codebuild:ap-northeast-1:999999999999:project/h4b-hands-on",
        "source": {
            "type": "CODECOMMIT",
            "location": "https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/h4b-hands-on",
            "gitCloneDepth": 1,
            "gitSubmodulesConfig": {
                "fetchSubmodules": false
            },
            "insecureSsl": false
        },
        "sourceVersion": "refs/heads/master",
        "artifacts": {
            "type": "S3",
            "location": "codebuild-h4b-hands-on-artifactstore",
            "namespaceType": "NONE",
            "name": "h4b-hands-on",
            "packaging": "NONE",
            "overrideArtifactName": false,
            "encryptionDisabled": false
        },
        "cache": {
            "type": "NO_CACHE"
        },
        "environment": {
            "type": "LINUX_CONTAINER",
            "image": "aws/codebuild/amazonlinux2-x86_64-standard:5.0",
            "computeType": "BUILD_GENERAL1_SMALL",
            "environmentVariables": [],
            "privilegedMode": false,
            "imagePullCredentialsType": "CODEBUILD"
        },
        "serviceRole": "arn:aws:iam::999999999999:role/service-role/codebuild-h4b-hands-on-service-role",
        "timeoutInMinutes": 60,
        "queuedTimeoutInMinutes": 480,
        "encryptionKey": "arn:aws:kms:ap-northeast-1:999999999999:alias/aws/s3",
        "created": "2024-09-14T06:34:05.519000+00:00",
        "lastModified": "2024-09-14T06:34:05.519000+00:00",
        "badge": {
            "badgeEnabled": false
        },
        "logsConfig": {
            "cloudWatchLogs": {
                "status": "ENABLED"
            },
            "s3Logs": {
                "status": "DISABLED",
                "encryptionDisabled": false
            }
        },
        "projectVisibility": "PRIVATE"
    }
}

確認

コマンド
# 確認
aws codebuild batch-get-projects \
    --names ${CODEBUILD_NAME} \
    --no-cli-pager

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # 確認
[cloudshell-user@ip-10-132-76-170 ~]$ aws codebuild batch-get-projects \
>     --names ${CODEBUILD_NAME} \
>     --no-cli-pager
{
    "projects": [
        {
            "name": "h4b-hands-on",
            "arn": "arn:aws:codebuild:ap-northeast-1:999999999999:project/h4b-hands-on",
            "source": {
                "type": "CODECOMMIT",
                "location": "https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/h4b-hands-on",
                "gitCloneDepth": 1,
                "gitSubmodulesConfig": {
                    "fetchSubmodules": false
                },
                "insecureSsl": false
            },
            "sourceVersion": "refs/heads/master",
            "artifacts": {
                "type": "S3",
                "location": "codebuild-h4b-hands-on-artifactstore",
                "namespaceType": "NONE",
                "name": "h4b-hands-on",
                "packaging": "NONE",
                "overrideArtifactName": false,
                "encryptionDisabled": false
            },
            "cache": {
                "type": "NO_CACHE"
            },
            "environment": {
                "type": "LINUX_CONTAINER",
                "image": "aws/codebuild/amazonlinux2-x86_64-standard:5.0",
                "computeType": "BUILD_GENERAL1_SMALL",
                "environmentVariables": [],
                "privilegedMode": false,
                "imagePullCredentialsType": "CODEBUILD"
            },
            "serviceRole": "arn:aws:iam::999999999999:role/service-role/codebuild-h4b-hands-on-service-role",
            "timeoutInMinutes": 60,
            "queuedTimeoutInMinutes": 480,
            "encryptionKey": "arn:aws:kms:ap-northeast-1:999999999999:alias/aws/s3",
            "tags": [],
            "created": "2024-09-14T06:34:05.519000+00:00",
            "lastModified": "2024-09-14T06:34:05.519000+00:00",
            "badge": {
                "badgeEnabled": false
            },
            "logsConfig": {
                "cloudWatchLogs": {
                    "status": "ENABLED"
                },
                "s3Logs": {
                    "status": "DISABLED",
                    "encryptionDisabled": false
                }
            },
            "projectVisibility": "PRIVATE"
        }
    ],
    "projectsNotFound": []
}

以降、Cloud9で実施

buildspec.yamlの作成

CODEBUILD_ARTIFACTSTORE_BUCKET_NAMEは適宜変更

コマンド
# フォルダの作成
mkdir ~/environment/h4b-hands-on/src

# index.htmlの移動
mv ~/environment/h4b-hands-on/index.html ~/environment/h4b-hands-on/src/

# バケット変数
CODEBUILD_ARTIFACTSTORE_BUCKET_NAME="codebuild-h4b-hands-on-artifactstore" \
&& echo ${CODEBUILD_ARTIFACTSTORE_BUCKET_NAME}

# buildspec.yamlの作成
cat << EOF > buildspec.yaml
version: 0.2

phases:
  build:
    commands:
      - aws deploy push --application-name h4b-app --s3-location s3://${CODEBUILD_ARTIFACTSTORE_BUCKET_NAME}/artifact.zip --source src
artifacts:
  files:
    - '**/*'
  base-directory: src
EOF

出力
admin:~/environment/h4b-hands-on (master) $ # フォルダの作成
admin:~/environment/h4b-hands-on (master) $ mkdir ~/environment/h4b-hands-on/src
admin:~/environment/h4b-hands-on (master) $ 
admin:~/environment/h4b-hands-on (master) $ # index.htmlの移動
admin:~/environment/h4b-hands-on (master) $ mv ~/environment/h4b-hands-on/index.html ~/environment/h4b-hands-on/src/
admin:~/environment/h4b-hands-on (master) $ 
admin:~/environment/h4b-hands-on (master) $ # バケット変数
admin:~/environment/h4b-hands-on (master) $ CODEBUILD_ARTIFACTSTORE_BUCKET_NAME="codebuild-h4b-hands-on-artifactstore" \
> && echo ${CODEBUILD_ARTIFACTSTORE_BUCKET_NAME}
codebuild-h4b-hands-on-artifactstore
admin:~/environment/h4b-hands-on (master) $ 
admin:~/environment/h4b-hands-on (master) $ # buildspec.yamlの作成
admin:~/environment/h4b-hands-on (master) $ cat << EOF > buildspec.yaml
> version: 0.2
> 
> phases:
>   build:
>     commands:
>       - aws deploy push --application-name h4b-app --s3-location s3://${CODEBUILD_ARTIFACTSTORE_BUCKET_NAME}/artifact.zip --source src
> artifacts:
>   files:
>     - '**/*'
>   base-directory: src
> EOF

06 EC2 インスタンスをデプロイ先とした、CI/CD 環境を構築する【CodeDeploy 編】

以降、CloudShellで実施

コマンド
# ロール名
CODEDEPLOY_IAM_ROLE_NAME="CodeDeployRole" \
&& echo ${CODEDEPLOY_IAM_ROLE_NAME}

# AWS管理ポリシー
AWS_POLICY_NAME="AWSCodeDeployRole" \
&& echo ${AWS_POLICY_NAME}

# 信頼関係ポリシードキュメントの作成
ASSUME_ROLE_POLICY_DOCUMENT=$(cat << EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Principal": {
                "Service": "codedeploy.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
EOF
) \
&& echo ${ASSUME_ROLE_POLICY_DOCUMENT}

# JSONフォーマットの確認
echo ${ASSUME_ROLE_POLICY_DOCUMENT} | python -m json.tool

# IAMロールの作成
aws iam create-role \
    --role-name ${CODEDEPLOY_IAM_ROLE_NAME} \
    --assume-role-policy-document "${ASSUME_ROLE_POLICY_DOCUMENT}"

# ARN取得
CODEDEPLOY_IAM_ROLE_ARN=$(
    aws iam get-role \
        --role-name ${CODEDEPLOY_IAM_ROLE_NAME} \
        --query 'Role.Arn' --output text
) \
&& echo ${CODEDEPLOY_IAM_ROLE_ARN}

# IAMロールにポリシーをアタッチ
aws iam attach-role-policy \
    --role-name ${CODEDEPLOY_IAM_ROLE_NAME} \
    --policy-arn arn:aws:iam::aws:policy/service-role/${AWS_POLICY_NAME}

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # ロール名
[cloudshell-user@ip-10-132-76-170 ~]$ CODEDEPLOY_IAM_ROLE_NAME="CodeDeployRole" \
> && echo ${CODEDEPLOY_IAM_ROLE_NAME}
CodeDeployRole
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # AWS管理ポリシー
[cloudshell-user@ip-10-132-76-170 ~]$ AWS_POLICY_NAME="AWSCodeDeployRole" \
> && echo ${AWS_POLICY_NAME}
AWSCodeDeployRole
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # 信頼関係ポリシードキュメントの作成
[cloudshell-user@ip-10-132-76-170 ~]$ ASSUME_ROLE_POLICY_DOCUMENT=$(cat << EOF
> {
>     "Version": "2012-10-17",
>     "Statement": [
>         {
>             "Sid": "",
>             "Effect": "Allow",
>             "Principal": {
>                 "Service": "codedeploy.amazonaws.com"
>             },
>             "Action": "sts:AssumeRole"
>         }
>     ]
> }
> EOF
> ) \
> && echo ${ASSUME_ROLE_POLICY_DOCUMENT}
{ "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": "codedeploy.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-132-76-170 ~]$ echo ${ASSUME_ROLE_POLICY_DOCUMENT} | python -m json.tool
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Principal": {
                "Service": "codedeploy.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # IAMロールの作成
[cloudshell-user@ip-10-132-76-170 ~]$ aws iam create-role \
>     --role-name ${CODEDEPLOY_IAM_ROLE_NAME} \
>     --assume-role-policy-document "${ASSUME_ROLE_POLICY_DOCUMENT}"
{
    "Role": {
        "Path": "/",
        "RoleName": "CodeDeployRole",
        "RoleId": "AROAWFKRCMKO52G73R6PL",
        "Arn": "arn:aws:iam::999999999999:role/CodeDeployRole",
        "CreateDate": "2024-09-14T06:35:52+00:00",
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Sid": "",
                    "Effect": "Allow",
                    "Principal": {
                        "Service": "codedeploy.amazonaws.com"
                    },
                    "Action": "sts:AssumeRole"
                }
            ]
        }
    }
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # ARN取得
[cloudshell-user@ip-10-132-76-170 ~]$ CODEDEPLOY_IAM_ROLE_ARN=$(
>     aws iam get-role \
>         --role-name ${CODEDEPLOY_IAM_ROLE_NAME} \
>         --query 'Role.Arn' --output text
> ) \
> && echo ${CODEDEPLOY_IAM_ROLE_ARN}
arn:aws:iam::999999999999:role/CodeDeployRole
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # IAMロールにポリシーをアタッチ
[cloudshell-user@ip-10-132-76-170 ~]$ aws iam attach-role-policy \
>     --role-name ${CODEDEPLOY_IAM_ROLE_NAME} \
>     --policy-arn arn:aws:iam::aws:policy/service-role/${AWS_POLICY_NAME}

CodeDeploy

アプリケーション

コマンド
# 変数
CODEDEPLOY_APP_NAME="h4b-app" \
&& echo ${CODEDEPLOY_APP_NAME}

# 作成
aws deploy create-application \
    --application-name ${CODEDEPLOY_APP_NAME} \
    --compute-platform Server

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # 変数
[cloudshell-user@ip-10-132-76-170 ~]$ CODEDEPLOY_APP_NAME="h4b-app" \
> && echo ${CODEDEPLOY_APP_NAME}
h4b-app
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # 作成
[cloudshell-user@ip-10-132-76-170 ~]$ aws deploy create-application \
>     --application-name ${CODEDEPLOY_APP_NAME} \
>     --compute-platform Server
{
    "applicationId": "065b91d9-744e-4001-adec-6e3d7745cdcd"
}

デプロイグループ

コマンド
# 変数
CODEDEPLOY_GROUP_NAME="Web" \
&& echo ${CODEDEPLOY_GROUP_NAME}

# 作成
aws deploy create-deployment-group \
    --application-name ${CODEDEPLOY_APP_NAME} \
    --deployment-group-name ${CODEDEPLOY_GROUP_NAME} \
    --service-role-arn ${CODEDEPLOY_IAM_ROLE_ARN} \
    --deployment-config-name CodeDeployDefault.AllAtOnce \
    --ec2-tag-filters Key=Name,Value=Web,Type=KEY_AND_VALUE

# 確認
aws deploy get-deployment-group \
    --application-name ${CODEDEPLOY_APP_NAME} \
    --deployment-group-name ${CODEDEPLOY_GROUP_NAME}

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # 変数
[cloudshell-user@ip-10-132-76-170 ~]$ CODEDEPLOY_GROUP_NAME="Web" \
> && echo ${CODEDEPLOY_GROUP_NAME}
Web
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # 作成
[cloudshell-user@ip-10-132-76-170 ~]$ aws deploy create-deployment-group \
>     --application-name ${CODEDEPLOY_APP_NAME} \
>     --deployment-group-name ${CODEDEPLOY_GROUP_NAME} \
>     --service-role-arn ${CODEDEPLOY_IAM_ROLE_ARN} \
>     --deployment-config-name CodeDeployDefault.AllAtOnce \
>     --ec2-tag-filters Key=Name,Value=Web,Type=KEY_AND_VALUE
{
    "deploymentGroupId": "e6ad5cde-6789-42bd-8cad-23b5fedc7703"
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # 確認
[cloudshell-user@ip-10-132-76-170 ~]$ aws deploy get-deployment-group \
>     --application-name ${CODEDEPLOY_APP_NAME} \
>     --deployment-group-name ${CODEDEPLOY_GROUP_NAME}
{
    "deploymentGroupInfo": {
        "applicationName": "h4b-app",
        "deploymentGroupId": "e6ad5cde-6789-42bd-8cad-23b5fedc7703",
        "deploymentGroupName": "Web",
        "deploymentConfigName": "CodeDeployDefault.AllAtOnce",
        "ec2TagFilters": [
            {
                "Key": "Name",
                "Value": "Web",
                "Type": "KEY_AND_VALUE"
            }
        ],
        "onPremisesInstanceTagFilters": [],
        "autoScalingGroups": [],
        "serviceRoleArn": "arn:aws:iam::999999999999:role/CodeDeployRole",
        "triggerConfigurations": [],
        "deploymentStyle": {
            "deploymentType": "IN_PLACE",
            "deploymentOption": "WITHOUT_TRAFFIC_CONTROL"
        },
        "outdatedInstancesStrategy": "UPDATE",
        "computePlatform": "Server",
        "terminationHookEnabled": false
    }
}

以降、Cloud9で実施

appspec.ymlの作成

コマンド
cat << EOF > src/appspec.yml
version: 0.0
os: linux
files:
  - source: index.html
    destination: /var/www/html/
EOF

出力
admin:~/environment/h4b-hands-on (master) $ cat << EOF > src/appspec.yml
> version: 0.0
> os: linux
> files:
>   - source: index.html
>     destination: /var/www/html/
> EOF

リポジトリの更新

コマンド
git add -A
git commit -m "fix."
git push origin master

出力
admin:~/environment/h4b-hands-on (master) $ git add -A
admin:~/environment/h4b-hands-on (master) $ git commit -m "fix."
[master 6457444] fix.
 3 files changed, 15 insertions(+)
 create mode 100644 buildspec.yaml
 create mode 100644 src/appspec.yml
 rename index.html => src/index.html (100%)
admin:~/environment/h4b-hands-on (master) $ git push origin master
Enumerating objects: 6, done.
Counting objects: 100% (6/6), done.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (5/5), 591 bytes | 591.00 KiB/s, done.
Total 5 (delta 0), reused 0 (delta 0), pack-reused 0
remote: Validating objects: 100%
To https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/h4b-hands-on
   8cb8648..6457444  master -> master

以降、CloudShellで実施

ビルドプロジェクトの開始

開始

コマンド
aws codebuild start-build \
    --project-name ${CODEBUILD_NAME} \
    --no-cli-pager

出力
[cloudshell-user@ip-10-132-76-170 ~]$ aws codebuild start-build \
>     --project-name ${CODEBUILD_NAME} \
>     --no-cli-pager
{
    "build": {
        "id": "h4b-hands-on:b0350b03-06ed-48f6-971d-dcbfa6ca8837",
        "arn": "arn:aws:codebuild:ap-northeast-1:999999999999:build/h4b-hands-on:b0350b03-06ed-48f6-971d-dcbfa6ca8837",
        "buildNumber": 1,
        "startTime": "2024-09-14T06:40:44.235000+00:00",
        "currentPhase": "QUEUED",
        "buildStatus": "IN_PROGRESS",
        "sourceVersion": "refs/heads/master",
        "projectName": "h4b-hands-on",
        "phases": [
            {
                "phaseType": "SUBMITTED",
                "phaseStatus": "SUCCEEDED",
                "startTime": "2024-09-14T06:40:44.235000+00:00",
                "endTime": "2024-09-14T06:40:44.307000+00:00",
                "durationInSeconds": 0
            },
            {
                "phaseType": "QUEUED",
                "startTime": "2024-09-14T06:40:44.307000+00:00"
            }
        ],
        "source": {
            "type": "CODECOMMIT",
            "location": "https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/h4b-hands-on",
            "gitCloneDepth": 1,
            "gitSubmodulesConfig": {
                "fetchSubmodules": false
            },
            "insecureSsl": false
        },
        "secondarySources": [],
        "secondarySourceVersions": [],
        "artifacts": {
            "location": "arn:aws:s3:::codebuild-h4b-hands-on-artifactstore/h4b-hands-on",
            "overrideArtifactName": false,
            "encryptionDisabled": false
        },
        "cache": {
            "type": "NO_CACHE"
        },
        "environment": {
            "type": "LINUX_CONTAINER",
            "image": "aws/codebuild/amazonlinux2-x86_64-standard:5.0",
            "computeType": "BUILD_GENERAL1_SMALL",
            "environmentVariables": [],
            "privilegedMode": false,
            "imagePullCredentialsType": "CODEBUILD"
        },
        "serviceRole": "arn:aws:iam::999999999999:role/service-role/codebuild-h4b-hands-on-service-role",
        "logs": {
            "deepLink": "https://console.aws.amazon.com/cloudwatch/home?region=ap-northeast-1#logsV2:log-groups",
            "cloudWatchLogsArn": "arn:aws:logs:ap-northeast-1:999999999999:log-group:null:log-stream:null",
            "cloudWatchLogs": {
                "status": "ENABLED"
            },
            "s3Logs": {
                "status": "DISABLED",
                "encryptionDisabled": false
            }
        },
        "timeoutInMinutes": 45,
        "queuedTimeoutInMinutes": 480,
        "buildComplete": false,
        "initiator": "admin",
        "encryptionKey": "arn:aws:kms:ap-northeast-1:999999999999:alias/aws/s3"
    }
}

ビルドの詳細を取得

コマンド
# 最近のビルドIDを取得
BUILD_ID=$(
    aws codebuild list-builds \
        --sort-order DESCENDING \
        --query 'ids[0]' \
        --output text
) \
&& echo ${BUILD_ID}

# ビルドの詳細を取得
aws codebuild batch-get-builds \
    --ids ${BUILD_ID} \
    --no-cli-pager

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # 最近のビルドIDを取得
[cloudshell-user@ip-10-132-76-170 ~]$ BUILD_ID=$(
>     aws codebuild list-builds \
>         --sort-order DESCENDING \
>         --query 'ids[0]' \
>         --output text
> ) \
> && echo ${BUILD_ID}
h4b-hands-on:b0350b03-06ed-48f6-971d-dcbfa6ca8837
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # ビルドの詳細を取得
[cloudshell-user@ip-10-132-76-170 ~]$ aws codebuild batch-get-builds \
>     --ids ${BUILD_ID} \
>     --no-cli-pager
{
    "builds": [
        {
            "id": "h4b-hands-on:b0350b03-06ed-48f6-971d-dcbfa6ca8837",
            "arn": "arn:aws:codebuild:ap-northeast-1:999999999999:build/h4b-hands-on:b0350b03-06ed-48f6-971d-dcbfa6ca8837",
            "buildNumber": 1,
            "startTime": "2024-09-14T06:40:44.235000+00:00",
            "currentPhase": "BUILD",
            "buildStatus": "IN_PROGRESS",
            "sourceVersion": "refs/heads/master",
            "resolvedSourceVersion": "64574445a2585cc5ccba54602b1c51c5dc14cdd5",
            "projectName": "h4b-hands-on",
            "phases": [
                {
                    "phaseType": "SUBMITTED",
                    "phaseStatus": "SUCCEEDED",
                    "startTime": "2024-09-14T06:40:44.235000+00:00",
                    "endTime": "2024-09-14T06:40:44.307000+00:00",
                    "durationInSeconds": 0
                },
                {
                    "phaseType": "QUEUED",
                    "phaseStatus": "SUCCEEDED",
                    "startTime": "2024-09-14T06:40:44.307000+00:00",
                    "endTime": "2024-09-14T06:40:45.057000+00:00",
                    "durationInSeconds": 0
                },
                {
                    "phaseType": "PROVISIONING",
                    "phaseStatus": "SUCCEEDED",
                    "startTime": "2024-09-14T06:40:45.057000+00:00",
                    "endTime": "2024-09-14T06:40:50.299000+00:00",
                    "durationInSeconds": 5,
                    "contexts": [
                        {
                            "statusCode": "",
                            "message": ""
                        }
                    ]
                },
                {
                    "phaseType": "DOWNLOAD_SOURCE",
                    "phaseStatus": "SUCCEEDED",
                    "startTime": "2024-09-14T06:40:50.299000+00:00",
                    "endTime": "2024-09-14T06:40:58.931000+00:00",
                    "durationInSeconds": 8,
                    "contexts": [
                        {
                            "statusCode": "",
                            "message": ""
                        }
                    ]
                },
                {
                    "phaseType": "INSTALL",
                    "phaseStatus": "SUCCEEDED",
                    "startTime": "2024-09-14T06:40:58.931000+00:00",
                    "endTime": "2024-09-14T06:40:58.985000+00:00",
                    "durationInSeconds": 0,
                    "contexts": [
                        {
                            "statusCode": "",
                            "message": ""
                        }
                    ]
                },
                {
                    "phaseType": "PRE_BUILD",
                    "phaseStatus": "SUCCEEDED",
                    "startTime": "2024-09-14T06:40:58.985000+00:00",
                    "endTime": "2024-09-14T06:40:59.031000+00:00",
                    "durationInSeconds": 0,
                    "contexts": [
                        {
                            "statusCode": "",
                            "message": ""
                        }
                    ]
                },
                {
                    "phaseType": "BUILD",
                    "startTime": "2024-09-14T06:40:59.031000+00:00"
                }
            ],
            "source": {
                "type": "CODECOMMIT",
                "location": "https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/h4b-hands-on",
                "gitCloneDepth": 1,
                "gitSubmodulesConfig": {
                    "fetchSubmodules": false
                },
                "insecureSsl": false
            },
            "secondarySources": [],
            "secondarySourceVersions": [],
            "artifacts": {
                "location": "arn:aws:s3:::codebuild-h4b-hands-on-artifactstore/h4b-hands-on",
                "overrideArtifactName": false,
                "encryptionDisabled": false
            },
            "cache": {
                "type": "NO_CACHE"
            },
            "environment": {
                "type": "LINUX_CONTAINER",
                "image": "aws/codebuild/amazonlinux2-x86_64-standard:5.0",
                "computeType": "BUILD_GENERAL1_SMALL",
                "environmentVariables": [],
                "privilegedMode": false,
                "imagePullCredentialsType": "CODEBUILD"
            },
            "serviceRole": "arn:aws:iam::999999999999:role/service-role/codebuild-h4b-hands-on-service-role",
            "logs": {
                "groupName": "/aws/codebuild/h4b-hands-on",
                "streamName": "b0350b03-06ed-48f6-971d-dcbfa6ca8837",
                "deepLink": "https://console.aws.amazon.com/cloudwatch/home?region=ap-northeast-1#logsV2:log-groups/log-group/$252Faws$252Fcodebuild$252Fh4b-hands-on/log-events/b0350b03-06ed-48f6-971d-dcbfa6ca8837",
                "cloudWatchLogsArn": "arn:aws:logs:ap-northeast-1:999999999999:log-group:/aws/codebuild/h4b-hands-on:log-stream:b0350b03-06ed-48f6-971d-dcbfa6ca8837",
                "cloudWatchLogs": {
                    "status": "ENABLED"
                },
                "s3Logs": {
                    "status": "DISABLED",
                    "encryptionDisabled": false
                }
            },
            "timeoutInMinutes": 45,
            "queuedTimeoutInMinutes": 480,
            "buildComplete": false,
            "initiator": "admin",
            "encryptionKey": "arn:aws:kms:ap-northeast-1:999999999999:alias/aws/s3"
        }
    ],
    "buildsNotFound": []
}

テールログの確認

コマンド
# ビルドログの確認
LOG_GROUP_NAME="/aws/codebuild/${CODEBUILD_NAME}" \
&& echo ${LOG_GROUP_NAME}

LOG_STREAM_NAME=$(
    aws logs describe-log-streams \
        --log-group-name ${LOG_GROUP_NAME} \
        --order-by LastEventTime \
        --descending \
        --limit 1 \
        --query 'logStreams[0].logStreamName' \
        --output text
) \
&& echo ${LOG_STREAM_NAME}

aws logs get-log-events \
    --log-group-name ${LOG_GROUP_NAME} \
    --log-stream-name ${LOG_STREAM_NAME} \
    --output text \
    --no-cli-pager

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # ビルドログの確認
[cloudshell-user@ip-10-132-76-170 ~]$ LOG_GROUP_NAME="/aws/codebuild/${CODEBUILD_NAME}" \
> && echo ${LOG_GROUP_NAME}
/aws/codebuild/h4b-hands-on
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ LOG_STREAM_NAME=$(
>     aws logs describe-log-streams \
>         --log-group-name ${LOG_GROUP_NAME} \
>         --order-by LastEventTime \
>         --descending \
>         --limit 1 \
>         --query 'logStreams[0].logStreamName' \
>         --output text
> ) \
> && echo ${LOG_STREAM_NAME}
b0350b03-06ed-48f6-971d-dcbfa6ca8837
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ aws logs get-log-events \
>     --log-group-name ${LOG_GROUP_NAME} \
>     --log-stream-name ${LOG_STREAM_NAME} \
>     --output text \
>     --no-cli-pager
b/38497688623292670323638309851495241895033887558412140544/s    f/38497688884835810012005458069591474214596368678172688409/s
EVENTS  1726296062364   [Container] 2024/09/14 06:40:50.109700 Running on CodeBuild On-demand
        1726296062332
EVENTS  1726296062364   [Container] 2024/09/14 06:40:50.109746 Waiting for agent ping
        1726296062332
EVENTS  1726296062364   [Container] 2024/09/14 06:40:50.311161 Waiting for DOWNLOAD_SOURCE
        1726296062332
EVENTS  1726296062364   [Container] 2024/09/14 06:40:58.273967 Phase is DOWNLOAD_SOURCE
        1726296062332
EVENTS  1726296062364   [Container] 2024/09/14 06:40:58.322286 CODEBUILD_SRC_DIR=/codebuild/output/src280942417/src/git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/h4b-hands-on
        1726296062332
EVENTS  1726296062364   [Container] 2024/09/14 06:40:58.322795 YAML location is /codebuild/output/src280942417/src/git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/h4b-hands-on/buildspec.yaml
        1726296062332
EVENTS  1726296062364   [Container] 2024/09/14 06:40:58.324406 Not setting HTTP client timeout for source type codecommit
        1726296062332
EVENTS  1726296062364   [Container] 2024/09/14 06:40:58.324610 Processing environment variables
        1726296062332
EVENTS  1726296062364   [Container] 2024/09/14 06:40:58.548234 No runtime version selected in buildspec.
        1726296062332
EVENTS  1726296062364   [Container] 2024/09/14 06:40:58.578527 Moving to directory /codebuild/output/src280942417/src/git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/h4b-hands-on
        1726296062332
EVENTS  1726296062364   [Container] 2024/09/14 06:40:58.581813 Unable to initialize cache download: no paths specified to be cached
        1726296062332
EVENTS  1726296062364   [Container] 2024/09/14 06:40:58.778875 Configuring ssm agent with target id: codebuild:b0350b03-06ed-48f6-971d-dcbfa6ca8837
        1726296062332
EVENTS  1726296062364   [Container] 2024/09/14 06:40:58.815424 Successfully updated ssm agent configuration
        1726296062332
EVENTS  1726296062364   [Container] 2024/09/14 06:40:58.815856 Registering with agent
        1726296062332
EVENTS  1726296062364   [Container] 2024/09/14 06:40:58.862897 Phases found in YAML: 1
        1726296062332
EVENTS  1726296062364   [Container] 2024/09/14 06:40:58.862922  BUILD: 1 commands
        1726296062332
EVENTS  1726296062364   [Container] 2024/09/14 06:40:58.863528 Phase complete: DOWNLOAD_SOURCE State: SUCCEEDED
        1726296062332
EVENTS  1726296062364   [Container] 2024/09/14 06:40:58.863552 Phase context status code:  Message: 
        1726296062332
EVENTS  1726296062364   [Container] 2024/09/14 06:40:58.952063 Entering phase INSTALL
        1726296062332
EVENTS  1726296062364   [Container] 2024/09/14 06:40:58.959279 Phase complete: INSTALL State: SUCCEEDED
        1726296062332
EVENTS  1726296062364   [Container] 2024/09/14 06:40:58.959309 Phase context status code:  Message: 
        1726296062332
EVENTS  1726296062364   [Container] 2024/09/14 06:40:59.003793 Entering phase PRE_BUILD
        1726296062332
EVENTS  1726296062364   [Container] 2024/09/14 06:40:59.007236 Phase complete: PRE_BUILD State: SUCCEEDED
        1726296062332
EVENTS  1726296062364   [Container] 2024/09/14 06:40:59.007255 Phase context status code:  Message: 
        1726296062332
EVENTS  1726296062364   [Container] 2024/09/14 06:40:59.049948 Entering phase BUILD
        1726296062332
EVENTS  1726296062364   [Container] 2024/09/14 06:40:59.094525 Running command aws deploy push --application-name h4b-app --s3-location s3://codebuild-h4b-hands-on-artifactstore/artifact.zip --source src
        1726296062332
EVENTS  1726296074081   To deploy with this revision, run:
        1726296074060
EVENTS  1726296074081   aws deploy create-deployment --application-name h4b-app --s3-location bucket=codebuild-h4b-hands-on-artifactstore,key=artifact.zip,bundleType=zip,eTag=8dc3595d7c932fd7bf4520d570e4dea5 --deployment-group-name <deployment-group-name> --deployment-config-name <deployment-config-name> --description <description>
        1726296074060
EVENTS  1726296074081
        1726296074060
EVENTS  1726296074081   [Container] 2024/09/14 06:41:13.560456 Phase complete: BUILD State: SUCCEEDED
        1726296074060
EVENTS  1726296074081   [Container] 2024/09/14 06:41:13.560478 Phase context status code:  Message: 
        1726296074060
EVENTS  1726296074081   [Container] 2024/09/14 06:41:13.594475 Entering phase POST_BUILD
        1726296074060
EVENTS  1726296074081   [Container] 2024/09/14 06:41:13.596228 Phase complete: POST_BUILD State: SUCCEEDED
        1726296074060
EVENTS  1726296074081   [Container] 2024/09/14 06:41:13.596246 Phase context status code:  Message: 
        1726296074060
EVENTS  1726296074081   [Container] 2024/09/14 06:41:13.694181 Expanding base directory path: src
        1726296074060
EVENTS  1726296074081   [Container] 2024/09/14 06:41:13.700155 Assembling file list
        1726296074060
EVENTS  1726296074081   [Container] 2024/09/14 06:41:13.700171 Expanding src
        1726296074060
EVENTS  1726296074081   [Container] 2024/09/14 06:41:13.705504 Expanding file paths for base directory src
        1726296074060
EVENTS  1726296074081   [Container] 2024/09/14 06:41:13.705517 Assembling file list
        1726296074060
EVENTS  1726296074081   [Container] 2024/09/14 06:41:13.705521 Expanding **/*
        1726296074060
EVENTS  1726296074081   [Container] 2024/09/14 06:41:13.710280 Found 2 file(s)
        1726296074060
EVENTS  1726296074081   [Container] 2024/09/14 06:41:13.711837 Set report auto-discover timeout to 5 seconds
        1726296074060
EVENTS  1726296074081   [Container] 2024/09/14 06:41:13.711867 Expanding base directory path:  .
        1726296074060
EVENTS  1726296074081   [Container] 2024/09/14 06:41:13.716154 Assembling file list
        1726296074060
EVENTS  1726296074081   [Container] 2024/09/14 06:41:13.716167 Expanding .
        1726296074060
EVENTS  1726296074081   [Container] 2024/09/14 06:41:13.720291 Expanding file paths for base directory .
        1726296074060
EVENTS  1726296074081   [Container] 2024/09/14 06:41:13.720304 Assembling file list
        1726296074060
EVENTS  1726296074081   [Container] 2024/09/14 06:41:13.720308 Expanding **/*
        1726296074060
EVENTS  1726296074081   [Container] 2024/09/14 06:41:13.723792 No matching auto-discover report paths found
        1726296074060
EVENTS  1726296074081   [Container] 2024/09/14 06:41:13.723810 Report auto-discover file discovery took 0.011973 seconds
        1726296074060
EVENTS  1726296074081   [Container] 2024/09/14 06:41:13.723826 Phase complete: UPLOAD_ARTIFACTS State: SUCCEEDED
        1726296074060
EVENTS  1726296074081   [Container] 2024/09/14 06:41:13.723834 Phase context status code:  Message: 
        1726296074060

07 EC2 インスタンスをデプロイ先とした、CI/CD 環境を構築する【CodePipeline 編】

変数

コマンド
# パイプライン名
PIPELINE_2_NAME="h4b-hands-on-ec2" \
&& echo ${PIPELINE_2_NAME}

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # パイプライン名
[cloudshell-user@ip-10-132-76-170 ~]$ PIPELINE_2_NAME="h4b-hands-on-ec2" \
> && echo ${PIPELINE_2_NAME}
h4b-hands-on-ec2

パイプライン定義ファイル

コマンド
# パイプライン定義ファイル
PIPELINE_2_JSON=$(cat << EOF
{
    "pipeline": {
        "name": "${PIPELINE_2_NAME}",
        "roleArn": "${PIPELINE_IAM_ROLE_ARN}",
        "artifactStore": {
            "type": "S3",
            "location": "${ARTIFACTSTORE_BUCKET_NAME}"
        },
        "stages": [
            {
                "name": "Source",
                "actions": [
                    {
                        "name": "Source",
                        "actionTypeId": {
                            "category": "Source",
                            "owner": "AWS",
                            "provider": "CodeCommit",
                            "version": "1"
                        },
                        "runOrder": 1,
                        "configuration": {
                            "BranchName": "master",
                            "OutputArtifactFormat": "CODE_ZIP",
                            "PollForSourceChanges": "false",
                            "RepositoryName": "${REPOSITORY_NAME}"
                        },
                        "outputArtifacts": [
                            {
                                "name": "SourceArtifact"
                            }
                        ],
                        "inputArtifacts": [],
                        "region": "ap-northeast-1",
                        "namespace": "SourceVariables"
                    }
                ]
            },
            {
                "name": "Build",
                "actions": [
                    {
                        "name": "Build",
                        "actionTypeId": {
                            "category": "Build",
                            "owner": "AWS",
                            "provider": "CodeBuild",
                            "version": "1"
                        },
                        "runOrder": 1,
                        "configuration": {
                            "ProjectName": "${CODEBUILD_NAME}"
                        },
                        "outputArtifacts": [
                            {
                                "name": "BuildArtifact"
                            }
                        ],
                        "inputArtifacts": [
                            {
                                "name": "SourceArtifact"
                            }
                        ],
                        "region": "ap-northeast-1",
                        "namespace": "BuildVariables"
                    }
                ]
            },
            {
                "name": "Deploy",
                "actions": [
                    {
                        "name": "Deploy",
                        "actionTypeId": {
                            "category": "Deploy",
                            "owner": "AWS",
                            "provider": "CodeDeploy",
                            "version": "1"
                        },
                        "runOrder": 1,
                        "configuration": {
                            "ApplicationName": "${CODEDEPLOY_APP_NAME}",
                            "DeploymentGroupName": "${CODEDEPLOY_GROUP_NAME}"
                        },
                        "outputArtifacts": [],
                        "inputArtifacts": [
                            {
                                "name": "BuildArtifact"
                            }
                        ],
                        "region": "ap-northeast-1",
                        "namespace": "DeployVariables"
                    }
                ]
            }
        ],
        "version": 1,
        "executionMode": "QUEUED",
        "pipelineType": "V2"
    }
}
EOF
) \
&& echo ${PIPELINE_2_JSON}

# JSONフォーマットの確認
echo ${PIPELINE_2_JSON} | python -m json.tool

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # パイプライン定義ファイル
[cloudshell-user@ip-10-132-76-170 ~]$ PIPELINE_2_JSON=$(cat << EOF
> {
>     "pipeline": {
>         "name": "${PIPELINE_2_NAME}",
>         "roleArn": "${PIPELINE_IAM_ROLE_ARN}",
>         "artifactStore": {
>             "type": "S3",
>             "location": "${ARTIFACTSTORE_BUCKET_NAME}"
>         },
>         "stages": [
>             {
>                 "name": "Source",
>                 "actions": [
>                     {
>                         "name": "Source",
>                         "actionTypeId": {
>                             "category": "Source",
>                             "owner": "AWS",
>                             "provider": "CodeCommit",
>                             "version": "1"
>                         },
>                         "runOrder": 1,
>                         "configuration": {
>                             "BranchName": "master",
>                             "OutputArtifactFormat": "CODE_ZIP",
>                             "PollForSourceChanges": "false",
>                             "RepositoryName": "${REPOSITORY_NAME}"
>                         },
>                         "outputArtifacts": [
>                             {
>                                 "name": "SourceArtifact"
>                             }
>                         ],
>                         "inputArtifacts": [],
>                         "region": "ap-northeast-1",
>                         "namespace": "SourceVariables"
>                     }
>                 ]
>             },
>             {
>                 "name": "Build",
>                 "actions": [
>                     {
>                         "name": "Build",
>                         "actionTypeId": {
>                             "category": "Build",
>                             "owner": "AWS",
>                             "provider": "CodeBuild",
>                             "version": "1"
>                         },
>                         "runOrder": 1,
>                         "configuration": {
>                             "ProjectName": "${CODEBUILD_NAME}"
>                         },
>                         "outputArtifacts": [
>                             {
>                                 "name": "BuildArtifact"
>                             }
>                         ],
>                         "inputArtifacts": [
>                             {
>                                 "name": "SourceArtifact"
>                             }
>                         ],
>                         "region": "ap-northeast-1",
>                         "namespace": "BuildVariables"
>                     }
>                 ]
>             },
>             {
>                 "name": "Deploy",
>                 "actions": [
>                     {
>                         "name": "Deploy",
>                         "actionTypeId": {
>                             "category": "Deploy",
>                             "owner": "AWS",
>                             "provider": "CodeDeploy",
>                             "version": "1"
>                         },
>                         "runOrder": 1,
>                         "configuration": {
>                             "ApplicationName": "${CODEDEPLOY_APP_NAME}",
>                             "DeploymentGroupName": "${CODEDEPLOY_GROUP_NAME}"
>                         },
>                         "outputArtifacts": [],
>                         "inputArtifacts": [
>                             {
>                                 "name": "BuildArtifact"
>                             }
>                         ],
>                         "region": "ap-northeast-1",
>                         "namespace": "DeployVariables"
>                     }
>                 ]
>             }
>         ],
>         "version": 1,
>         "executionMode": "QUEUED",
>         "pipelineType": "V2"
>     }
> }
> EOF
> ) \
> && echo ${PIPELINE_2_JSON}
{ "pipeline": { "name": "h4b-hands-on-ec2", "roleArn": "arn:aws:iam::999999999999:role/service-role/AWSCodePipelineServiceRole-ap-northeast-1", "artifactStore": { "type": "S3", "location": "codepipeline-ap-northeast-1-artifactstore-20240914" }, "stages": [ { "name": "Source", "actions": [ { "name": "Source", "actionTypeId": { "category": "Source", "owner": "AWS", "provider": "CodeCommit", "version": "1" }, "runOrder": 1, "configuration": { "BranchName": "master", "OutputArtifactFormat": "CODE_ZIP", "PollForSourceChanges": "false", "RepositoryName": "h4b-hands-on" }, "outputArtifacts": [ { "name": "SourceArtifact" } ], "inputArtifacts": [], "region": "ap-northeast-1", "namespace": "SourceVariables" } ] }, { "name": "Build", "actions": [ { "name": "Build", "actionTypeId": { "category": "Build", "owner": "AWS", "provider": "CodeBuild", "version": "1" }, "runOrder": 1, "configuration": { "ProjectName": "h4b-hands-on" }, "outputArtifacts": [ { "name": "BuildArtifact" } ], "inputArtifacts": [ { "name": "SourceArtifact" } ], "region": "ap-northeast-1", "namespace": "BuildVariables" } ] }, { "name": "Deploy", "actions": [ { "name": "Deploy", "actionTypeId": { "category": "Deploy", "owner": "AWS", "provider": "CodeDeploy", "version": "1" }, "runOrder": 1, "configuration": { "ApplicationName": "h4b-app", "DeploymentGroupName": "Web" }, "outputArtifacts": [], "inputArtifacts": [ { "name": "BuildArtifact" } ], "region": "ap-northeast-1", "namespace": "DeployVariables" } ] } ], "version": 1, "executionMode": "QUEUED", "pipelineType": "V2" } }
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-132-76-170 ~]$ echo ${PIPELINE_2_JSON} | python -m json.tool
{
    "pipeline": {
        "name": "h4b-hands-on-ec2",
        "roleArn": "arn:aws:iam::999999999999:role/service-role/AWSCodePipelineServiceRole-ap-northeast-1",
        "artifactStore": {
            "type": "S3",
            "location": "codepipeline-ap-northeast-1-artifactstore-20240914"
        },
        "stages": [
            {
                "name": "Source",
                "actions": [
                    {
                        "name": "Source",
                        "actionTypeId": {
                            "category": "Source",
                            "owner": "AWS",
                            "provider": "CodeCommit",
                            "version": "1"
                        },
                        "runOrder": 1,
                        "configuration": {
                            "BranchName": "master",
                            "OutputArtifactFormat": "CODE_ZIP",
                            "PollForSourceChanges": "false",
                            "RepositoryName": "h4b-hands-on"
                        },
                        "outputArtifacts": [
                            {
                                "name": "SourceArtifact"
                            }
                        ],
                        "inputArtifacts": [],
                        "region": "ap-northeast-1",
                        "namespace": "SourceVariables"
                    }
                ]
            },
            {
                "name": "Build",
                "actions": [
                    {
                        "name": "Build",
                        "actionTypeId": {
                            "category": "Build",
                            "owner": "AWS",
                            "provider": "CodeBuild",
                            "version": "1"
                        },
                        "runOrder": 1,
                        "configuration": {
                            "ProjectName": "h4b-hands-on"
                        },
                        "outputArtifacts": [
                            {
                                "name": "BuildArtifact"
                            }
                        ],
                        "inputArtifacts": [
                            {
                                "name": "SourceArtifact"
                            }
                        ],
                        "region": "ap-northeast-1",
                        "namespace": "BuildVariables"
                    }
                ]
            },
            {
                "name": "Deploy",
                "actions": [
                    {
                        "name": "Deploy",
                        "actionTypeId": {
                            "category": "Deploy",
                            "owner": "AWS",
                            "provider": "CodeDeploy",
                            "version": "1"
                        },
                        "runOrder": 1,
                        "configuration": {
                            "ApplicationName": "h4b-app",
                            "DeploymentGroupName": "Web"
                        },
                        "outputArtifacts": [],
                        "inputArtifacts": [
                            {
                                "name": "BuildArtifact"
                            }
                        ],
                        "region": "ap-northeast-1",
                        "namespace": "DeployVariables"
                    }
                ]
            }
        ],
        "version": 1,
        "executionMode": "QUEUED",
        "pipelineType": "V2"
    }
}

パイプラインの作成

作成

コマンド
aws codepipeline create-pipeline \
    --cli-input-json "${PIPELINE_2_JSON}" \
    --no-cli-pager

# ARN取得
PIPELINE_2_ARN=$(
    aws codepipeline get-pipeline \
        --name ${PIPELINE_2_NAME} \
        --query metadata.pipelineArn \
        --output text
) \
&& echo ${PIPELINE_2_ARN}

出力
[cloudshell-user@ip-10-132-76-170 ~]$ aws codepipeline create-pipeline \
>     --cli-input-json "${PIPELINE_2_JSON}" \
>     --no-cli-pager
{
    "pipeline": {
        "name": "h4b-hands-on-ec2",
        "roleArn": "arn:aws:iam::999999999999:role/service-role/AWSCodePipelineServiceRole-ap-northeast-1",
        "artifactStore": {
            "type": "S3",
            "location": "codepipeline-ap-northeast-1-artifactstore-20240914"
        },
        "stages": [
            {
                "name": "Source",
                "actions": [
                    {
                        "name": "Source",
                        "actionTypeId": {
                            "category": "Source",
                            "owner": "AWS",
                            "provider": "CodeCommit",
                            "version": "1"
                        },
                        "runOrder": 1,
                        "configuration": {
                            "BranchName": "master",
                            "OutputArtifactFormat": "CODE_ZIP",
                            "PollForSourceChanges": "false",
                            "RepositoryName": "h4b-hands-on"
                        },
                        "outputArtifacts": [
                            {
                                "name": "SourceArtifact"
                            }
                        ],
                        "inputArtifacts": [],
                        "region": "ap-northeast-1",
                        "namespace": "SourceVariables"
                    }
                ]
            },
            {
                "name": "Build",
                "actions": [
                    {
                        "name": "Build",
                        "actionTypeId": {
                            "category": "Build",
                            "owner": "AWS",
                            "provider": "CodeBuild",
                            "version": "1"
                        },
                        "runOrder": 1,
                        "configuration": {
                            "ProjectName": "h4b-hands-on"
                        },
                        "outputArtifacts": [
                            {
                                "name": "BuildArtifact"
                            }
                        ],
                        "inputArtifacts": [
                            {
                                "name": "SourceArtifact"
                            }
                        ],
                        "region": "ap-northeast-1",
                        "namespace": "BuildVariables"
                    }
                ]
            },
            {
                "name": "Deploy",
                "actions": [
                    {
                        "name": "Deploy",
                        "actionTypeId": {
                            "category": "Deploy",
                            "owner": "AWS",
                            "provider": "CodeDeploy",
                            "version": "1"
                        },
                        "runOrder": 1,
                        "configuration": {
                            "ApplicationName": "h4b-app",
                            "DeploymentGroupName": "Web"
                        },
                        "outputArtifacts": [],
                        "inputArtifacts": [
                            {
                                "name": "BuildArtifact"
                            }
                        ],
                        "region": "ap-northeast-1",
                        "namespace": "DeployVariables"
                    }
                ]
            }
        ],
        "version": 1,
        "executionMode": "QUEUED",
        "pipelineType": "V2"
    }
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # ARN取得
[cloudshell-user@ip-10-132-76-170 ~]$ PIPELINE_2_ARN=$(
>     aws codepipeline get-pipeline \
>         --name ${PIPELINE_2_NAME} \
>         --query metadata.pipelineArn \
>         --output text
> ) \
> && echo ${PIPELINE_2_ARN}
arn:aws:codepipeline:ap-northeast-1:999999999999:h4b-hands-on-ec2

確認

コマンド
# 詳細確認
aws codepipeline get-pipeline \
    --name ${PIPELINE_2_NAME} \
    --no-cli-pager

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # 詳細確認
[cloudshell-user@ip-10-132-76-170 ~]$ aws codepipeline get-pipeline \
>     --name ${PIPELINE_2_NAME} \
>     --no-cli-pager
{
    "pipeline": {
        "name": "h4b-hands-on-ec2",
        "roleArn": "arn:aws:iam::999999999999:role/service-role/AWSCodePipelineServiceRole-ap-northeast-1",
        "artifactStore": {
            "type": "S3",
            "location": "codepipeline-ap-northeast-1-artifactstore-20240914"
        },
        "stages": [
            {
                "name": "Source",
                "actions": [
                    {
                        "name": "Source",
                        "actionTypeId": {
                            "category": "Source",
                            "owner": "AWS",
                            "provider": "CodeCommit",
                            "version": "1"
                        },
                        "runOrder": 1,
                        "configuration": {
                            "BranchName": "master",
                            "OutputArtifactFormat": "CODE_ZIP",
                            "PollForSourceChanges": "false",
                            "RepositoryName": "h4b-hands-on"
                        },
                        "outputArtifacts": [
                            {
                                "name": "SourceArtifact"
                            }
                        ],
                        "inputArtifacts": [],
                        "region": "ap-northeast-1",
                        "namespace": "SourceVariables"
                    }
                ]
            },
            {
                "name": "Build",
                "actions": [
                    {
                        "name": "Build",
                        "actionTypeId": {
                            "category": "Build",
                            "owner": "AWS",
                            "provider": "CodeBuild",
                            "version": "1"
                        },
                        "runOrder": 1,
                        "configuration": {
                            "ProjectName": "h4b-hands-on"
                        },
                        "outputArtifacts": [
                            {
                                "name": "BuildArtifact"
                            }
                        ],
                        "inputArtifacts": [
                            {
                                "name": "SourceArtifact"
                            }
                        ],
                        "region": "ap-northeast-1",
                        "namespace": "BuildVariables"
                    }
                ]
            },
            {
                "name": "Deploy",
                "actions": [
                    {
                        "name": "Deploy",
                        "actionTypeId": {
                            "category": "Deploy",
                            "owner": "AWS",
                            "provider": "CodeDeploy",
                            "version": "1"
                        },
                        "runOrder": 1,
                        "configuration": {
                            "ApplicationName": "h4b-app",
                            "DeploymentGroupName": "Web"
                        },
                        "outputArtifacts": [],
                        "inputArtifacts": [
                            {
                                "name": "BuildArtifact"
                            }
                        ],
                        "region": "ap-northeast-1",
                        "namespace": "DeployVariables"
                    }
                ]
            }
        ],
        "version": 1,
        "executionMode": "QUEUED",
        "pipelineType": "V2"
    },
    "metadata": {
        "pipelineArn": "arn:aws:codepipeline:ap-northeast-1:999999999999:h4b-hands-on-ec2",
        "created": "2024-09-14T05:18:39.488000+00:00",
        "updated": "2024-09-14T05:18:39.488000+00:00"
    }
}

EventBridge

IAM

コマンド
# ポリシー名
EVENT_IAM_POLICY_2_NAME="start-pipeline-execution-${REGION}-${PIPELINE_2_NAME}" \
&& echo ${EVENT_IAM_POLICY_2_NAME}

# ロール名
EVENT_IAM_ROLE_2_NAME="cwe-role-${REGION}-${PIPELINE_2_NAME}" \
&& echo ${EVENT_IAM_ROLE_2_NAME}

# IAMパス
IAM_PATH="/service-role/" \
&& echo ${IAM_PATH}

# IAMポリシー
POLICY_DOCUMENT_JSON=$(cat << EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "codepipeline:StartPipelineExecution"
            ],
            "Resource": [
                "${PIPELINE_2_ARN}"
            ]
        }
    ]
}
EOF
) \
&& echo ${POLICY_DOCUMENT_JSON}

# JSONフォーマットの確認
echo ${POLICY_DOCUMENT_JSON} | python -m json.tool

# ポリシーの作成
aws iam create-policy \
    --policy-name ${EVENT_IAM_POLICY_2_NAME} \
    --path ${IAM_PATH} \
    --policy-document "${POLICY_DOCUMENT_JSON}"

# ARN取得
EVENT_IAM_POLICY_2_ARN=$(
    aws iam list-policies \
        --query "Policies[?PolicyName=='${EVENT_IAM_POLICY_2_NAME}'].Arn" \
        --output text
) \
&& echo ${EVENT_IAM_POLICY_2_ARN}

# 信頼関係ポリシードキュメントの作成
ASSUME_ROLE_POLICY_DOCUMENT=$(cat << EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "events.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
EOF
) \
&& echo ${ASSUME_ROLE_POLICY_DOCUMENT}

# JSONフォーマットの確認
echo ${ASSUME_ROLE_POLICY_DOCUMENT} | python -m json.tool

# IAMロールの作成
aws iam create-role \
    --path ${IAM_PATH} \
    --role-name ${EVENT_IAM_ROLE_2_NAME} \
    --assume-role-policy-document "${ASSUME_ROLE_POLICY_DOCUMENT}"

# ARN取得
EVENT_IAM_ROLE_2_ARN=$(
    aws iam get-role \
        --role-name ${EVENT_IAM_ROLE_2_NAME} \
        --query 'Role.Arn' --output text
) \
&& echo ${EVENT_IAM_ROLE_2_ARN}

# IAMロールにポリシーをアタッチ
aws iam attach-role-policy \
    --role-name ${EVENT_IAM_ROLE_2_NAME} \
    --policy-arn ${EVENT_IAM_POLICY_2_ARN}

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # ポリシー名
[cloudshell-user@ip-10-132-76-170 ~]$ EVENT_IAM_POLICY_2_NAME="start-pipeline-execution-${REGION}-${PIPELINE_2_NAME}" \
> && echo ${EVENT_IAM_POLICY_2_NAME}
start-pipeline-execution-ap-northeast-1-h4b-hands-on-ec2
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # ロール名
[cloudshell-user@ip-10-132-76-170 ~]$ EVENT_IAM_ROLE_2_NAME="cwe-role-${REGION}-${PIPELINE_2_NAME}" \
> && echo ${EVENT_IAM_ROLE_2_NAME}
cwe-role-ap-northeast-1-h4b-hands-on-ec2
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # IAMパス
[cloudshell-user@ip-10-132-76-170 ~]$ IAM_PATH="/service-role/" \
> && echo ${IAM_PATH}
/service-role/
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # IAMポリシー
[cloudshell-user@ip-10-132-76-170 ~]$ POLICY_DOCUMENT_JSON=$(cat << EOF
> {
>     "Version": "2012-10-17",
>     "Statement": [
>         {
>             "Effect": "Allow",
>             "Action": [
>                 "codepipeline:StartPipelineExecution"
>             ],
>             "Resource": [
>                 "${PIPELINE_2_ARN}"
>             ]
>         }
>     ]
> }
> EOF
> ) \
> && echo ${POLICY_DOCUMENT_JSON}
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "codepipeline:StartPipelineExecution" ], "Resource": [ "arn:aws:codepipeline:ap-northeast-1:999999999999:h4b-hands-on-ec2" ] } ] }
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-132-76-170 ~]$ echo ${POLICY_DOCUMENT_JSON} | python -m json.tool
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "codepipeline:StartPipelineExecution"
            ],
            "Resource": [
                "arn:aws:codepipeline:ap-northeast-1:999999999999:h4b-hands-on-ec2"
            ]
        }
    ]
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # ポリシーの作成
[cloudshell-user@ip-10-132-76-170 ~]$ aws iam create-policy \
>     --policy-name ${EVENT_IAM_POLICY_2_NAME} \
>     --path ${IAM_PATH} \
>     --policy-document "${POLICY_DOCUMENT_JSON}"
{
    "Policy": {
        "PolicyName": "start-pipeline-execution-ap-northeast-1-h4b-hands-on-ec2",
        "PolicyId": "ANPAWFKRCMKO22BJUS675",
        "Arn": "arn:aws:iam::999999999999:policy/service-role/start-pipeline-execution-ap-northeast-1-h4b-hands-on-ec2",
        "Path": "/service-role/",
        "DefaultVersionId": "v1",
        "AttachmentCount": 0,
        "PermissionsBoundaryUsageCount": 0,
        "IsAttachable": true,
        "CreateDate": "2024-09-14T06:44:49+00:00",
        "UpdateDate": "2024-09-14T06:44:49+00:00"
    }
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # ARN取得
[cloudshell-user@ip-10-132-76-170 ~]$ EVENT_IAM_POLICY_2_ARN=$(
>     aws iam list-policies \
>         --query "Policies[?PolicyName=='${EVENT_IAM_POLICY_2_NAME}'].Arn" \
>         --output text
> ) \
> && echo ${EVENT_IAM_POLICY_2_ARN}
arn:aws:iam::999999999999:policy/service-role/start-pipeline-execution-ap-northeast-1-h4b-hands-on-ec2
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # 信頼関係ポリシードキュメントの作成
[cloudshell-user@ip-10-132-76-170 ~]$ ASSUME_ROLE_POLICY_DOCUMENT=$(cat << EOF
> {
>     "Version": "2012-10-17",
>     "Statement": [
>         {
>             "Effect": "Allow",
>             "Principal": {
>                 "Service": "events.amazonaws.com"
>             },
>             "Action": "sts:AssumeRole"
>         }
>     ]
> }
> EOF
> ) \
> && echo ${ASSUME_ROLE_POLICY_DOCUMENT}
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "events.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-132-76-170 ~]$ echo ${ASSUME_ROLE_POLICY_DOCUMENT} | python -m json.tool
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "events.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # IAMロールの作成
[cloudshell-user@ip-10-132-76-170 ~]$ aws iam create-role \
>     --path ${IAM_PATH} \
>     --role-name ${EVENT_IAM_ROLE_2_NAME} \
>     --assume-role-policy-document "${ASSUME_ROLE_POLICY_DOCUMENT}"
{
    "Role": {
        "Path": "/service-role/",
        "RoleName": "cwe-role-ap-northeast-1-h4b-hands-on-ec2",
        "RoleId": "AROAWFKRCMKOVH6HPI7VL",
        "Arn": "arn:aws:iam::999999999999:role/service-role/cwe-role-ap-northeast-1-h4b-hands-on-ec2",
        "CreateDate": "2024-09-14T06:47:18+00:00",
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Effect": "Allow",
                    "Principal": {
                        "Service": "events.amazonaws.com"
                    },
                    "Action": "sts:AssumeRole"
                }
            ]
        }
    }
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # ARN取得
[cloudshell-user@ip-10-132-76-170 ~]$ EVENT_IAM_ROLE_2_ARN=$(
>     aws iam get-role \
>         --role-name ${EVENT_IAM_ROLE_2_NAME} \
>         --query 'Role.Arn' --output text
> ) \
> && echo ${EVENT_IAM_ROLE_2_ARN}
arn:aws:iam::999999999999:role/service-role/cwe-role-ap-northeast-1-h4b-hands-on-ec2
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # IAMロールにポリシーをアタッチ
[cloudshell-user@ip-10-132-76-170 ~]$ aws iam attach-role-policy \
>     --role-name ${EVENT_IAM_ROLE_2_NAME} \
>     --policy-arn ${EVENT_IAM_POLICY_2_ARN}

ルール作成

コマンド
# ルール名
EVENTS_RULE_2_NAME="codepipeline-${PIPELINE_2_NAME}-rule" \
&& echo ${EVENTS_RULE_2_NAME}

# ルール
aws events put-rule \
    --name "${EVENTS_RULE_2_NAME}" \
    --event-pattern "${EVENT_PATTERN_JSON}" \
    --role-arn "${EVENT_IAM_ROLE_ARN}"

# ターゲット
aws events put-targets \
    --rule ${EVENTS_RULE_2_NAME} \
    --targets Id="codepipeline-${PIPELINE_2_NAME}",Arn="${PIPELINE_2_ARN}",RoleArn="${EVENT_IAM_ROLE_2_ARN}"

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # ルール名
[cloudshell-user@ip-10-132-76-170 ~]$ EVENTS_RULE_2_NAME="codepipeline-${PIPELINE_2_NAME}-rule" \
> && echo ${EVENTS_RULE_2_NAME}
codepipeline-h4b-hands-on-ec2-rule
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # ルール
[cloudshell-user@ip-10-132-76-170 ~]$ aws events put-rule \
>     --name "${EVENTS_RULE_2_NAME}" \
>     --event-pattern "${EVENT_PATTERN_JSON}" \
>     --role-arn "${EVENT_IAM_ROLE_ARN}"
{
    "RuleArn": "arn:aws:events:ap-northeast-1:999999999999:rule/codepipeline-h4b-hands-on-ec2-rule"
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # ターゲット
[cloudshell-user@ip-10-132-76-170 ~]$ aws events put-targets \
>     --rule ${EVENTS_RULE_2_NAME} \
>     --targets Id="codepipeline-${PIPELINE_2_NAME}",Arn="${PIPELINE_2_ARN}",RoleArn="${EVENT_IAM_ROLE_2_ARN}"
{
    "FailedEntryCount": 0,
    "FailedEntries": []
}

以降、Cloud9で実施

index.htmlの更新

コマンド
cat << EOF > src/index.html
<!DOCTYPE html>

<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>S3 Static Web Hosting</title>
</head>
<body>
  Hello, AWS Code* World!! :)
</body>
</html>
EOF

出力
admin:~/environment/h4b-hands-on (master) $ cat << EOF > src/index.html
> <!DOCTYPE html>
> 
> <html lang="ja">
> <head>
>   <meta charset="utf-8">
>   <title>S3 Static Web Hosting</title>
> </head>
> <body>
>   Hello, AWS Code* World!! :)
> </body>
> </html>
> EOF

リポジトリの更新

コマンド
git add -A
git commit -m "fix."
git push origin master

出力
admin:~/environment/h4b-hands-on (master) $ git add -A
admin:~/environment/h4b-hands-on (master) $ git commit -m "fix."
[master 3f86091] fix.
 1 file changed, 1 insertion(+), 1 deletion(-)
admin:~/environment/h4b-hands-on (master) $ git push origin master
Enumerating objects: 7, done.
Counting objects: 100% (7/7), done.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 398 bytes | 398.00 KiB/s, done.
Total 4 (delta 1), reused 0 (delta 0), pack-reused 0
remote: Validating objects: 100%
To https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/h4b-hands-on
   6457444..3f86091  master -> master

以降、CloudShellで実施

アクセス確認

コマンド
curl ${EC2_PUBLIC_IP}

出力
[cloudshell-user@ip-10-132-76-170 ~]$ curl ${EC2_PUBLIC_IP}
<!DOCTYPE html>

<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>S3 Static Web Hosting</title>
</head>
<body>
  Hello, AWS Code* World!! :)
</body>
</html

08 削除手順の紹介、本シリーズのまとめ、Next Step のご案内

Cloud9

コマンド
aws cloud9 delete-environment \
    --environment-id ${CLOUD9_ENVIRONMENT_ID}

出力
[cloudshell-user@ip-10-132-76-170 ~]$ aws cloud9 delete-environment \
>     --environment-id ${CLOUD9_ENVIRONMENT_ID}

EC2

インスタンス

コマンド
# インスタンス
aws ec2 terminate-instances \
    --instance-ids ${EC2_INSTANCE_ID} 

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # インスタンス
[cloudshell-user@ip-10-132-76-170 ~]$ aws ec2 terminate-instances \
>     --instance-ids ${EC2_INSTANCE_ID} 
{
    "TerminatingInstances": [
        {
            "CurrentState": {
                "Code": 32,
                "Name": "shutting-down"
            },
            "InstanceId": "i-02a25fbe53f00866b",
            "PreviousState": {
                "Code": 16,
                "Name": "running"
            }
        }
    ]
}

以下、インスタンス削除後に実施 (約2分)

SG

コマンド
# セキュリティグループ
aws ec2 delete-security-group \
    --group-id ${EC2_SG_ID}

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # セキュリティグループ
[cloudshell-user@ip-10-132-76-170 ~]$ aws ec2 delete-security-group \
>     --group-id ${EC2_SG_ID}

CodePipeline

コマンド
# CodePipeline削除
aws codepipeline delete-pipeline \
    --name ${PIPELINE_NAME}

aws codepipeline delete-pipeline \
    --name ${PIPELINE_2_NAME}

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # CodePipeline削除
[cloudshell-user@ip-10-132-76-170 ~]$ aws codepipeline delete-pipeline \
>     --name ${PIPELINE_NAME}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ aws codepipeline delete-pipeline \
>     --name ${PIPELINE_2_NAME}

CodeCommit

コマンド
# CodeCommitリポジトリ削除
aws codecommit delete-repository \
    --repository-name ${REPOSITORY_NAME}

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # CodeCommitリポジトリ削除
[cloudshell-user@ip-10-132-76-170 ~]$ aws codecommit delete-repository \
>     --repository-name ${REPOSITORY_NAME}
{
    "repositoryId": "944f7933-79af-41e8-a9af-35db1f7d0324"
}

CodeBuild

コマンド
# プロジェクト
aws codebuild delete-project \
    --name ${CODEBUILD_NAME}

出力
cloudshell-user@ip-10-132-76-170 ~]$ # プロジェクト
[cloudshell-user@ip-10-132-76-170 ~]$ aws codebuild delete-project \
>     --name ${CODEBUILD_NAME}

CodeDeploy

コマンド
# デプロイグループ
aws deploy delete-deployment-group \
    --application-name ${CODEDEPLOY_APP_NAME} \
    --deployment-group-name ${CODEDEPLOY_GROUP_NAME}

# アプリケーション
aws deploy delete-application \
    --application-name ${CODEDEPLOY_APP_NAME}

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # デプロイグループ
[cloudshell-user@ip-10-132-76-170 ~]$ aws deploy delete-deployment-group \
>     --application-name ${CODEDEPLOY_APP_NAME} \
>     --deployment-group-name ${CODEDEPLOY_GROUP_NAME}
{
    "hooksNotCleanedUp": []
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # アプリケーション
[cloudshell-user@ip-10-132-76-170 ~]$ aws deploy delete-application \
>     --application-name ${CODEDEPLOY_APP_NAME}

S3

コマンド
# オブジェクト一覧取得
OBJECT_LIST=$(
    aws s3api list-object-versions \
        --bucket ${S3_BUCKET_NAME} \
        --query='{Objects: Versions[].{Key:Key,VersionId:VersionId}}'
) \
&& echo ${OBJECT_LIST}

# JSONフォーマットの確認
echo ${OBJECT_LIST} | python -m json.tool

# バケットを空にする
aws s3api delete-objects \
    --bucket ${S3_BUCKET_NAME} \
    --delete "${OBJECT_LIST}"

# S3バケットを削除
aws s3api delete-bucket \
    --bucket ${S3_BUCKET_NAME}

# オブジェクト一覧取得
OBJECT_LIST=$(
    aws s3api list-object-versions \
        --bucket ${ARTIFACTSTORE_BUCKET_NAME} \
        --query='{Objects: Versions[].{Key:Key,VersionId:VersionId}}'
) \
&& echo ${OBJECT_LIST}

# JSONフォーマットの確認
echo ${OBJECT_LIST} | python -m json.tool

# バケットを空にする
aws s3api delete-objects \
    --bucket ${ARTIFACTSTORE_BUCKET_NAME} \
    --delete "${OBJECT_LIST}"

# S3バケットを削除
aws s3api delete-bucket \
    --bucket ${ARTIFACTSTORE_BUCKET_NAME}

# オブジェクト一覧取得
OBJECT_LIST=$(
    aws s3api list-object-versions \
        --bucket ${CODEBUILD_ARTIFACTSTORE_BUCKET_NAME} \
        --query='{Objects: Versions[].{Key:Key,VersionId:VersionId}}'
) \
&& echo ${OBJECT_LIST}

# JSONフォーマットの確認
echo ${OBJECT_LIST} | python -m json.tool

# バケットを空にする
aws s3api delete-objects \
    --bucket ${CODEBUILD_ARTIFACTSTORE_BUCKET_NAME} \
    --delete "${OBJECT_LIST}"

# S3バケットを削除
aws s3api delete-bucket \
    --bucket ${CODEBUILD_ARTIFACTSTORE_BUCKET_NAME}

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # オブジェクト一覧取得
[cloudshell-user@ip-10-132-76-170 ~]$ OBJECT_LIST=$(
>     aws s3api list-object-versions \
>         --bucket ${S3_BUCKET_NAME} \
>         --query='{Objects: Versions[].{Key:Key,VersionId:VersionId}}'
> ) \
> && echo ${OBJECT_LIST}
{ "Objects": [ { "Key": "buildspec.yaml", "VersionId": "null" }, { "Key": "index.html", "VersionId": "null" }, { "Key": "src/appspec.yml", "VersionId": "null" }, { "Key": "src/index.html", "VersionId": "null" } ] }
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-132-76-170 ~]$ echo ${OBJECT_LIST} | python -m json.tool
{
    "Objects": [
        {
            "Key": "buildspec.yaml",
            "VersionId": "null"
        },
        {
            "Key": "index.html",
            "VersionId": "null"
        },
        {
            "Key": "src/appspec.yml",
            "VersionId": "null"
        },
        {
            "Key": "src/index.html",
            "VersionId": "null"
        }
    ]
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # バケットを空にする
[cloudshell-user@ip-10-132-76-170 ~]$ aws s3api delete-objects \
>     --bucket ${S3_BUCKET_NAME} \
>     --delete "${OBJECT_LIST}"
{
    "Deleted": [
        {
            "Key": "index.html",
            "VersionId": "null"
        },
        {
            "Key": "src/appspec.yml",
            "VersionId": "null"
        },
        {
            "Key": "buildspec.yaml",
            "VersionId": "null"
        },
        {
            "Key": "src/index.html",
            "VersionId": "null"
        }
    ]
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # S3バケットを削除
[cloudshell-user@ip-10-132-76-170 ~]$ aws s3api delete-bucket \
>     --bucket ${S3_BUCKET_NAME}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # オブジェクト一覧取得
[cloudshell-user@ip-10-132-76-170 ~]$ OBJECT_LIST=$(
>     aws s3api list-object-versions \
>         --bucket ${ARTIFACTSTORE_BUCKET_NAME} \
>         --query='{Objects: Versions[].{Key:Key,VersionId:VersionId}}'
> ) \
> && echo ${OBJECT_LIST}
{ "Objects": [ { "Key": "h4b-hands-on-ec2/BuildArtif/wkxrsDK", "VersionId": "null" }, { "Key": "h4b-hands-on-ec2/SourceArti/8LHRFme", "VersionId": "null" }, { "Key": "h4b-hands-on-s3/SourceArti/MYU9p06", "VersionId": "null" }, { "Key": "h4b-hands-on-s3/SourceArti/Wovweya", "VersionId": "null" }, { "Key": "h4b-hands-on-s3/SourceArti/ozYCGsg", "VersionId": "null" }, { "Key": "h4b-hands-on-s3/SourceArti/xNtW3Ec", "VersionId": "null" } ] }
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-132-76-170 ~]$ echo ${OBJECT_LIST} | python -m json.tool
{
    "Objects": [
        {
            "Key": "h4b-hands-on-ec2/BuildArtif/wkxrsDK",
            "VersionId": "null"
        },
        {
            "Key": "h4b-hands-on-ec2/SourceArti/8LHRFme",
            "VersionId": "null"
        },
        {
            "Key": "h4b-hands-on-s3/SourceArti/MYU9p06",
            "VersionId": "null"
        },
        {
            "Key": "h4b-hands-on-s3/SourceArti/Wovweya",
            "VersionId": "null"
        },
        {
            "Key": "h4b-hands-on-s3/SourceArti/ozYCGsg",
            "VersionId": "null"
        },
        {
            "Key": "h4b-hands-on-s3/SourceArti/xNtW3Ec",
            "VersionId": "null"
        }
    ]
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # バケットを空にする
[cloudshell-user@ip-10-132-76-170 ~]$ aws s3api delete-objects \
>     --bucket ${ARTIFACTSTORE_BUCKET_NAME} \
>     --delete "${OBJECT_LIST}"
{
    "Deleted": [
        {
            "Key": "h4b-hands-on-s3/SourceArti/ozYCGsg",
            "VersionId": "null"
        },
        {
            "Key": "h4b-hands-on-ec2/BuildArtif/wkxrsDK",
            "VersionId": "null"
        },
        {
            "Key": "h4b-hands-on-s3/SourceArti/Wovweya",
            "VersionId": "null"
        },
        {
            "Key": "h4b-hands-on-ec2/SourceArti/8LHRFme",
            "VersionId": "null"
        },
        {
            "Key": "h4b-hands-on-s3/SourceArti/MYU9p06",
            "VersionId": "null"
        },
        {
            "Key": "h4b-hands-on-s3/SourceArti/xNtW3Ec",
            "VersionId": "null"
        }
    ]
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # S3バケットを削除
[cloudshell-user@ip-10-132-76-170 ~]$ aws s3api delete-bucket \
>     --bucket ${ARTIFACTSTORE_BUCKET_NAME}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # オブジェクト一覧取得
[cloudshell-user@ip-10-132-76-170 ~]$ OBJECT_LIST=$(
>     aws s3api list-object-versions \
>         --bucket ${CODEBUILD_ARTIFACTSTORE_BUCKET_NAME} \
>         --query='{Objects: Versions[].{Key:Key,VersionId:VersionId}}'
> ) \
> && echo ${OBJECT_LIST}
{ "Objects": [ { "Key": "artifact.zip", "VersionId": "null" }, { "Key": "h4b-hands-on/appspec.yml", "VersionId": "null" }, { "Key": "h4b-hands-on/index.html", "VersionId": "null" } ] }
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # JSONフォーマットの確認
[cloudshell-user@ip-10-132-76-170 ~]$ echo ${OBJECT_LIST} | python -m json.tool
{
    "Objects": [
        {
            "Key": "artifact.zip",
            "VersionId": "null"
        },
        {
            "Key": "h4b-hands-on/appspec.yml",
            "VersionId": "null"
        },
        {
            "Key": "h4b-hands-on/index.html",
            "VersionId": "null"
        }
    ]
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # バケットを空にする
[cloudshell-user@ip-10-132-76-170 ~]$ aws s3api delete-objects \
>     --bucket ${CODEBUILD_ARTIFACTSTORE_BUCKET_NAME} \
>     --delete "${OBJECT_LIST}"
{
    "Deleted": [
        {
            "Key": "h4b-hands-on/index.html",
            "VersionId": "null"
        },
        {
            "Key": "artifact.zip",
            "VersionId": "null"
        },
        {
            "Key": "h4b-hands-on/appspec.yml",
            "VersionId": "null"
        }
    ]
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # S3バケットを削除
[cloudshell-user@ip-10-132-76-170 ~]$ aws s3api delete-bucket \
>     --bucket ${CODEBUILD_ARTIFACTSTORE_BUCKET_NAME}

IAM

コマンド
# ロールにアタッチされているポリシーをリスト
POLICIES=$(
    aws iam list-attached-role-policies \
        --role-name ${PIPELINE_IAM_ROLE_NAME} \
        --query 'AttachedPolicies[*].PolicyArn' \
        --output text
) \
&& echo ${POLICIES}

# リスト内のポリシーをデタッチする
for POLICY in ${POLICIES}; do
    aws iam detach-role-policy \
        --role-name ${PIPELINE_IAM_ROLE_NAME} \
        --policy-arn ${POLICY}
done

# IAMロールの削除
aws iam delete-role \
    --role-name ${PIPELINE_IAM_ROLE_NAME}

# IAMポリシーの削除
aws iam delete-policy \
    --policy-arn ${PIPELINE_IAM_POLICY_ARN}

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # ロールにアタッチされているポリシーをリスト
[cloudshell-user@ip-10-132-76-170 ~]$ POLICIES=$(
>     aws iam list-attached-role-policies \
>         --role-name ${PIPELINE_IAM_ROLE_NAME} \
>         --query 'AttachedPolicies[*].PolicyArn' \
>         --output text
> ) \
> && echo ${POLICIES}
arn:aws:iam::999999999999:policy/service-role/AWSCodePipelineServiceRole-ap-northeast-1
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # リスト内のポリシーをデタッチする
[cloudshell-user@ip-10-132-76-170 ~]$ for POLICY in ${POLICIES}; do
>     aws iam detach-role-policy \
>         --role-name ${PIPELINE_IAM_ROLE_NAME} \
>         --policy-arn ${POLICY}
> done
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # IAMロールの削除
[cloudshell-user@ip-10-132-76-170 ~]$ aws iam delete-role \
>     --role-name ${PIPELINE_IAM_ROLE_NAME}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # IAMポリシーの削除
[cloudshell-user@ip-10-132-76-170 ~]$ aws iam delete-policy \
>     --policy-arn ${PIPELINE_IAM_POLICY_ARN}
コマンド
# CODEDEPLOY_IAM_ROLE_NAME
# ロールにアタッチされているポリシーをリスト
POLICIES=$(
    aws iam list-attached-role-policies \
        --role-name ${EVENT_IAM_ROLE_NAME} \
        --query 'AttachedPolicies[*].PolicyArn' \
        --output text
) \
&& echo ${POLICIES}

# リスト内のポリシーをデタッチする
for POLICY in ${POLICIES}; do
    aws iam detach-role-policy \
        --role-name ${EVENT_IAM_ROLE_NAME} \
        --policy-arn ${POLICY}
done

# IAMロールの削除
aws iam delete-role \
    --role-name ${EVENT_IAM_ROLE_NAME}

# IAMポリシーの削除
aws iam delete-policy \
    --policy-arn ${EVENT_IAM_POLICY_ARN}

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # CODEDEPLOY_IAM_ROLE_NAME
[cloudshell-user@ip-10-132-76-170 ~]$ # ロールにアタッチされているポリシーをリスト
[cloudshell-user@ip-10-132-76-170 ~]$ POLICIES=$(
>     aws iam list-attached-role-policies \
>         --role-name ${EVENT_IAM_ROLE_NAME} \
>         --query 'AttachedPolicies[*].PolicyArn' \
>         --output text
> ) \
> && echo ${POLICIES}
arn:aws:iam::999999999999:policy/service-role/start-pipeline-execution-ap-northeast-1-h4b-hands-on-s3
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # リスト内のポリシーをデタッチする
[cloudshell-user@ip-10-132-76-170 ~]$ for POLICY in ${POLICIES}; do
>     aws iam detach-role-policy \
>         --role-name ${EVENT_IAM_ROLE_NAME} \
>         --policy-arn ${POLICY}
> done
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # IAMロールの削除
[cloudshell-user@ip-10-132-76-170 ~]$ aws iam delete-role \
>     --role-name ${EVENT_IAM_ROLE_NAME}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # IAMポリシーの削除
[cloudshell-user@ip-10-132-76-170 ~]$ aws iam delete-policy \
>     --policy-arn ${EVENT_IAM_POLICY_ARN}
コマンド
# CODEDEPLOY_IAM_ROLE_NAME
# ロールにアタッチされているポリシーをリスト
POLICIES=$(
    aws iam list-attached-role-policies \
        --role-name ${EVENT_IAM_ROLE_2_NAME} \
        --query 'AttachedPolicies[*].PolicyArn' \
        --output text
) \
&& echo ${POLICIES}

# リスト内のポリシーをデタッチする
for POLICY in ${POLICIES}; do
    aws iam detach-role-policy \
        --role-name ${EVENT_IAM_ROLE_2_NAME} \
        --policy-arn ${POLICY}
done

# IAMロールの削除
aws iam delete-role \
    --role-name ${EVENT_IAM_ROLE_2_NAME}

# IAMポリシーの削除
aws iam delete-policy \
    --policy-arn ${EVENT_IAM_POLICY_2_ARN}

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # CODEDEPLOY_IAM_ROLE_NAME
[cloudshell-user@ip-10-132-76-170 ~]$ # ロールにアタッチされているポリシーをリスト
[cloudshell-user@ip-10-132-76-170 ~]$ POLICIES=$(
>     aws iam list-attached-role-policies \
>         --role-name ${EVENT_IAM_ROLE_2_NAME} \
>         --query 'AttachedPolicies[*].PolicyArn' \
>         --output text
> ) \
> && echo ${POLICIES}
arn:aws:iam::999999999999:policy/service-role/start-pipeline-execution-ap-northeast-1-h4b-hands-on-ec2
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # リスト内のポリシーをデタッチする
[cloudshell-user@ip-10-132-76-170 ~]$ for POLICY in ${POLICIES}; do
>     aws iam detach-role-policy \
>         --role-name ${EVENT_IAM_ROLE_2_NAME} \
>         --policy-arn ${POLICY}
> done
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # IAMロールの削除
[cloudshell-user@ip-10-132-76-170 ~]$ aws iam delete-role \
>     --role-name ${EVENT_IAM_ROLE_2_NAME}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # IAMポリシーの削除
[cloudshell-user@ip-10-132-76-170 ~]$ aws iam delete-policy \
>     --policy-arn ${EVENT_IAM_POLICY_2_ARN}
コマンド
# EC2_IAM_ROLE_NAME
# IAMプロファイルのデタッチ
aws iam remove-role-from-instance-profile \
    --instance-profile-name ${EC2_IAM_ROLE_NAME}\
    --role-name ${EC2_IAM_ROLE_NAME}

# インスタンスプロファイル削除
aws iam delete-instance-profile \
    --instance-profile-name ${EC2_IAM_ROLE_NAME}

# ロールにアタッチされているポリシーをリスト
POLICIES=$(
    aws iam list-attached-role-policies \
        --role-name ${EC2_IAM_ROLE_NAME} \
        --query 'AttachedPolicies[*].PolicyArn' \
        --output text
) \
&& echo ${POLICIES}

# リスト内のポリシーをデタッチする
for POLICY in ${POLICIES}; do
    aws iam detach-role-policy \
        --role-name ${EC2_IAM_ROLE_NAME} \
        --policy-arn ${POLICY}
done

# IAMロールの削除
aws iam delete-role \
    --role-name ${EC2_IAM_ROLE_NAME}

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # EC2_IAM_ROLE_NAME
[cloudshell-user@ip-10-132-76-170 ~]$ # IAMプロファイルのデタッチ
[cloudshell-user@ip-10-132-76-170 ~]$ aws iam remove-role-from-instance-profile \
>     --instance-profile-name ${EC2_IAM_ROLE_NAME}\
>     --role-name ${EC2_IAM_ROLE_NAME}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # インスタンスプロファイル削除
[cloudshell-user@ip-10-132-76-170 ~]$ aws iam delete-instance-profile \
>     --instance-profile-name ${EC2_IAM_ROLE_NAME}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # ロールにアタッチされているポリシーをリスト
[cloudshell-user@ip-10-132-76-170 ~]$ POLICIES=$(
>     aws iam list-attached-role-policies \
>         --role-name ${EC2_IAM_ROLE_NAME} \
>         --query 'AttachedPolicies[*].PolicyArn' \
>         --output text
> ) \
> && echo ${POLICIES}
arn:aws:iam::aws:policy/AmazonS3FullAccess
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # リスト内のポリシーをデタッチする
[cloudshell-user@ip-10-132-76-170 ~]$ for POLICY in ${POLICIES}; do
>     aws iam detach-role-policy \
>         --role-name ${EC2_IAM_ROLE_NAME} \
>         --policy-arn ${POLICY}
> done
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # IAMロールの削除
[cloudshell-user@ip-10-132-76-170 ~]$ aws iam delete-role \
>     --role-name ${EC2_IAM_ROLE_NAME}
コマンド
# CODEBUILD_IAM_ROLE_NAME
# ロールにアタッチされているポリシーをリスト
POLICIES=$(
    aws iam list-attached-role-policies \
        --role-name ${CODEBUILD_IAM_ROLE_NAME} \
        --query 'AttachedPolicies[*].PolicyArn' \
        --output text
) \
&& echo ${POLICIES}

# リスト内のポリシーをデタッチする
for POLICY in ${POLICIES}; do
    aws iam detach-role-policy \
        --role-name ${CODEBUILD_IAM_ROLE_NAME} \
        --policy-arn ${POLICY}
done

# IAMロールの削除
aws iam delete-role \
    --role-name ${CODEBUILD_IAM_ROLE_NAME}

# IAMポリシーの削除
aws iam delete-policy \
    --policy-arn ${CODEBUILD_IAM_POLICY_ARN}

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # CODEBUILD_IAM_ROLE_NAME
[cloudshell-user@ip-10-132-76-170 ~]$ # ロールにアタッチされているポリシーをリスト
[cloudshell-user@ip-10-132-76-170 ~]$ POLICIES=$(
>     aws iam list-attached-role-policies \
>         --role-name ${CODEBUILD_IAM_ROLE_NAME} \
>         --query 'AttachedPolicies[*].PolicyArn' \
>         --output text
> ) \
> && echo ${POLICIES}
arn:aws:iam::999999999999:policy/service-role/CodeBuildBasePolicy-h4b-hands-on-ap-northeast-1 arn:aws:iam::aws:policy/AWSCodeDeployDeployerAccess
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # リスト内のポリシーをデタッチする
[cloudshell-user@ip-10-132-76-170 ~]$ for POLICY in ${POLICIES}; do
>     aws iam detach-role-policy \
>         --role-name ${CODEBUILD_IAM_ROLE_NAME} \
>         --policy-arn ${POLICY}
> done
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # IAMロールの削除
[cloudshell-user@ip-10-132-76-170 ~]$ aws iam delete-role \
>     --role-name ${CODEBUILD_IAM_ROLE_NAME}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # IAMポリシーの削除
[cloudshell-user@ip-10-132-76-170 ~]$ aws iam delete-policy \
>     --policy-arn ${CODEBUILD_IAM_POLICY_ARN}
コマンド
# CODEDEPLOY_IAM_ROLE_NAME
# ロールにアタッチされているポリシーをリスト
POLICIES=$(
    aws iam list-attached-role-policies \
        --role-name ${CODEDEPLOY_IAM_ROLE_NAME} \
        --query 'AttachedPolicies[*].PolicyArn' \
        --output text
) \
&& echo ${POLICIES}

# リスト内のポリシーをデタッチする
for POLICY in ${POLICIES}; do
    aws iam detach-role-policy \
        --role-name ${CODEDEPLOY_IAM_ROLE_NAME} \
        --policy-arn ${POLICY}
done

# IAMロールの削除
aws iam delete-role \
    --role-name ${CODEDEPLOY_IAM_ROLE_NAME}

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # CODEDEPLOY_IAM_ROLE_NAME
[cloudshell-user@ip-10-132-76-170 ~]$ # ロールにアタッチされているポリシーをリスト
[cloudshell-user@ip-10-132-76-170 ~]$ POLICIES=$(
>     aws iam list-attached-role-policies \
>         --role-name ${CODEDEPLOY_IAM_ROLE_NAME} \
>         --query 'AttachedPolicies[*].PolicyArn' \
>         --output text
> ) \
> && echo ${POLICIES}
arn:aws:iam::aws:policy/service-role/AWSCodeDeployRole
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # リスト内のポリシーをデタッチする
[cloudshell-user@ip-10-132-76-170 ~]$ for POLICY in ${POLICIES}; do
>     aws iam detach-role-policy \
>         --role-name ${CODEDEPLOY_IAM_ROLE_NAME} \
>         --policy-arn ${POLICY}
> done
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # IAMロールの削除
[cloudshell-user@ip-10-132-76-170 ~]$ aws iam delete-role \
>     --role-name ${CODEDEPLOY_IAM_ROLE_NAME}

EventBridge

コマンド
# codepipeline-h4b-hands-on-s3-rule用
aws events remove-targets \
    --rule ${EVENTS_RULE_NAME} \
    --ids "codepipeline-${PIPELINE_NAME}"

aws events delete-rule \
    --name ${EVENTS_RULE_NAME}

# codepipeline-h4b-hands-on-ec2-rule用
aws events remove-targets \
    --rule ${EVENTS_RULE_2_NAME} \
    --ids "codepipeline-${PIPELINE_2_NAME}"

aws events delete-rule \
    --name ${EVENTS_RULE_2_NAME}

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # codepipeline-h4b-hands-on-s3-rule用
[cloudshell-user@ip-10-132-76-170 ~]$ aws events remove-targets \
>     --rule ${EVENTS_RULE_NAME} \
>     --ids "codepipeline-${PIPELINE_NAME}"
{
    "FailedEntryCount": 0,
    "FailedEntries": []
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ aws events delete-rule \
>     --name ${EVENTS_RULE_NAME}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ # codepipeline-h4b-hands-on-ec2-rule用
[cloudshell-user@ip-10-132-76-170 ~]$ aws events remove-targets \
>     --rule ${EVENTS_RULE_2_NAME} \
>     --ids "codepipeline-${PIPELINE_2_NAME}"
{
    "FailedEntryCount": 0,
    "FailedEntries": []
}
[cloudshell-user@ip-10-132-76-170 ~]$ 
[cloudshell-user@ip-10-132-76-170 ~]$ aws events delete-rule \
>     --name ${EVENTS_RULE_2_NAME}

CloudWatch

コマンド
# ロググループ
aws logs delete-log-group \
    --log-group-name ${LOG_GROUP_NAME}

出力
[cloudshell-user@ip-10-132-76-170 ~]$ # ロググループ
[cloudshell-user@ip-10-132-76-170 ~]$ aws logs delete-log-group \
>     --log-group-name ${LOG_GROUP_NAME}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0