Amazon EC2에 웹 애플리케이션 배포

시작 안내서

모듈 1: 인프라 생성

이 모듈에서는 AWS CDK 스택, 인바운드 액세스 권한이 있는 보안 그룹, IAM 인스턴스 프로파일을 생성합니다.

소개

웹 애플리케이션을 배포하기 전에 Amazon EC2 인스턴스와 지원 리소스를 생성해야 합니다. 이 모듈에서는 새로운 AWS CDK 앱을 생성하고 리소스에 대한 종속성을 설치한 다음 마지막으로 Amazon EC2 인스턴스, 인바운드 액세스 권한이 있는 보안 그룹, IAM 인스턴스 프로파일을 정의합니다. 또한 CDK의 도움을 받아 인스턴스 액세스에 사용할 키 페어를 생성합니다.

배우게 될 내용

  • 새로운 AWS CDK 앱 생성
  • 필요한 리소스에 대해 종속성 설치
  • CDK 앱에 리소스 정의

 완료 시간

10분

 모듈 선행 조건

  • 관리자 수준의 액세스 권한이 있는 AWS 계정**
  • 권장 브라우저: 최신 버전의 Chrome 또는 Firefox

[**]생성된 지 24시간이 지나지 않은 계정은 이 자습서를 완료하는 데 필요한 서비스에 액세스할 권한이 아직 없을 수 있습니다.

구현

CDK 앱 생성

먼저 CDK가 설치되어 있는지 확인합니다. 아직 설치하지 않았다면 AWS CDK를 사용하여 시작하기 가이드를 따라하면 됩니다.

cdk --verison

이제 언어로는 TypeScript를 가용해 CDK 애플리케이션 골격을 생성합니다.

mkdir ec2-cdk
cd ec2-cdk
cdk init app --language typescript

이는다음 내용을 출력합니다.

Applying project template app for typescript
# Welcome to your CDK TypeScript project!

This is a blank project for TypeScript development with CDK.

The `cdk.json` file tells the CDK Toolkit how to execute your app.

## Useful commands

 * `npm run build`   compile typescript to js
 * `npm run watch`   watch for changes and compile
 * `npm run test`    perform the jest unit tests
 * `cdk deploy`      deploy this stack to your default AWS account/region
 * `cdk diff`        compare deployed stack with current state
 * `cdk synth`       emits the synthesized CloudFormation template

Executing npm install...
✅ All done!

다음 메시지가 표시된다면 지원된 명령어를 사용하고 npm update를 실행해 CDK 버전을 업그레이드하는 것이 좋습니다.

****************************************************
*** Newer version of CDK is available [1.122.0]  ***
*** Upgrade recommended (npm install -g aws-cdk) ***
****************************************************

# npm install -g aws-cdk
# npm update

리소스 스택에 대한 코드 생성

파일 /lib/cdk-ecs-infra-stack.ts로 이동합니다. 생성하려는 리소스 스택에 대한 코드를 작성할 위치입니다.

리소스 스택은 특정 계정에 프로비저닝 될 클라우드 인프라 리소스의 집합(이 가이드 수행의 경우 모든 AWS 리소스)입니다. 해당 리소스가 프로비저닝될 계정/리전을 스택에 구성할 수 있습니다.

이 리소스 스택에서는 다음의 리소스를 생성하게 됩니다.

  • IAM 역할: 이 역할은 다른 AWS 서비스를 호출할 수 있도록 EC2 인스턴스에 할당됩니다.
  • EC2 인스턴스: 웹 에플리케이션을 호스트하는 데에 사용할 가상 머신입니다.
  • 보안 그룹: 웹 애플리케이션에 대한 인바운드 요청을 허용하는 가상 방화벽입니다.
  • EC2 SSH 키 페어: SSH에서 인스턴스로 모든 명령을 실행하여 설정하기 위해 사용하는 자격 증명의 집합입니다.

EC2 인스턴스 생성

EC2 인스턴스 및 기타 리소스 생성을 시작하기 위해 먼저 정확한 모듈을 가져와야 합니다.

