VPC Peering으로 다른 AWS 계정의 S3에 파일 업로드하기

VPC peering과 VPC interface endpoint(privatelink)를 이용하여 비공개망으로 다른 계정의 S3에 파일을 업로드하는 방법을 기재한 글입니다
2021.12.28

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

안녕하세요 클래스메소드의 수재입니다.
이번에 다른 AWS 계정의 S3에 파일을 업로드하는 작업이 있었습니다.
다른 계정의 버킷에 업로드를 하기 위한 다양한 방법을 검토해보던 중 VPC Peering과 S3를 가지고 있는 계정의 VPC endpoint를 이용하여 인터넷망을 사용하지 않고 AWS 네트워크만을 이용하는 방법이 있어 글로 남깁니다.
(인터넷을 경유하지 않고 다른 계정의 버킷에 파일을 업로드 하는 것만이 목적이라면 VPC Gateway Endpoint를 사용하면 됩니다.)

구성

VPC peering이 설정되지 않은 환경은 다음과 같습니다.
VPC peering을 설정하면 다음과 같은 환경으로 구성됩니다.

설정해보기

VPC endpoint란?

VPC 엔드포인트는 VPC와 지원되는 AWS 서비스 및 AWS PrivateLink로 지원하는 VPC 엔드포인트 서비스 간에 프라이빗 연결을 활성화합니다. AWS PrivateLink는 프라이빗 IP 주소를 사용하여 서비스에 비공개로 액세스할 수 있는 기술입니다 - 공식 문서

공개망을 통과하지 않고 AWS 망을 통과하여 통신할 수 있도록 지원하는 서비스입니다. 인터페이스 유형(AWS privatelink) 및 게이트웨이 유형이 있습니다.
본 글에서는 인터페이스 유형을 이용합니다.
엔드포인트 자체의 요금도 발생합니다.
상세한 내용은 위의 공식 문서를 참고해주세요.

전제 조건

본 글에서는 NAT gateway의 설정은 따로 기재하지 않습니다.
피어링 연결을 생성하고 파일을 업로드하는 계정을 계정 A
S3를 가지고 있는 계정을 계정 B 라고 합니다.

작업 순서

본 글에서는 VPC peering 설정부터 작업합니다.

  1. 피어링 설정
  2. 엔드포인트 설정
  3. S3 작성 및 정책 설정
  4. EC2에서 파일 업로드

피어링 설정

계정 A에서 계정 B로 피어링 연결을 생성합니다.
VPC 콘솔의 [피어링 연결]에서 연결을 생성합니다.
피어링을 연결할 계정 A의 VPC를 선택합니다.
그리고 계정 B의 ID 및 VPC ID를 기입합니다.

생성하면 계정 B에서 연결을 허가할 때 까지 수락 대기중(Pending acceptance) 상태가 됩니다.
계정 B로 로그인하여 VPC 콘솔의 피어링 연결에서 수락 대기 중인 연결을 클릭하여 [작업 - 요청 수락]으로 피어링 연결을 완료합니다.
수락 후에 잠시 기다리면 수락 대기중 이었던 상태가 활성으로 바뀝니다.

이어서 피어링 연결을 생성한 VPC의 프라이빗 라우팅 테이블에 피어링 경로를 추가합니다.
대상(Destination)에는 상대 계정 VPC의 범위를 기입합니다.

엔드포인트 설정

계정 B에서 S3 인터페이스 엔드포인트를 설정합니다.
그전에 엔드포인트에 적용할 보안 그룹을 생성합니다.
계정 A에 peering 된 VPC의 cidr 블록으로부터 오는 연결을 허용하도록 인바운드를 설정합니다.

이후 VPC 콘솔의 [엔드포인트]에서 엔드포인트를 생성합니다.
interface 타입으로 서비스를 선택하고 대상 VPC와 방금 생성한 보안 그룹을 선택합니다. 필요하다면 정책도 설정합니다.

S3 작성

