0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ひろ亭Advent Calendar 2021

Day 22

AWS CLIで Web サイトを構築、管理、運用する(22日目)

Last updated at Posted at 2021-12-21

22 日目!

昨日の続編!
リポジトリ管理を始めたコンテンツをデプロイできるように設定をいれていきます。

22日目の要約

コンテンツをデプロイできるようにするよ!

AWS CLI の準備

このあたりをみて、好きなバージョンとお使いのOSにあった環境設定をしてくださいね。
なんなら、 AWS CloudShell で実行するのも楽でよいと思います。
この記事シリーズは、AWS CloudShell で実行し、実行例を載せています。

バージョン1
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv1.html

バージョン2
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv2.html

概要

CodeCommit を使ってコンテンツを管理するよ!

さあ、やってみよう!

CodePipeline サービスロールを作成する

Code Pipelineがパイプラインを動かすにあたって使用するサービスロールをまずは作成します。

iam create-role コマンドを実行します

aws iam create-role --path /service-role/ --role-name  AWSCodePipelineServiceRole-ap-northeast-1-AdventCalendar2021 --assume-role-policy-document '{"Version": "2012-10-17","Statement": [{"Effect": "Allow","Principal": {"Service": "codepipeline.amazonaws.com"},"Action": "sts:AssumeRole"}]}'

ロール作成が完了すると、以下のような json が返ります。

{
    "Role": {
        "Path": "/service-role/",
        "RoleName": "AWSCodePipelineServiceRole-ap-northeast-1-AdventCalendar2021",
        "RoleId": "AROA*****************",
        "Arn": "arn:aws:iam::************:role/service-role/AWSCodePipelineServiceRole-ap-northeast-1-AdventCalendar2021",
        "CreateDate": "2021-12-21T15:47:04+00:00",
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Effect": "Allow",
                    "Principal": {
                        "Service": "codepipeline.amazonaws.com"
                    },
                    "Action": "sts:AssumeRole"
                }
            ]
        }
    }
}

次にポリシーを作成します。
まずは、jsonファイルをこしらえます。

policy-pipeline.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"
}

json を使って IAM ポリシーを作成します。

aws iam create-policy --policy-name AWSCodePipelineServiceRole-ap-northeast-1-AdventCalendar2021 --path /service-role/ --policy-document file://policy-pipeline.json

ポリシー作成が成功すると、以下の json が返りますので、 Arn の値を確認します。

{
    "Policy": {
        "PolicyName": "AWSCodePipelineServiceRole-ap-northeast-1-AdventCalendar2021",
        "PolicyId": "ANPA*****************",
        "Arn": "arn:aws:iam::************:policy/service-role/AWSCodePipelineServiceRole-ap-northeast-1-AdventCalendar2021",
        "Path": "/service-role/",
        "DefaultVersionId": "v1",
        "AttachmentCount": 0,
        "PermissionsBoundaryUsageCount": 0,
        "IsAttachable": true,
        "CreateDate": "2021-12-21T16:27:44+00:00",
        "UpdateDate": "2021-12-21T16:27:44+00:00"
    }
}

作成したロールとポリシーを関連づけてしまいます。

aws iam attach-role-policy --role-name AWSCodePipelineServiceRole-ap-northeast-1-AdventCalendar2021 --policy-arn arn:aws:iam::<AWS アカウントID>:policy/service-role/AWSCodePipelineServiceRole-ap-northeast-1-AdventCalendar2021

割り当てに成功しても特に応答はありません。

パイプラインの元になる json を作成する

CodePipeline で作成するパイプラインの定義となる json を作成します。

pipeline.json
{
    "pipeline": {
        "name": "AdventCalendar2021",
        "roleArn": "arn:aws:iam::<AWSアカウントID>:role/service-role/AWSCodePipelineServiceRole-ap-northeast-1-AdventCalendar2021",
        "artifactStore": {
            "type": "S3",
            "location": "codepipeline-ap-northeast-1-<12桁くらいの文字列>"
        },
        "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": "AdventCalendar2021"
                        },
                        "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": "CloudFrontのオリジンになっているS3バケット名",
                            "Extract": "true"
                        },
                        "outputArtifacts": [],
                        "inputArtifacts": [
                            {
                                "name": "SourceArtifact"
                            }
                        ],
                        "region": "ap-northeast-1",
                        "namespace": "DeployVariables"
                    }
                ]
            }
        ],
        "version": 1
    }
}

パイプラインを作成する

codepipeline create-pipeline コマンドでパイプラインを作成します。

aws codepipeline create-pipeline --cli-input-json file://pipeline.json

パイプラインの作成に成功すると json が返りますが長いので割愛します。

