CodeBuild, S3, CloudFront를 통한 Web 서비스
여기서는 CodeBuild, S3, CloudFront를 통한 Web 서비스를 하는 방법에 대해서 알아볼 것이다.
이번 글에서는 아래의 아키텍처를 구성하면서 S3의 권한과 CloudFront설정에 대한 부분을 중점적으로 확인해 보도록 한다.
- 참고
여기서는 node.js를 통해 진행하므로 node.js를 미리 설치한다. 자세한 내용은 기타 설치문서 참고.
- brew install nvm
- nvm instasll v18.13.0
1. CodeCommit, CodeBuild 구성
-
CI/CD 계정에 CodeCommit을 생성한다.
bys-shared-cdcm-s3cfn
- CI/CD 계정에 CodeBuild를 생성한다.
bys-shared-cdb-s3cfn
- 코드빌드에 대한 자세한 구성은 CodeSeries 구성를 참고한다.
bys-shared-iam-cdb-role
IAM role은 ‘AWSCodeCommitFullAccess’, ‘AmazonS3FullAccess’ 정책을 할당했다.# Create Template aws codebuild create-project --generate-cli-skeleton > codebuild.json # Create CodeBuild project aws codebuild create-project --cli-input-json file://codebuild.json
codebuild.json
Schema 참고{ "name": "bys-shared-cdb-s3cloudfront", "description": "bys-shared-cdb-s3cloudfront", "source": { "type": "CODECOMMIT", "location": "https://git-codecommit.ap-northeast-2.amazonaws.com/v1/repos/bys-shared-cdcm-s3cfn", "gitCloneDepth": 1, "gitSubmodulesConfig": { "fetchSubmodules": false }, "buildspec": "codeseries/codebuild/buildspec.yml", "insecureSsl": false }, "secondarySources": [], "sourceVersion": "refs/heads/main", "secondarySourceVersions": [], "artifacts": { "type": "S3", "location": "bys-shared-s3-codeseries-cloudfront", "path": "/dev/artifacts", "name": "BuildArtifact" }, "secondaryArtifacts": [], "cache": { "type": "S3", "location": "bys-shared-s3-codeseries-cloudfront/sample/dev/cahce" }, "environment": { "type": "LINUX_CONTAINER", "image": "aws/codebuild/amazonlinux2-x86_64-standard:4.0", "computeType": "BUILD_GENERAL1_SMALL", "environmentVariables": [], "privilegedMode": false, "imagePullCredentialsType": "CODEBUILD" }, "serviceRole": "arn:aws:iam::202949997891:role/service-role/bys-shared-iam-cdb-role", "timeoutInMinutes": 60, "queuedTimeoutInMinutes": 480, "encryptionKey": "arn:aws:kms:ap-northeast-2:202949997891:key/7d16264a-10b4-4b7e-bea6-1863ac0b50c1", "tags": [ { "key": "Name", "value": "bys-shared-cdb-s3cloudfront" } ], "badgeEnabled": false, "logsConfig": { "cloudWatchLogs": { "status": "ENABLED" }, "s3Logs": { "status": "ENABLED", "location": "bys-shared-s3-codeseries-cloudfront/dev/logs", "encryptionDisabled": false } } }
- CodeBuild 소스 구성
- dist/index.html
- codeseries/codebuild/buildspec.yml
buildspec.yml
version: 0.2 phases: install: runtime-versions: nodejs: 16 commands: build: commands: - aws s3 cp --recursive dist/ s3://bys-dev-s3-cloudfront-service
2. S3 구성
S3를 구성하면서 알아 두면 좋을 점
- S3는 region 서비스이며 bucket 명은 global unique해야 한다.
- S3는 내/외부 모두에서 접근이 가능하므로 Bucket Policy와 ACLs를 통해서 접근제어가 가능하다.
- ACLs Disabled(AWS 권장)인 경우 Bucket Policy 만으로 접근 제어가 이루어진다.
- S3의 Object Ownership는 ACLs의 사용여부에 따라
ACLs Disabled -> Bucket owner enforced
/ACLs Enabled -> Bucket owner preferred, Object writer
로 나뉜다. Bucket Ownership- ACLs Disabled(AWS 권장)인 경우 무조건 Bucker의 소유계정이 모든 업로드된 Object에 대해 소유권을 가지게 되며 Object들에 대한 접근제어는 bucket policy 설정을 통해 제어한다.
- ACLs Enabled인 경우 ‘Bucket owner preferred’와 ‘Object writer’로 Ownership을 선택할 수 있다.
- ‘Bucket owner preferred’가 설정되어있는 상황에서 다른 계정에서
--acl bucket-owner-full-control
옵션을 통해 bucket에 object를 쓰는 경우, bucket을 소유한 계정에서 새 객체를 소유하고 제어 할 수 있다. - ‘Object writer’가 설정되어있는 상황에서 다른 계정에서 업로드한 경우 object를 업로드한 writer가 소유권을 가진다. ACLs를 통해 Permission 부여는 가능하다.
- 소유권을 누가 가지고 있느냐에 따라 접근제어가 달라지므로 이는 매우 중요하다.
- Canned ACL
S3 구성
-
CI/CD 계정에서 S3를 생성한다.
bys-shared-s3-codeseries-cloudfront
이 S3는 CodeBuild에서 사용하는 S3용도이며 log, cache용도로 사용한다. - DEV 계정에서 S3를 생성한다.
bys-dev-s3-cloudfront-service
이 계정의 S3는 CodeBuild에서 서비스될 resource들이 업로드 될 S3이며 Cloudfront를 통해 서비스 되는 S3다.- ACLs disabled (recommended)
- Check ‘Block all public access’
- Static website hosting enabled
- bucket policy 설정
- CodeBuild에서 업로드가 가능해야 한다. CodeBuild가 사용하는 role에 대해서 ‘s3:PutObject’가 가능해야 한다.
{ "Version": "2008-10-17", "Statement": [ { "Sid": "FromCodeBuild", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::202949997891:role/service-role/bys-shared-iam-cdb-role" }, "Action": [ "s3:Delete*", "s3:Put*" ], "Resource": [ "arn:aws:s3:::bys-dev-s3-cloudfront-service", "arn:aws:s3:::bys-dev-s3-cloudfront-service/*" ] } ] }
- CloudFront의 OAC가 접근 가능해야 한다. CloudFront의 OAC에 대해서 ‘s3:GetObject’가 가능해야 한다. S3 Origin Access
{ "Version": "2012-10-17", "Statement": { "Sid": "AllowCloudFrontServicePrincipalReadOnly", "Effect": "Allow", "Principal": { "Service": "cloudfront.amazonaws.com" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::bys-dev-s3-cloudfront-service/*", "Condition": { "StringEquals": { "AWS:SourceArn": "arn:aws:cloudfront::558846430793:distribution/E1H6SYS9DTGCA" } } } }
- CodeBuild에서 업로드가 가능해야 한다. CodeBuild가 사용하는 role에 대해서 ‘s3:PutObject’가 가능해야 한다.
3. CloudFront 구성
- Origin Domain -
bys-dev-s3-cloudfront-service.s3.ap-northeast-2.amazonaws.com
- Origin access
- Origin access 생성 - Origin access controls 생성.
bys-dev-cloudfront-oac-s3cfn
- Origin access control settings (recommended) -
bys-dev-cloudfront-oac-s3cfn
선택 후 생성
- Origin access 생성 - Origin access controls 생성.
- 생성 완료 후 위의 S3 bucket policy의 cloudfront정보를 업데이트한 후 S3에 반영
4. Test
- CodeCommit - 소스 반영
- CodeBuild - Run build
- S3 - index.html 업로드 확인
- Cloudfront - domain/index.html 주소를 통해 index.html 정상접속 확인