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ファイルをこしらえます。
{
"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": {
"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 ファイルを作成します。
{
"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
ファイルを編集します。
<!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 だけで設定、構築していく予定です。