npm i @aws-cdk/aws-ec2 @aws-cdk/aws-iam @aws-cdk/aws-s3-assets cdk-ec2-key-pair

그런 다음 lib/cdk-eb-infra-stack.ts 파일을 편집해 @aws-cdk/core에 대한 기존 가져오기 아래에서 파일 최상단에 종속성을 추가합니다.

import * as ec2 from "@aws-cdk/aws-ec2";            // Allows working with EC2 and VPC resources
import * as iam from "@aws-cdk/aws-iam";            // Allows working with IAM resources
import * as s3assets from "@aws-cdk/aws-s3-assets"; // Allows managing files with S3
import * as keypair from "cdk-ec2-key-pair";        // Helper to create EC2 SSH keypairs
import * as path from "path";                       // Helper for working with file paths

해당 모듈은 웹 애플리케이션 배포에 필요한 모든 구성 요소에 대한 액세스를 제공합니다. 첫 단계로는 // The code that defines your stack goes here 라인아래에 다음 코드를 추가하여 계정 내에 있는 기존 기본 VPC를 찾습니다.

// The code that defines your stack goes here
      
      // Look up the default VPC
      const vpc = ec2.Vpc.fromLookup(this, "VPC", {
        isDefault: true
      });

cdk-ec2-key-pair 패키지를 사용해 SSH 키 페어를 생성하고 AWS Secrets Manager에 저장합니다.

 // Create a key pair to be used with this EC2 Instance
    const key = new keypair.KeyPair(this, "KeyPair", {
      name: "cdk-keypair",
      description: "Key Pair created with CDK Deployment",
    });
    key.grantReadOnPublicKey; 

이제 2개의 규칙을 추가하여 어디에서나 SSH 및 HTTP 액세스를 허용하도록 보안 그룹을 생성합니다. 어디에서나 SSH 액세스가 가능한 옵션은 테스트 환경에서 짧은 시간 동안만 허용할 수 있으며 프로덕션 환경에서는 안전하지 않음을 기억하세요. 또한 EC2 인스턴스에 대한 IAM 역할을 생성하여 다른 AWS 서비스를 호출하고 AWS Secrets Manager(SSH 퍼블릭 키가 저장되는 위치) 외부에서 구성을 읽도록 사전 구축된 정책을 연결합니다.

// Security group for the EC2 instance
    const securityGroup = new ec2.SecurityGroup(this, "SecurityGroup", {
      vpc,
      description: "Allow SSH (TCP port 22) and HTTP (TCP port 80) in",
      allowAllOutbound: true,
    });

    // Allow SSH access on port tcp/22
    securityGroup.addIngressRule(
      ec2.Peer.anyIpv4(),
      ec2.Port.tcp(22),
      "Allow SSH Access"
    );

    // Allow HTTP access on port tcp/80
    securityGroup.addIngressRule(
      ec2.Peer.anyIpv4(),
      ec2.Port.tcp(80),
      "Allow HTTP Access"
    );

    // IAM role to allow access to other AWS services
    const role = new iam.Role(this, "ec2Role", {
      assumedBy: new iam.ServicePrincipal("ec2.amazonaws.com"),
    });

    // IAM policy attachment to allow access to 
    role.addManagedPolicy(
      iam.ManagedPolicy.fromAwsManagedPolicyName("AmazonSSMManagedInstanceCore")
    );

이제 사전 구축 Amazon Machine Image(AMI)를 사용해 EC2 인스턴스를 생성할 준비가 되었습니다. 이 안내서의 경우 Amazon Linux 2 하나를 X86_64 CPU 아키텍처에 대해 사용할 것입니다. 또한 생성한 IAM 역할, 기본 VPC, 실행할 인스턴스 유형(여기서는 1개 vCPU 및 메모리 1GB가 있는 t2.micro)을 전달합니다. 사용 가능한 다양한 인스턴스 유형은 여기에서 확인할 수 있습니다.

// Look up the AMI Id for the Amazon Linux 2 Image with CPU Type X86_64
    const ami = new ec2.AmazonLinuxImage({
      generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2,
      cpuType: ec2.AmazonLinuxCpuType.X86_64,
    });