계정 B에서 S3를 작성 후 정책을 변경합니다.
기존에 사용하던 S3를 그대로 사용한다면 정책만을 변경합니다.
저는 sujae-peering-test-1 이라는 버킷을 생성하고 다음과 같이 정책을 설정하였습니다.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DelegateS3Access",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::{계정 A의 ID}:role/{계정 A의 EC2에 설정되는 역할 이름}"
            },
            "Action": [
                "s3:*"
            ],
            "Resource": [
                "arn:aws:s3:::sujae-peering-test-1",
                "arn:aws:s3:::sujae-peering-test-1/*"
            ]
        }
    ]
}

EC2에서 파일 업로드

마지막으로 EC2에서 파일을 업로드해봅니다.
S3에 업로드 할 수 있는 역할을 EC2에 적용합니다.
방금 계정 B에서 S3 정책으로 설정한 {계정 A의 EC2에 설정되는 역할 이름}으로 역할 이름을 설정합니다.

이 후 내부 EC2에 접속하여 기본 방식으로 S3에 파일을 업로드 해 봅니다.

aws s3 cp test.txt s3://sujae-peering-test-1/test.txt

NAT gateway가 연결되어 있기 때문에 문제없이 업로드가 가능했습니다. 이후 라우팅 테이블에서 NAT gateway의 경로를 삭제하겠습니다.

이어서 엔드포인트를 경유하여 업로드해보겠습니다. 이때 엔드포인트의 URL이 필요한데 여기서 확인할 수 있습니다.

아래의 커맨드에 해당 URL을 대입하여 실행한 뒤 접속이 가능한지 확인해봅니다.
만약 오류가 발생한다면 피어링 연결, 버킷 정책, 엔드포인트 URL 등을 다시 확인해봅니다.

# aws s3 --endpoint-url https://bucket.{엔드포인트의 url} ls s3://{버킷명}
aws s3 --endpoint-url https://bucket.vpce-0700000000000-1234567.s3.ap-northeast-1.vpce.amazonaws.com ls s3://sujae-peering-test-1

아까 업로드한 test.txt가 확인되면 이어서 업로드를 해봅니다.

# aws s3 --endpoint-url https://bucket.{엔드포인트의 url} cp s3://{버킷명}/test2.txt
aws s3 --endpoint-url https://bucket.vpce-0700000000000-1234567.s3.ap-northeast-1.vpce.amazonaws.com cp test.txt s3://sujae-peering-test-1/test2.txt

버킷에서 test2.txt를 확인할 수 있다면 성공입니다.

이외의 설정

엔드포인트에 대한 상세한 설명은 공식문서를 확인해주세요.

버킷과의 통신만이 통과하도록 엔드포인트의 정책을 설정할 수 있습니다.

{
  "Version": "2012-10-17",
  "Id": "Policy1415115909151",
  "Statement": [
    { "Sid": "Access-to-specific-bucket-only",
      "Principal": "*",
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Effect": "Allow",
      "Resource": ["arn:aws:s3:::DOC-EXAMPLE-BUCKET1",
                   "arn:aws:s3:::DOC-EXAMPLE-BUCKET1/*"]
    }
  ]
}

또한 S3의 정책에서도 엔드포인트를 통한 접근만 허용하도록 설정할 수 있습니다.

{
  "Version": "2012-10-17",
  "Id": "Policy1415115909152",
  "Statement": [
    { "Sid": "Access-to-specific-VPCE-only",
      "Principal": "*",
      "Action": "s3:*",
      "Effect": "Deny",
      "Resource": ["arn:aws:s3:::DOC-EXAMPLE-BUCKET2",
                   "arn:aws:s3:::DOC-EXAMPLE-BUCKET2/*"],
      "Condition": {"StringNotEquals": {"aws:sourceVpce": "vpce-1a2b3c4d"}}
    }
  ]
}

위 설정의 상세한 설명은 공식 문서를 참고해주세요.

마치며

이렇게 VPC peering을 이용하여 공개망을 통과하지 않는 S3 업로드 방식을 알아보았습니다.
privatelink는 S3로의 업로드 뿐만 아니라 다양한 서비스와 연계하여 사용하는 경우가 많으니 꼭 한번 알아보시길 바랍니다.

이상 긴 글 읽어주셔서 감사합니다.
내용 및 오탈자 피드백은 언제나 환영합니다. must01940 지메일로 보내주시면 감사합니다.