반응형
250x250
Notice
Recent Posts
Recent Comments
Link
«   2024/12   »
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 인프라 구축하기 - #3 보안 그룹과 RDBMS 본문

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

CDK로 AWS 인프라 구축하기 - #3 보안 그룹과 RDBMS

가온아 2022. 6. 14. 12:26

이번에는 보안 그룹을 생성해보고 MySQL ( serverless v1 포함)를 추가해 보겠습니다.

보안그룹 생성은 중복되는 요소들이 많아 별도의 생성함수를 만들고, 보안 그룹을 중복 사용되는 경우도 있으므로 dictionary에 저장하여 관리하고 사용할 수 있도록 만들어 보겠습니다. 아래는 보안 그룹을 생성하는 함수의 예 입니다.

.
//	credential과 database 관련 lib를 import
import * as rds from 'aws-cdk-lib/aws-rds';
import { Credentials, DatabaseInstance, DatabaseInstanceEngine, DatabaseSecret, MysqlEngineVersion } from 'aws-cdk-lib/aws-rds'

.
.
.
  // 보안 그룹 생성 함수
  createSecurityGroup(name:string, vpc:ec2.Vpc, desc:string, bAllOutbound:boolean, ingressRules:any){
    const sg = new ec2.SecurityGroup(
      this, name, {
      vpc,
      description: desc,
      allowAllOutbound: bAllOutbound
    });

    ingressRules.forEach((item:any) => 
      sg.addIngressRule(
        (item.ipv4 === 'any') ? ec2.Peer.anyIpv4() : ec2.Peer.ipv4(item.ipv4),
        (typeof item.port === 'number') ? ec2.Port.tcp(item.port) : ec2.Port.tcpRange(item.port[0], item.port[1]),
        item.desc
      )
    );

    return sg;
  }
.
.

(구글링으로 쉽게 검색 가능한 내용들을 굳이 이 글에서 다시 언급하지 않고 가능한 링크로 대체하겠습니다. SecurityGroup CDK Document Link , Ingress / inbound 용어 Link )

위 함수를 아래와 같이 호출하여 사용할 수 있습니다.

const sg = this.createSecurityGroup(
    'web_80_only_on_public', 	// security group name
    vpc,
    '80 port for web service',	//	desc
    true, 						// allowAllOutbound
    [
    	{ipv4:'any', port:80, desc:'80 port for web service'}, 
        {ipv4:'1.214.1.32/32', port:443, desc:'443 port for management'}, 
    ]	//	ingress rules, outgress가 필요하면 인자를 추가하여 사용하세요.
);

(* 코드 블럭 작성하다 문득 미드 실리콘벨리의 시즌 4에서 주인공 토마스가 여자친구와 tab, space 가지고 다투는 장면이 떠오르네요. Nerd가 다 그렇죠 뭐... 도찐개찐)

생성된 보안 그룹을 아래와 같이 dictionary에 넣고 필요할 때 재활용 할 수 있습니다.

  build_SecurityGroup(vpc:ec2.Vpc){
    let list_sg:  {[name:string] : ec2.SecurityGroup} = {};
    list_sg.web_80_only_on_public = this.createSecurityGroup('web_80_only_on_public', vpc, '80 port for web service',true, 
      [{ipv4:'any', port:80, desc:'80 port for web service'}]
    );
    list_sg.web_3000_for_private = this.createSecurityGroup('web_3000_for_private', vpc, '3000 and 443 port for web service on private subnet',true, 
      [ {ipv4:'10.0.0.0/16', port:3000, desc:'3000 and 443 port for web service on private subnet'},
        {ipv4:'any', port:443, desc:'443 port for private link'}
      ]
    );

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

이제 RDBMS(MySQL)를 추가하는 함수도 만들어 보겠습니다. (CDK RDS 관련 링크)  

  // cluster가 아닌 인스턴스로 생성하는 예제입니다. 
  // cluster 구성이 필요하면 위 문서 링크의 rds.DatabaseCluster를 참고하세요.
  build_rdb(vpc:ec2.Vpc, name:string, instanceIdentifier:string, credsSecretName:string, creds:DatabaseSecret){
    const m3_rdb = new DatabaseInstance(this, name, {
      vpcSubnets: {
        onePerAz: true,
        subnetType: ec2.SubnetType.PRIVATE_WITH_NAT
      },
      credentials: Credentials.fromSecret(creds), // credential 생성은 아래에서 다시 언급합니다.
      vpc: vpc,
      port: 3306,
      databaseName: 'hello-mysql',
      allocatedStorage: 20,
      instanceIdentifier,
      engine: DatabaseInstanceEngine.mysql({
        version: MysqlEngineVersion.VER_8_0
      }),
      // defaults to m5.large
      instanceType: ec2.InstanceType.of(ec2.InstanceClass.T2, ec2.InstanceSize.LARGE)
    });
  }

아래는 Serverless cluster (링크)를 구성하는 함수입니다. v2는 쿼리 편집기를 지원하지 않기 때문에 v1으로 생성자로 살펴보겠습니다.

  build_rdb_serverless(vpc:ec2.Vpc, creds:DatabaseSecret){
    const cluster = new rds.ServerlessCluster(this, 'hello-mysql-cluster', {
      engine: rds.DatabaseClusterEngine.AURORA_MYSQL,
      credentials: Credentials.fromSecret(creds),
      vpc,
      enableDataApi: true, // 쿼리 분석기 사용을 위해 활성화해야 합니다.
      deletionProtection: false, // 중요한 데이터라면 true로 설정하세요.
    });
  }

serverless v2 는 2022년 4월에 릴리즈되어 서울 리전에서도 사용 가능합니다. 단, 쿼리 분석기는 지원하지 않지만 이 문서를 참고해 보시면 v2를 사용하는게 개꿀!! 이라는거... 하지만 ... 비쌉니다!!

위 샘플 코드에서 credential 관련 내용은 빠져 있습니다. 이는 아래와 같이 secret manager에 생성하여 관리하면 됩니다.

    .
    .
    const instanceIdentifier = 'hello-rds'
    const credsSecretName = `/${id}/rds/creds/${instanceIdentifier}`.toLowerCase()
    const creds = new DatabaseSecret(this, 'hello-rdb-credentials', {
        secretName: credsSecretName,
        username: 'admin'
    });
    this.build_rdb_serverless(vpc, creds);
    .
    .

다음에는 마지막으로 CDK를 이용해 ECS를 포함해 Web 서비스를 구축하는 샘플을 살펴 보겠습니다. 

(* 저는 제 자신과 제 작업을 이어받을 분들을 위해 이 블로그를 정리합니다. 구글 검색하다 제 블로그 글이 나오면 즐겁고 허망한 느낌이 같이 들긴 하지만 공들여 정리한 보람을 느낀달까... 이러다보니 사실 가능한 코드 위주로 글을 정리합니다. 가끔은 너무 설명이 부족하다 싶을만큼 상세 설명이 없다고 저도 생각하지만 코드를 보시면 대부분 이해할거라 생각합니다. 코드 모르는 분들이 이 글을 보실리도 없고... ^^a 상세 설명 등은 가능한 공식 문서 링크를 남기니 그곳을 참고하세요.

공식문서 혹은 구글링해도 잘 이해가 안되는 내용이 있으면 댓글을 남겨주세요. 늦게라도 보고 꼭 답변 남기겠습니다.)

반응형