初回動作の状況を確認する

パイプラインが作成されると、CodeCommit からソースの取得を行い、S3 バケットへデプロイを行います。
この状況を確認します。

aws codepipeline get-pipeline-state --name AdventCalendar2021

取得に成功すると json が出力されます。
この json のうち、2つある、latestExecution の中にある、status の値が、両方とも Succeeded になっていればOKです。

Amazon EventBridge の設定を行い、プッシュから自動でデプロイできるようにする

EventBridge用の IAM ロールを作成する

リポジトリへのプッシュを契機に、EventBridge が CodePipeline を動作できるようにロールとポリシーを作成していきます。

aws iam create-role --role-name role-event-adcale --assume-role-policy-document '{"Version": "2012-10-17","Statement": [{"Effect": "Allow","Principal": {"Service": "events.amazonaws.com"},"Action": "sts:AssumeRole"}]}'

ロールが作成できると json が返ってきます。

次に、ポリシーを作成します。
まずは json ファイルを作成します。

policy-event.json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "codepipeline:StartPipelineExecution"
            ],
            "Resource": [
                "arn:aws:codepipeline:ap-northeast-1:<AWSアカウントID>:AdventCalendar2021"
            ]
        }
    ]
}

ポリシーをロールに割り当てます。

aws iam put-role-policy --role-name role-event-adcale --policy-name pol-policyevent --policy-document file://policy-event.json

特に応答はありません。

EventBridge のルールを作成する

events put-rule コマンドでルールを作成します。

aws events put-rule --name "MyCodeCommitRepoRule" --event-pattern "{\"source\":[\"aws.codecommit\"],\"detail-type\":[\"CodeCommit Repository State Change\"],\"resources\":[\"arn:aws:codecommit:ap-northeast-1:<AWS アカウントID>:AdventCalendar2021\"],\"detail\":{\"referenceType\":[\"branch\"],\"referenceName\":[\"master\"]}}" --role-arn "arn:aws:iam::<AWS アカウントID>:role/role-event-adcale"

CorePipeline をイベントのターゲットに指定する

最後に、イベントのターゲットとして指定します。

aws events put-targets --rule MyCodeCommitRepoRule --targets Id=1,Arn=arn:aws:codepipeline:ap-northeast-1:<AWS アカウントID>:AdventCalendar2021,RoleArn="arn:aws:iam::<AWS アカウントID>:role/role-event-adcale"

動作確認

まずは、現状の コンテンツを確認します。

curl https://<ドメイン名>
<!DOCTYPE html>
<html lang="ja">
<head>
  <title>Advent calendar 2021</title>
</head>
<body>
  <h1>Hello world!!</h1>
  <h2>Advent calendar 2021 DAY 21</h2>
</body>
</html>

確認ができたら、ローカルリポジトリのディレクトリに移動します。

cd <ローカルリポジトリのディレクトリ>

リモートリポジトリと同期させます。

git pull origin master

index.html ファイルを編集します。

index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <title>Advent calendar 2021</title>
</head>
<body>
  <h1>Hello world!!</h1>
  <h2>Advent calendar 2021 DAY 22</h2>
  <h2>Content is managed by CodeCommit!!</h2>
  <h2>Deployed by CodePipeline!!</h2>
</body>
</html>

編集が完了したら、コミットし、リモートリポジトリへプッシュします。

git add index.html
git commit -m "Day 22"
[master 5******] Day 22
 1 file changed, 2 insertions(+), 1 deletion(-)

git push origin master

Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 2 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 327 bytes | 327.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0), pack-reused 0
To https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/AdventCalendar2021
   a******..5******  master -> master

プッシュした後、codepipeline get-pipeline-state コマンドで状態を確認します。

2つある actionStates 内の latestExecution 以下の情報を確認します。

  • status: Suceeded になっているか
  • summary: コミット時に設定したメッセージが割り当てられているか
  • lastStatusChange: プッシュした時刻(UTC表記)に近い値か

問題がなさそうであれば、改めて、 curl コマンドでデプロイしたコンテンツが表示されるか確認します。

curl https://<ドメイン名>/
<!DOCTYPE html>
<html lang="ja">
<head>
  <title>Advent calendar 2021</title>
</head>
<body>
  <h1>Hello world!!</h1>
  <h2>Advent calendar 2021 DAY 22</h2>
  <h2>Content is managed by CodeCommit!!</h2>
  <h2>Deployed by CodePipeline!!</h2>
</body>
</html>

問題なさそうですね。よかった。

まとめ

AWS CLI だけで CI/CD の設定までできてしまいました。

残り3日!
明日、明後日は API Gateway + Lambda を AWS CLI だけで設定、構築していく予定です。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?