1. はじめに
このブログ(Cloud Steps)は、CloudFront+S3の構成で静的サイトを運用しています。
ブログを更新する際、S3にファイルをアップロードする必要がありますが、
ブログ更新の度にS3コマンドやAWSマネジメントコンソールからファイルアップロードするのは、少し面倒です。
なので、GitHubへのpushを検知し、CodeFamilyで自動的にS3にファイルの変更を自動で反映
できるようしました。
2. Hugoとは
Hugoは、オープンソースの静的サイト生成ツールです。
マークダウンファイルを記述すれば、静的ファイルを生成することができ、簡単に、柔軟に、静的サイトを作成することができます。
サイトのデザインはコントリビューターが作成したテーマを適応すれば、自由に変更することができます。また、自分自身でテーマを作成することも可能なので、デザインにこだわりがある人はテーマを作成するのもいいでしょう。
※ Hugoの導入方法や利用方法は、この記事では対象外とします。
3. CodeFamilyとは
CodeFamilyとは、AWSが提供するソフトウェア開発とデプロイメントのライフサイクルを支援するサービス群の総称です。CodeFamilyは、公式なサービス名ではなく、一般的に以下のような 「Code」から始まるAWSサービス群 を指すことが多いです。
- CodeFamily
- CodePipeline
- CodeBuild
- CodeDeploy
- CodeStar(非推奨)
このページでは、CodePipeline, CodeBuildについて書いていきます。
3.1 CodeBuild
CodeBuildは、フルマネージドの継続的インテグレーションサービスです。
アプリケーションコードのコンパイル、テストを実行などのビルド環境を提供するサービスです。
CodeBuildは、フルマネージドなサービスのため、ユーザーがビルドサーバーのプロビジョニングの必要なく、サーバーのパッチ適用などのメンテナンス作業を必要としません。
3.2 CodePipeline
CodePipeline は、継続的インテグレーション(CI)と継続的デリバリー(CD) を自動化するための パイプライン構築サービス です。アプリケーションのコードの変更が本番環境に届くまでの一連の流れ(ビルド、テスト、デプロイなど)をステージごとに視覚的に構成して自動化できます。
4. 構成図
5. パイプライン構築手順
- 作成するリソース
- AWSとGithubの接続
- CodePipeline
- CodeBuild
- IAM
5.1 GitHubとCodePipelineを接続する
GitHubとCodePipelineの接続は、AWSマネージメントコンソールから行います。
- AWSマネージメントコンソールの検索欄からCodeBuildと検索>左ペインの設定>接続>接続ボタンをクリック。
- プロバイダー選択で「GitHub」を選択する。
- 「GitHubアプリ接続を作成する」に任意の接続名を入力し、「GitHubに接続する」をクリックする。
- GitHubの認証情報をきかれるので入力する。
5.2 CodePipelineを作成する
CodePipelineでステージを作成する。
Pipeline:
Type: AWS::CodePipeline::Pipeline
Properties:
Name: !Sub "${ProjectName}-pipeline"
RoleArn: !GetAtt PipelineRole.Arn
ArtifactStore:
Type: S3
Location: !Ref ArtifactBucket
Stages:
- Name: Source
Actions:
- Name: GitHub_Source
ActionTypeId:
Category: Source
Owner: AWS
Provider: CodeStarSourceConnection
Version: 1
OutputArtifacts:
- Name: SourceOutput
Configuration:
ConnectionArn: !Ref CodeStarConnectionArn
FullRepositoryId: !Ref GitHubRepo
BranchName: main
DetectChanges: true
RunOrder: 1
- Name: Build
Actions:
- Name: CodeBuild
ActionTypeId:
Category: Build
Owner: AWS
Provider: CodeBuild
Version: 1
InputArtifacts:
- Name: SourceOutput
OutputArtifacts:
- Name: BuildOutput
Configuration:
ProjectName: !Ref CodeBuildProject
RunOrder: 1
5.3 CodeBuildを作成する
CodeBuildProject:
Type: AWS::CodeBuild::Project
Properties:
Name: !Sub '${ProjectName}-hugo-deploy'
ServiceRole: !GetAtt CodeBuildServiceRole.Arn
Artifacts:
Type: CODEPIPELINE
Environment:
Type: LINUX_CONTAINER
ComputeType: BUILD_GENERAL1_SMALL
Image: aws/codebuild/standard:7.0
Source:
Type: CODEPIPELINE
BuildSpec: buildspec.yml
5.4 buildspec.yamlを作成する
buildspec.yamlとは、そもそもなんでしょうか。
CodeBuild のビルド仕様に関するリファレンスより
CodeBuild がビルドを実行するために使用するオペレーティングシステム、プログラミング言語ランタイム、およびツールの組み合わせを表します。
利用するbuildspec.yamlです。
version: 0.2
phases:
install:
runtime-versions:
python: 3.12
commands:
build:
commands:
- echo "Uploading to S3..."
# public配下のデータとバケットを同期する
- aws s3 sync src/public/ s3://sre-blog-static-hosting/ --delete
post_build:
on-failure: ABORT
# CloudFronのキャッシュ削除
commands:
aws cloudfront create-invalidation --distribution-id E3O57BDJL8K2FC --paths "/*"
5.5 IAMロールを作成する
# Codepipeline用
PipelineRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: codepipeline.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: CodePipelineCustomPolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- codebuild:*
- s3:*
- codestar-connections:UseConnection
Resource: "*"
# Codebuildのサービスロール
CodeBuildServiceRole:
Type: AWS::IAM::Role
DependsOn: ArtifactBucket
Properties:
RoleName: !Sub "CodeBuildServiceRole-${AWS::StackName}"
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: codebuild.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: CodeBuildS3Access
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- s3:ListBucket
Resource: !Sub "arn:aws:s3:::${S3BucketName}"
- Effect: Allow
Action:
- s3:PutObject
- s3:DeleteObject
- s3:GetObject
Resource: !Sub "arn:aws:s3:::${S3BucketName}/*"
- Effect: Allow
Action:
- s3:GetObject
Resource: !Sub "arn:aws:s3:::${S3ArtifactBucketName}/*"
- Effect: Allow
Action: logs:*
Resource: "*"
- Effect: Allow
Action:
- cloudfront:CreateInvalidation
Resource: !Sub "arn:aws:cloudfront::${AWS::AccountId}:distribution/{CloudFrontDistributionID}"
ファイルを作成してgit pushすると作成されたパイプラインが自動的に作動します。
7. まとめ
Hugoで生成した静的サイトをAWSのCodePipelineとCodeBuildを使ってS3に自動デプロイを作成しました。GitHubへのpushをトリガーに、ビルドとS3アップロード、CloudFrontキャッシュの削除までを自動化できました。ファイルのアップロード作業が面倒になっていたので、ブログの運営が快適になりました。