반응형
250x250
Notice
Recent Posts
Recent Comments
Link
«   2024/03   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
Archives
Today
Total
관리 메뉴

가끔 보자, 하늘.

CDK로 AWS 인프라 구축하기 - #2 VPC 생성 코드 작성하기 본문

개발 이야기/인프라 구축 및 운영

CDK로 AWS 인프라 구축하기 - #2 VPC 생성 코드 작성하기

가온아 2022. 6. 13. 15:19

이번에는 API 공신 문서를 살펴보고 AWS Console 에서 VPC 생성 시 생성되는 모든 리소스를 직접 생성하는 재활용 가능한 코드를 만들어 보겠습니다. 

API 문서

API 공식 문서 링크 - https://docs.aws.amazon.com/cdk/api/v2/docs/aws-construct-library.html

현재 CDK 는 v1과 v2 (https://docs.aws.amazon.com/cdk/api/versions.html)를 제공하고 있으며 우리는 v2를 기준으로 알아보겠습니다.

API 문서를 살펴보신 분은 어떤 리소스를 생성하는 몇 가지 방법이 있다는 것을 알고 계실 겁니다. 예를 들어 VPC를 생성할 때 class Vpc를 사용하거나 혹은 class CfnVPC를 사용할 수 있습니다. 이에 대한 상세한 내용은 https://docs.aws.amazon.com/cdk/v2/guide/constructs.html 이 문서에서 확인할 수 있습니다. 간단히 정리하자면 Construct library를 Layer 1부터 3까지 제공하면 Cfnxxx 라고 명명된 construct를 layer 1(줄여서 L1)이라고 칭하며 모든 리소스 props들의 설정을 상세히 명시해야 합니다.

아래 코드로 각각 실행해 보시면 어떤 차이가 있는지 확인하실 수 있습니다.

// L1 Construct로 VPC를 생성

import { Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as ec2 from 'aws-cdk-lib/aws-ec2';

export class HelloStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

	new ec2.CfnVPC(this, 'HelloVpc', {
		cidrBlock: "10.0.0.0/16"
  	});
  }
}

이렇게 L1 construct로 리소스를 생성하면 default로 제공되는 설정이 없어 명시된 내용만으로 VPC가 생성되었음을 확인할 수 있습니다. 위 코드에는 cidrBlock만 명시했기 때문에 subnet도, gateway도 추가되지 않은 것을 확인할 수 있습니다.

// L2 Construct로 VPC를 생성

import { Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as ec2 from 'aws-cdk-lib/aws-ec2';

export class HelloStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    new ec2.Vpc(this, 'HelloVpc', {
        maxAzs: 2,
        vpcName : 'vpcHello',
    });
  }
}

반면 L2 construct로 VPC를 생성하면  subnet을 포함 여러 리소스가 같이 생성되는 것을 확인할 수 있습니다. 필요에 따라 두 형태의 class를 혼용하여 사용해도 무방하므로 제공되는 default 설정 및 props를 확인하여 필요한 class를 사용하시면 됩니다.

재활용 가능한 VPC 생성 코드 작성하기

AWS Console -> VPC에서 VPC 생성을 시도하면 아래와 같은 화면을 보실 수 있습니다. 버튼 클릭으로 필요한 여러 설정을 손쉽게 생성할 수 있는데, 이번에는 이를 CDK로 구현하고 재활용 가능한 코드로 만들어 보겠습니다. 위에서 살펴본 class VPC를 사용하면 이름을 지정한 것만으로 필요한 모든 구성을 설정할 수 있으나 랜덤으로 생성되는 각종 서비스 이름때문에 오히려 관리하기가 힘들기도 합니다. 이런 문제를 해소하기 위해 우리가 원하는 값으로 설정하는 방법을 같이 알아보겠습니다.

AWS Console 혹은 CDK L2 VPC Construct로 VPC 생성하면 기본 VPC 외에도 subnet, Routing Table, Internet Gateway, Elastic IP,  Network ACL이 같이 생성됩니다. VPC의 이름값을 전달하면 대부분의 리소스 이름은 "Stack명/VPC명/Subnet명"+"Subnet" + AZIndex(1~4) 로 명명됩니다. 그리고 기본적으로 네 개의 tag가 추가되어 VPC 이름(이 예에서는 Hello)으로 검색하면 손쉽게 찾을 수 검색할 수 있습니다.

두 개의 가용영역을 가진 VPC를 구성해 보겠습니다. 인스턴스 없이 VPC만을 도식화 하면 아래와 같습니다.

