CircleCI에서 branch에 push는 테스트 환경에 배포하는 설정을 해 보았지만 S3과 CloudFront의 연결에서 조금 실수한 이야기

목적



이전에 GitHub에 push한 리소스를 CircleCI를 사용하여 S3에 배포하는 구성을 만들어 보았습니다.
이번에는 보다 현실적인 제품 개발을 이미지하여 테스트 환경과 프로덕션 환경이 나뉘어 있다고 가정하고 branch에 대한 커밋을 테스트 환경, master에 대한 커밋을 프로덕션 환경에 배포하도록 s3과 CiecleCI 설정 했습니다.

그 중 S3의 설정으로 실수를 깨달았으므로, 대처 방법 포함 공유합니다.

구성도



이용 서비스나 아키텍트는 전회와 같습니다. 테스트와 프로덕션의 2 환경이 됩니다.




환경 구축



CircleCI의 yaml 설정



전회의 설정치에 「테스트 환경의 bucket명」과 master에 push하지 않았을 경우의 처리를 기재했습니다.
본래라면 branch에 push를 명시해야하지만 else로 처리하고 있습니다.

config.yml
version: 2
jobs:
  build:
    working_directory: ~/repo
    environment:
      - AWS_S3_BUCKET_NAME: my-bcuket
      - AWS_S3_BUCKET_NAME_TEST: my-bcuket-test
      - AWS_S3_BUCKET_EXCLUDE: .*/*
    docker:
      - image: innovatorjapan/awscli:latest
    steps:
      - checkout
      - run:
          name: Deploy to Master or Branch.
          command: |
            if [ "${CIRCLE_BRANCH}" == "master" ]; then
              aws s3 sync ~/repo s3://${AWS_S3_BUCKET_NAME}/ --exact-timestamps --delete  --exclude "${AWS_S3_BUCKET_EXCLUDE}"
            else
              aws s3 sync ~/repo s3://${AWS_S3_BUCKET_NAME_TEST}/ --exact-timestamps --delete  --exclude "${AWS_S3_BUCKET_EXCLUDE}"
            fi

S3 버킷 생성



AWS_S3_BUCKET_NAME_TEST: 로 명명된 버킷을 생성합니다.
S3 버킷을 만들려면 "기존 버킷에서 설정 복사"라는 옵션이 있으므로 이전에 만든 프로덕션 버킷에서 설정을 복사했지만 나중에 설명하는 이유로 다시 만들었습니다.


S3의 액세스 로그는 이번에는 생략되었습니다.


생성 후 버킷 정책 설정을 복사합니다. 결국 여기가 오류의 원인이라는 것을 알았습니다.

bucket.policy
{
    "Version": "2008-10-17",
    "Id": "PolicyForCloudFrontPrivateContent",
    "Statement": [
        {
            "Sid": "1",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity XXXXXXXX"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::my-bcuket-test/*"
        },
        {
            "Sid": "forCircleCi",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::XXXXXXXXXXXX:user/CircleCI"
            },
            "Action": [
                "s3:PutObject",
                "s3:ListBucket",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::webpage-my-bcuket-test",
                "arn:aws:s3:::webpage-my-bcuket-test/*"
            ]
        }
    ]
}

CloudFront



이전에 만든 환경과 마찬가지로 S3을 오리진으로 설정합니다.


Route53 레코드 세트 추가



레코드 세트 작성에서 테스트 환경의 도메인을 등록합니다.


연결할 수 없음



S3의 Access deny 페이지가 표시되었습니다.
구성 도메인에서 S3 오류 페이지가 표시되었으므로 Route53과 Cloudfront 사이의 설정이 올바른 S3와 Cloudfront 사이의 문제로 나타났습니다.

원인



CloudFront Origin Access Identity 값이 Cloudfront에서 자동으로 업데이트되지 않으므로 복사 원본 설정이 남아 있습니다.
아마 패킷 정책에 CircleCi의 허가 설정 등 표준외의 값이 들어 있었기 때문이라고 추측하고 있을 것입니다.

bucket.policy
{
    "Version": "2008-10-17",
    "Id": "PolicyForCloudFrontPrivateContent",
    "Statement": [
        {
            "Sid": "1",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity XXXXXXXX" #←これ
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::my-bcuket-test/*"
        },
        {
            "Sid": "forCircleCi",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::XXXXXXXXXXXX:user/CircleCI"
            },
            "Action": [
                "s3:PutObject",
                "s3:ListBucket",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::webpage-my-bcuket-test",
                "arn:aws:s3:::webpage-my-bcuket-test/*"
            ]
        }
    ]
}

대책



위의 원인을 깨닫는 데 늦었고 S3 버킷을 다시 작성한 결과 무사한 테스트 페이지에 액세스 할 수있었습니다.
Diff 체크를 하면 좀 더 빨리 알아차릴 수 있고 S3 설정을 복사한 후의 패킷 정책에서 CloudFront Origin Access Identity의 값을 수동으로 변경하면 액세스할 수 있었다고 추측하고 있습니다.

소감



접속 트러블시에는 파라미터는 하나하나 검증할 필요가 있습니다.

좋은 웹페이지 즐겨찾기