

# 첫 번째 스택 생성
<a name="gettingstarted.walkthrough"></a>

이 주제에서는 AWS Management Console을 사용하여 첫 번째 CloudFormation 스택을 생성하는 방법을 설명합니다. 이 자습서를 따르면 기본 AWS 리소스를 프로비저닝하고 스택 이벤트를 모니터링하고 출력을 생성하는 방법을 배울 수 있습니다.

이 예제에서 CloudFormation 템플릿은 YAML로 작성됩니다. YAML은 인프라를 코드로 정의하는 데 널리 사용되는 사람이 읽을 수 있는 형식입니다. CloudFormation에 대한 학습을 계속하다 보면 JSON 형식의 다른 템플릿도 접할 수 있지만 이 자습서에서는 가독성을 위해 YAML을 선택했습니다.

**참고**  
CloudFormation은 무료이지만 생성하는 Amazon EC2 및 Amazon S3 리소스에 대해서는 요금이 부과됩니다. 그러나 AWS를 처음 사용하는 경우 [프리 티어](https://aws.amazon.com/free/)를 활용하여 이 학습 프로세스 중에 비용을 최소화하거나 제거할 수 있습니다.

**Topics**
+ [사전 조건](#getting-started-prerequisites)
+ [콘솔을 사용하여 CloudFormation 스택 생성](#getting-started-create-stack)
+ [스택 생성 모니터링](#getting-started-monitor-stack-creation)
+ [웹 서버 테스트](#getting-started-test-web-server)
+ [문제 해결](#getting-started-troubleshooting)
+ [정리](#getting-started-clean-up)
+ [다음 단계](#getting-started-next-steps)

## 사전 조건
<a name="getting-started-prerequisites"></a>
+ Amazon EC2, Amazon S3 및 CloudFormation을 사용할 수 있는 권한을 보유한 IAM 사용자 또는 역할이 있는 AWS 계정에 대한 액세스 권한 또는 관리 사용자 액세스 권한이 있어야 합니다.
+ 인터넷에 액세스할 수 있는 가상 프라이빗 클라우드(VPC)가 있어야 합니다. 이 연습 템플릿에는 최신 AWS 계정과 함께 자동으로 제공되는 기본 VPC가 필요합니다. 기본 VPC가 없거나 삭제된 경우에 적용되는 다른 해결 방법은 이 주제의 문제 해결 섹션을 참조하세요.

## 콘솔을 사용하여 CloudFormation 스택 생성
<a name="getting-started-create-stack"></a>

**콘솔을 사용하여 Hello World CloudFormation 스택을 생성하려면**

1. [CloudFormation 콘솔](https://console.aws.amazon.com/cloudformation/)을 엽니다.

1. **스택 생성**을 선택합니다.

1. **스택 생성** 페이지에서 **Infrastructure Composer에서 빌드**를 선택한 다음 **Infrastructure Composer에서 생성**을 선택합니다. 그러면 예제 템플릿을 업로드하고 검증할 수 있는 CloudFormation 콘솔 모드의 Infrastructure Composer로 이동합니다.

1. 예제 템플릿을 업로드하고 검증하려면 다음을 수행합니다.

   1. **템플릿**을 선택합니다. 다음 CloudFormation 템플릿을 복사하여 템플릿 편집기에 붙여넣습니다.

      ```
      AWSTemplateFormatVersion: 2010-09-09
      Description: CloudFormation Template for WebServer with Security Group and EC2 Instance
      
      Parameters:
        LatestAmiId:
          Description: The latest Amazon Linux 2 AMI from the Parameter Store
          Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
          Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2'
      
        InstanceType:
          Description: WebServer EC2 instance type
          Type: String
          Default: t2.micro
          AllowedValues:
            - t3.micro
            - t2.micro
          ConstraintDescription: must be a valid EC2 instance type.
          
        MyIP:
          Description: Your IP address in CIDR format (e.g. 203.0.113.1/32).
          Type: String
          MinLength: '9'
          MaxLength: '18'
          Default: 0.0.0.0/0
          AllowedPattern: '^(\d{1,3}\.){3}\d{1,3}\/\d{1,2}$'
          ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x.
      
      Resources:
        WebServerSecurityGroup:
          Type: AWS::EC2::SecurityGroup
          Properties:
            GroupDescription: Allow HTTP access via my IP address
            SecurityGroupIngress:
              - IpProtocol: tcp
                FromPort: 80
                ToPort: 80
                CidrIp: !Ref MyIP
      
        WebServer:
          Type: AWS::EC2::Instance
          Properties:
            ImageId: !Ref LatestAmiId
            InstanceType: !Ref InstanceType
            SecurityGroupIds:
              - !Ref WebServerSecurityGroup
            UserData: !Base64 |
              #!/bin/bash
              yum update -y
              yum install -y httpd
              systemctl start httpd
              systemctl enable httpd
              echo "<html><body><h1>Hello World!</h1></body></html>" > /var/www/html/index.html
      
      Outputs:
        WebsiteURL:
          Value: !Join
            - ''
            - - http://
              - !GetAtt WebServer.PublicDnsName
          Description: Website URL
      ```

      다음 단계로 넘어가기 전에 템플릿을 살펴보고 몇 가지 주요 CloudFormation 개념을 이해하는 시간을 갖도록 하겠습니다.
      + **`Parameters`** 섹션은 스택을 생성할 때 템플릿으로 전달할 수 있는 값을 선언합니다. 템플릿 뒷부분에 지정된 리소스는 이러한 값을 참조하고 데이터를 사용합니다. 파라미터는 템플릿 자체에 저장하고 싶지 않은 정보를 지정하는 효과적인 방법입니다. 또한 배포 중인 특정 애플리케이션 또는 구성에 고유할 수 있는 정보를 지정하는 방법이기도 합니다.
      + 템플릿에서 정의하는 파라미터는 다음과 같습니다.
        + **`LatestAmiId`** - AWS Systems Manager Parameter Store에서 최신 Amazon Linux 2 AMI ID를 검색합니다.
        + **`InstanceType`** - EC2 인스턴스 유형을 선택할 수 있습니다(기본값: `t2.micro`, 허용: `t3.micro`, `t2.micro`).
        + **`MyIP`** - HTTP 액세스의 IP 주소 범위를 지정합니다(기본값: 0.0.0.0/0, 모든 IP에서 액세스 허용).
      + **`Resources`** 섹션에는 이 템플릿으로 생성하려는 AWS 리소스에 대한 정의가 포함됩니다. 리소스 선언은 한 번에 모든 구성 설정을 지정할 수 있는 효율적인 방법입니다. 템플릿에 리소스 선언을 포함하면 해당 템플릿을 사용하여 스택을 생성함으로써 선언된 모든 리소스를 생성 및 구성할 수 있습니다. 동일한 템플릿에서 새 스택을 생성하여 동일한 구성의 리소스를 시작할 수도 있습니다.
      + 이 템플릿은 다음 리소스를 만듭니다.
        + **`WebServerSecurityGroup`** - 지정된 IP 범위에서 포트 80의 인바운드 HTTP 트래픽을 허용하는 EC2 보안 그룹입니다.
        + **`WebServer`** - 다음 구성의 EC2 인스턴스입니다.
          + 최신 Amazon Linux 2 AMI를 사용합니다.
          + 선택한 인스턴스 유형을 적용합니다.
          + `SecurityGroupIds` 속성에 `WebServerSecurityGroup`을 추가합니다.
          + Apache HTTP Server를 설치하기 위한 사용자 데이터 스크립트가 포함되어 있습니다.
      + 논리명은 각 리소스 및 파라미터 선언의 시작 부분에 지정됩니다. 예를 들어 `WebServerSecurityGroup`은 EC2 보안 그룹 리소스에 할당된 논리명입니다. 그런 다음 `Ref` 함수를 사용하여 템플릿의 다른 부분에서 논리명으로 리소스 및 파라미터를 참조합니다. 한 리소스가 다른 리소스를 참조하면 리소스 간에 종속성이 생성됩니다.
      + 이 **`Outputs`** 섹션에서는 스택 생성 후 반환되는 사용자 지정 값을 정의합니다. 출력 값을 사용하여 리소스 식별자 또는 URL과 같은 스택의 리소스 정보를 반환할 수 있습니다.
      + 템플릿은 하나의 출력을 정의합니다.
        + **`WebsiteURL`** - EC2 인스턴스의 퍼블릭 DNS 이름을 사용하여 구성된 배포된 웹 서버의 URL입니다. `Join` 함수는 `http://`와 변수 `PublicDnsName`을 단일 문자열로 결합하여 웹 서버의 전체 URL을 쉽게 출력할 수 있도록 합니다.

   1. 템플릿을 업로드하기 전에 YAML 코드가 유효한지 확인하려면 **검증**을 선택합니다.

   1. 그런 다음 **템플릿 생성**을 선택하여 템플릿을 생성하고 S3 버킷에 추가합니다.

   1. 나중에 삭제할 수 있도록 열리는 대화 상자에서 S3 버킷의 이름을 기록해 둡니다. 그런 다음 **확인 후 CloudFormation 계속 진행**을 선택합니다. 그러면 이제 템플릿에 대한 S3 경로가 지정되어 있는 CloudFormation 콘솔로 이동합니다.

1. **스택 생성** 페이지에서 **다음**을 선택합니다.

1. **스택 세부 정보 지정** 페이지의 **스택 이름** 필드에 이름을 입력합니다. 스택 이름에는 공백이 있어서는 안 됩니다. **MyTestStack**를 입력하세요.

1. **파라미터**에서 다음과 같이 파라미터 값을 지정합니다.
   + **LatestAmiId**: 기본적으로 최신 Amazon Linux 2 AMI로 설정됩니다.
   + **InstanceType**: EC2 인스턴스 유형으로 **t2.micro** 또는 **t3.micro**를 선택합니다.
**참고**  
AWS를 처음 사용하는 경우 프리 티어를 사용하여 12개월 동안 무료로 `t2.micro` 인스턴스를 시작하고 사용할 수 있습니다(`t2.micro`를 사용할 수 없는 리전에서는 프리 티어에서 `t3.micro` 인스턴스를 사용할 수 있음).
   + **MyIP**: `/32` 접미사를 사용하여 실제 퍼블릭 IP 주소를 지정합니다. `/32` 접미사는 CIDR 표기법에서 단일 IP 주소를 허용하도록 지정하는 데 사용됩니다. 이는 기본적으로 이 특정 IP 주소와의 트래픽을 허용하고 다른 IP 주소는 허용하지 않음을 의미합니다.

1. **다음**을 두 번 선택하여 **검토 및 생성** 페이지로 이동합니다. 이 자습서에서는 **스택 옵션 구성** 페이지의 기본값을 그대로 둘 수 있습니다.

1. 스택에 대한 정보를 검토합니다. 설정에 만족하면 **제출**을 클릭합니다.

## 스택 생성 모니터링
<a name="getting-started-monitor-stack-creation"></a>

**제출**을 선택하면 CloudFormation이 템플릿에 지정된 리소스를 생성하기 시작합니다. **CloudFormation** 콘솔의 윗부분에 있는 목록에 새로운 스택 **MyTestStack**이 나타납니다. 상태는 `CREATE_IN_PROGRESS`과 같아야 합니다. 스택의 이벤트를 보고 스택에 대한 자세한 상태를 확인할 수 있습니다.

**스택에 대한 이벤트를 보려면**

1. CloudFormation 콘솔에서 목록 내 스택 **MyTestStack**을 선택합니다.

1. 스택 세부 정보 창에서 [**이벤트(Events)**] 탭을 선택합니다.

   콘솔은 60초마다 최신 이벤트로 이벤트 목록을 자동으로 새로 고칩니다.

**이벤트** 탭에는 스택을 생성하는 각 주요 단계가 각 이벤트의 시간 순으로 정렬되어 표시됩니다. 즉, 최신 이벤트가 맨 위에 표시됩니다.

(이벤트 목록의 맨 아래 있는) 첫 번째 이벤트가 스택 생성 프로세스의 시작입니다.

`2024-12-23 18:54 UTC-7 MyTestStack CREATE_IN_PROGRESS User initiated`

다음은 각 리소스의 생성 시작 및 완료를 표시하는 이벤트입니다. 예를 들어, EC2 인스턴스가 생성되면 다음 항목이 나타납니다.

`2024-12-23 18:59 UTC-7 WebServer CREATE_COMPLETE`

`2024-12-23 18:54 UTC-7 WebServer CREATE_IN_PROGRESS Resource creation initiated`

`CREATE_IN_PROGRESS` 이벤트는 CloudFormation에서 리소스 생성이 시작되었다고 보고할 때 로깅됩니다. `CREATE_COMPLETE` 이벤트는 리소스를 성공적으로 생성한 경우에 로깅됩니다.

CloudFormation에서 스택을 성공적으로 생성하면 [**이벤트(Events)**] 탭 맨 위에 다음 이벤트가 표시됩니다.

`2024-12-23 19:17 UTC-7 MyTestStack CREATE_COMPLETE`

CloudFormation에서 리소스를 생성할 수 없는 경우 `CREATE_FAILED` 이벤트를 보고하고 기본적으로 스택을 롤백한 다음 생성된 리소스를 모두 삭제합니다. **상태 사유** 열에는 실패를 일으키는 문제가 표시됩니다.

스택이 생성된 후 **리소스** 탭으로 이동하여 생성한 EC2 인스턴스 및 보안 그룹을 확인할 수 있습니다.

## 웹 서버 테스트
<a name="getting-started-test-web-server"></a>

스택이 성공적으로 생성되면 CloudFormation 콘솔의 **출력** 탭으로 이동합니다. **WebsiteURL** 필드를 찾습니다. 여기에는 EC2 인스턴스의 퍼블릭 URL이 있습니다.

브라우저를 열고 **WebsiteURL**에 나열된 URL로 이동합니다. 브라우저에 간단한 "Hello World\$1" 메시지가 표시됩니다.

이를 통해 EC2 인스턴스가 Apache HTTP Server를 실행하고 기본 웹 페이지를 제공하고 있음을 확인할 수 있습니다.

## 문제 해결
<a name="getting-started-troubleshooting"></a>

스택 생성 중에 롤백이 발생하는 경우, VPC 누락 때문일 수 있습니다. 이 문제를 해결하는 방법은 다음과 같습니다.

### 사용 가능한 기본 VPC 없음
<a name="getting-started-troubleshooting-no-default-vpc"></a>

이 연습의 템플릿에는 기본 VPC가 필요합니다. VPC 또는 서브넷 가용성 오류로 인해 스택 생성에 실패하는 경우, 계정에 기본 VPC가 없기 때문일 수 있습니다. 다음과 같은 옵션이 있습니다.
+ **새 기본 VPC 생성** - Amazon VPC 콘솔을 통해 새 기본 VPC를 생성할 수 있습니다. 자세한 지침은 *Amazon VPC 사용 설명서*의 [기본 VPC 생성](https://docs.aws.amazon.com/vpc/latest/userguide/work-with-default-vpc.html#create-default-vpc)을 참조하세요.
+ **템플릿을 수정하여 서브넷 지정** - 기본 VPC 이외의 VPC가 있는 경우 템플릿을 수정하여 VPC 및 서브넷 ID를 명시적으로 지정할 수 있습니다. 템플릿에 다음 파라미터를 추가합니다.

  ```
    SubnetId:
      Description: The subnet ID to launch the instance into
      Type: AWS::EC2::Subnet::Id
  ```

  그런 다음 서브넷 ID를 포함하도록 `WebServer` 리소스를 업데이트합니다.

  ```
    WebServer:
      Type: AWS::EC2::Instance
      Properties:
        ImageId: !Ref LatestAmiId
        InstanceType: !Ref InstanceType
        SecurityGroupIds:
          - !Ref WebServerSecurityGroup
        SubnetId: !Ref SubnetId
        UserData: !Base64 |
          #!/bin/bash
          yum update -y
          yum install -y httpd
          systemctl start httpd
          systemctl enable httpd
          echo "<html><body><h1>Hello World!</h1></body></html>" > /var/www/html/index.html
  ```

  스택을 생성할 때, 웹 서버에 연결할 수 있도록 인터넷 액세스가 가능한 서브넷을 지정해야 합니다.

## 정리
<a name="getting-started-clean-up"></a>

불필요한 서비스에 대해 요금이 청구되지 않도록 하려면 스택 및 리소스를 삭제하려 정리할 수 있습니다. 스택의 템플릿을 저장하는 S3 버킷을 삭제할 수도 있습니다.

**스택 및 스택의 리소스를 삭제하려면**

1. [CloudFormation 콘솔](https://console.aws.amazon.com/cloudformation/)을 엽니다.

1. **스택** 페이지에서 생성한 스택의 이름(**MyTestStack**) 옆에 있는 옵션을 선택한 다음 **삭제**를 선택합니다.

1. 확인 메시지가 나타나면 **삭제**를 선택합니다.

1. **이벤트** 탭에서 스택 삭제 프로세스의 진행 상황을 모니터링합니다. **MyTestStack**의 상태를 `DELETE_IN_PROGRESS`로 변경합니다. CloudFormation에서 스택 삭제를 완료하면 목록에서 해당 스택이 제거됩니다.

예제 템플릿 작업을 마쳤는데 더 이상 Amazon S3 버킷이 필요하지 않은 경우 버킷을 삭제합니다. 버킷을 삭제하려면 먼저 버킷을 비워야 합니다. 버킷을 비우면 버킷 내 모든 객체가 삭제됩니다.

**Amazon S3 버킷을 비우고 삭제하려면**

1. [Amazon S3 콘솔](https://console.aws.amazon.com/s3/)을 엽니다.

1. 콘솔 왼쪽의 탐색 창에서 **버킷**을 선택합니다.

1. **버킷** 목록에서 이 자습서를 위해 생성한 버킷의 이름 옆에 있는 옵션을 선택한 다음 **비우기**를 선택합니다.

1. **버킷 비우기** 페이지에서 텍스트 필드에 **permanently delete**를 입력하여 버킷을 비우려는 의사를 확정한 후 **비우기**를 선택합니다.

1. [**버킷 비우기: 상태(Empty bucket: Status)**] 페이지에서 버킷 비우기 프로세스의 진행 상황을 모니터링합니다.

1. 버킷 목록으로 돌아가려면 **종료**를 선택합니다.

1. 버킷의 이름 옆에 있는 옵션을 선택한 다음 **삭제**를 선택합니다.

1. 확인 메시지가 나타나면 버킷의 이름을 입력한 다음 **버킷 삭제**를 선택합니다.

1. **버킷** 목록에서 버킷 삭제 프로세스의 진행 상황을 모니터링합니다. Amazon S3가 버킷 삭제를 완료하면 목록에서 해당 버킷을 제거합니다.

## 다음 단계
<a name="getting-started-next-steps"></a>

축하합니다\$1 성공적으로 스택을 생성하고, 생성을 모니터링하고, 출력을 사용했습니다.

계속 학습하려면:
+ 템플릿을 직접 생성할 수 있도록 템플릿에 대해 자세히 알아봅니다. 자세한 내용은 [CloudFormation 템플릿 작업](template-guide.md) 섹션을 참조하세요.
+ 템플릿 생성에 대한 실습을 더 해보려면 [CloudFormation 시작하기](https://catalog.us-east-1.prod.workshops.aws/workshops/df7f72cf-4f10-4664-acb6-b30dc8d4bcf0/en-US) 워크숍을 참조하세요.
+ [CloudFormation 시작하기](https://catalog.us-east-1.prod.workshops.aws/workshops/df7f72cf-4f10-4664-acb6-b30dc8d4bcf0/en-US)의 단축 버전은 [Amazon EC2에 애플리케이션 배포](deploying.applications.md) 섹션을 참조하세요. 이 주제에서는 `cfn-init`라는 CloudFormation 헬퍼 스크립트를 사용하여 Amazon EC2 인스턴스를 부트스트래핑하는, 동일한 시나리오를 설명합니다.