概要
S3で静的コンテンツをホスティングしている場合に、そのコンテンツの更新をCircleCIを使って自動化する方法についてまとめます。
Maven等で出力したレポートのHTMLをS3で公開、更新するようなケースを想定しています。
前提
- S3バケットは作成済である
- 静的ウェブサイトホスティングが有効になっている
手順
IAMユーザの作成
- CircleCI用のIAMユーザを作成して、Access Key IdとSecret Access Keyを控える
- 専用のユーザを作成することをCircleCIも推奨している
IAMポリシーの作成
- S3の特定バケットにsyncできるポリシーを作成する
- 作成したポリシーにユーザを紐付ける
- Policy Generatorなど活用する
サンプル
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "StmtXXXXX",
"Effect": "Allow",
"Action": [
"s3:DeleteObject",
"s3:GetObject",
"s3:ListAllMyBuckets",
"s3:ListBucket",
"s3:PutObject",
"s3:PutObjectAcl"
],
"Resource": [
"arn:aws:s3:::your.s3.backet",
"arn:aws:s3:::your.s3.backet/*"
]
}
]
}
ポイントとしては下記。
- Resourceはバケット自体とバケット配下の階層両方の指定が必要
- PutObjectAclをAllowする必要がる
バケットポリシーの作成
このままだと全公開されてしまうので、必要に応じてIP制限をかける。
- S3コンソールからバケットポリシーの作成を行う https://console.aws.amazon.com/s3/home
- 対象のバケットを選択→[プロパティ]→[アクセス制限]→[バケットポリシーの編集]
サンプル
{
"Version": "2012-10-17",
"Id": "PolicyXXXXX",
"Statement": [
{
"Sid": "StmtXXXXX",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::your.s3.backet/*",
"Condition": {
"NotIpAddress": {
"aws:SourceIp": [
"XXX.XXX.XXX.XX",
"XXX.XXX.XXX.XX"
]
}
}
}
]
}
- 許可IP以外をDenyする
- 許可IPにGetObjectを許可する
- 許可と拒否IPそれぞれでアクセスしてみて、期待挙動になるか確認する
- 許可IP以外だと403が返るはず
CircleCIの設定
AWS Permissionsの設定
- 対象のプロジェクトを選択
- [Project Settings]→[AWS Permissions]
- 作成したIAMユーザの認証情報を入力する
circle.ymlの設定
- aws cli で対象のファイルをsyncする
サンプル
machine:
java:
version: oraclejdk8
dependencies:
override:
- mvn dependency:resolve
test:
override:
- mvn integration-test
deployment:
deploy:
branch: aws_deploy
commands:
- mv your_uploadcontents $CIRCLE_ARTIFACTS
- aws s3 sync $CIRCLE_ARTIFACTS/your_upload_contents s3://your.s3.backet/ --delete --acl public-read
ポイントは下記の通り。
- aws_deployブランチの変更の際デプロイする
- 作成したコンテンツを$CIRCLE_ARTIFACTSに移動
- これはCircleCIのArtifactsを使いたいだけで、S3にアップロードするのと直接関係はない
- $CIRCLE_ARTIFACTS 配下をS3バケット直下と同期
-
--delete
で削除も同期 -
--acl public-read
でコンテンツを公開する- これをしないと、webサイトとしてアクセスできるようにならない