// Create the EC2 instance using the Security Group, AMI, and KeyPair defined.
    const ec2Instance = new ec2.Instance(this, "Instance", {
      vpc,
      instanceType: ec2.InstanceType.of(
        ec2.InstanceClass.T2,
        ec2.InstanceSize.MICRO
      ),
      machineImage: ami,
      securityGroup: securityGroup,
      keyName: key.keyPairName,
      role: role,
    });

이제 AWS CDK 스택을 정의해 Amazon EC2 인스턴스, 인바운드 액세스 권한이 있는 보안 그룹, IAM 인스턴스 프로파일을 생성했습니다. 스택을 배포하기 전에, 애플리케이션을 실행할 호스트 OS에 패키지를 설치하고 애플리케이션 코드를 인스턴스에 복사해야 합니다. 

이제 ec2-cdk-stack.ts 파일의 내용은 다음과 같습니다.

import * as cdk from '@aws-cdk/core';
import * as ec2 from "@aws-cdk/aws-ec2"; // Allows working with EC2 and VPC resources
import * as iam from "@aws-cdk/aws-iam"; // Allows working with IAM resources
import * as s3assets from "@aws-cdk/aws-s3-assets"; // Allows managing files with S3
import * as keypair from "cdk-ec2-key-pair"; // Helper to create EC2 SSH keypairs
import * as path from "path"; // Helper for working with file paths

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

    // The code that defines your stack goes here
          
    // Look up the default VPC
    const vpc = ec2.Vpc.fromLookup(this, "VPC", {
      isDefault: true
    });

    // Create a key pair to be used with this EC2 Instance
    const key = new keypair.KeyPair(this, "KeyPair", {
      name: "cdk-keypair",
      description: "Key Pair created with CDK Deployment",
    });
    key.grantReadOnPublicKey; 

    // Security group for the EC2 instance
    const securityGroup = new ec2.SecurityGroup(this, "SecurityGroup", {
      vpc,
      description: "Allow SSH (TCP port 22) and HTTP (TCP port 80) in",
      allowAllOutbound: true,
    });

    // Allow SSH access on port tcp/22
    securityGroup.addIngressRule(
      ec2.Peer.anyIpv4(),
      ec2.Port.tcp(22),
      "Allow SSH Access"
    );

    // Allow HTTP access on port tcp/80
    securityGroup.addIngressRule(
      ec2.Peer.anyIpv4(),
      ec2.Port.tcp(80),
      "Allow HTTP Access"
    );

    // IAM role to allow access to other AWS services
    const role = new iam.Role(this, "ec2Role", {
      assumedBy: new iam.ServicePrincipal("ec2.amazonaws.com"),
    });

    // IAM policy attachment to allow access to 
    role.addManagedPolicy(
      iam.ManagedPolicy.fromAwsManagedPolicyName("AmazonSSMManagedInstanceCore")
    );

    // Look up the AMI Id for the Amazon Linux 2 Image with CPU Type X86_64
    const ami = new ec2.AmazonLinuxImage({
      generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2,
      cpuType: ec2.AmazonLinuxCpuType.X86_64,
    });

    // Create the EC2 instance using the Security Group, AMI, and KeyPair defined.
    const ec2Instance = new ec2.Instance(this, "Instance", {
      vpc,
      instanceType: ec2.InstanceType.of(
        ec2.InstanceClass.T2,
        ec2.InstanceSize.MICRO
      ),
      machineImage: ami,
      securityGroup: securityGroup,
      keyName: key.keyPairName,
      role: role,
    });
  }
}

결론

이 모듈에서는 웹 애플리케이션을 EC2 인스턴스에 배포하는 데 필요한 모든 인프라를 생성하기 위해 CDK 애플리케이션을 생성하는 방법을 배웠습니다. 다음 모듈에서는 EC2 인스턴스 부팅 시 모든 OS 패키지를 설치하고 구성하며 코드를 인스턴스에 배포하여 인스턴스를 구성하는 방법을 배웁니다.

다음 차례: 자동 구성

내용이 마음에 드셨는지요.