더 진행하기 전에 VPC에 대한 몇 가지 알아둬야 할 사항들을 정리해 두었습니다. 본문의 내용 중 생소한 내용들이 있다면 아래 "더보기"를 눌러 가볍게 읽어 보시기 바랍니다.

더보기

사설망 대역  - RFC1918에 따라 사설망의 IP 대역은 다음과 같이 구분하여 사용합니다.

   The Internet Assigned Numbers Authority (IANA) has reserved the
   following three blocks of the IP address space for private internets:

     10.0.0.0        -   10.255.255.255  (10/8 prefix)
     172.16.0.0      -   172.31.255.255  (172.16/12 prefix)
     192.168.0.0     -   192.168.255.255 (192.168/16 prefix)

서브넷 - 어떤 네트워크 영역을 논리적/물리적으로 나눈 부분 네트워크를 말합니다. 서브넷의 영역을 구분하기 위해 서비스 마스크를 사용합니다. AWS에서는 서브넷 별로 기본 라우터가 생성되며 이를 통해 서브넷 간 통신을 기본적으로 보장합니다.

가용영역 - AWS 의 문서 참고(링크)

라우팅 - 위키 (링크) , 게이트웨이 - 위키 (링크)

NAT 게이트웨이 - NAT(네트워크 주소 변환, Network Address Translation) 서비스로 비공인 네트워크에 속한 여러 개의 호스트가 하나의 공인 IP 주소를 이용하여 인터넷에 접속할 수 있도록 할 수 있습니다. 이를 이용해 Private subnet의 인스턴스들이 외부로 접근하여 정보를 취할 수 있으며, 외부에서의 접근은 차단할 수 있습니다.

인터넷 게이트웨이 - VPC 내 인스턴스에서 기본적으로 인터넷 접근이 차단되어 있습니다. 어떤 서브넷의 라우터 내 라우팅 테이블에 인터넷 게이트웨이를 연결한 것을 퍼블릭 서브넷이라고 부릅니다.

네크워크 ACL - 1개 이상의 서브넷 내부와 외부 트래픽을 제어하기 위한 방화벽 역할을 합니다. 서브넷 레벨에서의 통신 규칙을 정의하며 해당 서브넷의 모든 인스턴스에 자동 적용됩니다. (링크)

보안그룹 - 특정 인스턴스의 방화벽 역할을 수행합니다.

위 도식화된 VPC를 아래와 같은 코드로 생성할 수 있습니다. 가용영역을 지정하지 않으면 기본적으로 a~d 순서대로 생성되므로 임의로 ap-northeast-2a와 ap-northeast-2c로 지정했습니다. (가용영역은 지역별로 상황이 다를 수 있습니다. 2022년 6월 기준, 한국은 네 개의 리전을 가진 국가에 속하며 mysql serverless를 사용할 경우 a,c 가용영역을 지정해야 사용할 수 있는 등 - 물리적인 공간 제약이 있다고 합니다.- 생각보다 고려해야 할 사항들이 있습니다.)

import { Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as ec2 from 'aws-cdk-lib/aws-ec2';

export class HelloStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

	const vpc = this.build_VPC('Hello');
	if(vpc != null){
		//	do something
	}
  }

  get availabilityZones(): string[] {
    return ['ap-northeast-2a', 'ap-northeast-2c'];
  }

  build_VPC(_id:string){
	try{
	    const vpc = new ec2.Vpc(this, _id, {
	        maxAzs: 2,
	        vpcName : _id,
	        subnetConfiguration: [
	          {
	            subnetType: ec2.SubnetType.PUBLIC,
	            cidrMask: 24,
	            name: 'public'
	          },
	          {
	            subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
	            cidrMask: 24,
	            name: 'private'
	          },
	        ]
	    });
	    return vpc;
    }catch(e){
      console.log("ERROR in build_VPC ", _id , " > ", e);
      return null;
    }
  }  
}

가용영역은 maxAzs값에 따라 자동으로 설정되나 availabilityZones을 위와 같이 별도 설정하는 방법을 제공합니다. (링크 참조

이제 deploy해서 정상적으로 생성되는지 여부를 확인해 본 후 추가 요금이 발생하지 않도록  destroy하시기 바랍니다.

cdk deploy
.
.
.
cdk destroy

이상으로 L2 construct로 VPC를 생성해 보았습니다. 추후 L1 construct로 구성하는 것도 시간되면 정리해 보겠습니다.

다음으로 private, public subnet을 위한 보안 그룹을 추가하고 RDBMS를 추가해 보겠습니다. 그럼 이만... :)

반응형