

# 조정 및 로드 밸런싱된 애플리케이션 생성
<a name="walkthrough-autoscaling"></a>

이 연습에서는 조정 및 로드 밸런싱된 애플리케이션을 설정하는 데 도움이 되는 스택을 생성합니다. 이 연습에서는 스택을 생성하는 데 사용할 샘플 템플릿을 제공합니다. 예제 템플릿은 auto scaling, Application Load Balancer, 로드 밸런서 및 Auto Scaling 그룹에 대한 트래픽을 제어하는 보안 그룹, 조정 활동에 대한 알림을 게시하기 위한 Amazon SNS 알림 구성을 제공합니다.

이 템플릿은 하나 이상의 Amazon EC2 인스턴스와 Application Load Balancer를 생성합니다. 이 템플릿에서 스택을 생성할 경우 사용한 AWS 리소스에 대한 요금이 청구됩니다.

## 전체 스택 템플릿
<a name="example-templates-autoscaling-full-stack-template"></a>

템플릿으로 시작하겠습니다.

**YAML**

```
AWSTemplateFormatVersion: 2010-09-09
Parameters:
  InstanceType:
    Description: The EC2 instance type
    Type: String
    Default: t3.micro
    AllowedValues:
      - t3.micro
      - t3.small
      - t3.medium
  KeyName:
    Description: Name of an existing EC2 key pair to allow SSH access to the instances
    Type: AWS::EC2::KeyPair::KeyName
  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'
  OperatorEmail:
    Description: The email address to notify when there are any scaling activities
    Type: String
  SSHLocation:
    Description: The IP address range that can be used to SSH to the EC2 instances
    Type: String
    MinLength: 9
    MaxLength: 18
    Default: 0.0.0.0/0
    ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x.
  Subnets:
    Type: 'List<AWS::EC2::Subnet::Id>'
    Description: At least two public subnets in different Availability Zones in the selected VPC
  VPC:
    Type: AWS::EC2::VPC::Id
    Description: A virtual private cloud (VPC) that enables resources in public subnets to connect to the internet
Resources:
  ELBSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: ELB Security Group
      VpcId: !Ref VPC
      SecurityGroupIngress:
      - IpProtocol: tcp
        FromPort: 80
        ToPort: 80
        CidrIp: 0.0.0.0/0
  EC2SecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: EC2 Security Group
      VpcId: !Ref VPC
      SecurityGroupIngress:
      - IpProtocol: tcp
        FromPort: 80
        ToPort: 80
        SourceSecurityGroupId:
          Fn::GetAtt:
          - ELBSecurityGroup
          - GroupId
      - IpProtocol: tcp
        FromPort: 22
        ToPort: 22
        CidrIp: !Ref SSHLocation
  EC2TargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      HealthCheckIntervalSeconds: 30
      HealthCheckProtocol: HTTP
      HealthCheckTimeoutSeconds: 15
      HealthyThresholdCount: 5
      Matcher:
        HttpCode: '200'
      Name: EC2TargetGroup
      Port: 80
      Protocol: HTTP
      TargetGroupAttributes:
      - Key: deregistration_delay.timeout_seconds
        Value: '20'
      UnhealthyThresholdCount: 3
      VpcId: !Ref VPC
  ALBListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
        - Type: forward
          TargetGroupArn: !Ref EC2TargetGroup
      LoadBalancerArn: !Ref ApplicationLoadBalancer
      Port: 80
      Protocol: HTTP
  ApplicationLoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Scheme: internet-facing
      Subnets: !Ref Subnets
      SecurityGroups:
        - !GetAtt ELBSecurityGroup.GroupId
  LaunchTemplate:
    Type: AWS::EC2::LaunchTemplate
    Properties: 
      LaunchTemplateName: !Sub ${AWS::StackName}-launch-template
      LaunchTemplateData:
        ImageId: !Ref LatestAmiId
        InstanceType: !Ref InstanceType
        KeyName: !Ref KeyName
        SecurityGroupIds: 
          - !Ref EC2SecurityGroup
        UserData:
          Fn::Base64: !Sub |
            #!/bin/bash
            yum update -y
            yum install -y httpd
            systemctl start httpd
            systemctl enable httpd
            echo "<h1>Hello World!</h1>" > /var/www/html/index.html
  NotificationTopic:
    Type: AWS::SNS::Topic
    Properties:
      Subscription:
        - Endpoint: !Ref OperatorEmail
          Protocol: email
  WebServerGroup:
    Type: AWS::AutoScaling::AutoScalingGroup
    Properties:
      LaunchTemplate:
        LaunchTemplateId: !Ref LaunchTemplate
        Version: !GetAtt LaunchTemplate.LatestVersionNumber
      MaxSize: '3'
      MinSize: '1'
      NotificationConfigurations:
        - TopicARN: !Ref NotificationTopic
          NotificationTypes: ['autoscaling:EC2_INSTANCE_LAUNCH', 'autoscaling:EC2_INSTANCE_LAUNCH_ERROR', 'autoscaling:EC2_INSTANCE_TERMINATE', 'autoscaling:EC2_INSTANCE_TERMINATE_ERROR']
      TargetGroupARNs:
        - !Ref EC2TargetGroup
      VPCZoneIdentifier: !Ref Subnets
```

**JSON**

```
{
  "AWSTemplateFormatVersion":"2010-09-09",
  "Parameters":{
    "InstanceType":{
      "Description":"The EC2 instance type",
      "Type":"String",
      "Default":"t3.micro",
      "AllowedValues":[
        "t3.micro",
        "t3.small",
        "t3.medium"
      ]
    },
    "KeyName":{
      "Description":"Name of an existing EC2 key pair to allow SSH access to the instances",
      "Type":"AWS::EC2::KeyPair::KeyName"
    },
    "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"
    },
    "OperatorEmail":{
      "Description":"The email address to notify when there are any scaling activities",
      "Type":"String"
    },
    "SSHLocation":{
      "Description":"The IP address range that can be used to SSH to the EC2 instances",
      "Type":"String",
      "MinLength":9,
      "MaxLength":18,
      "Default":"0.0.0.0/0",
      "ConstraintDescription":"Must be a valid IP CIDR range of the form x.x.x.x/x."
    },
    "Subnets":{
      "Type":"List<AWS::EC2::Subnet::Id>",
      "Description":"At least two public subnets in different Availability Zones in the selected VPC"
    },
    "VPC":{
      "Type":"AWS::EC2::VPC::Id",
      "Description":"A virtual private cloud (VPC) that enables resources in public subnets to connect to the internet"
    }
  },
  "Resources":{
    "ELBSecurityGroup":{
      "Type":"AWS::EC2::SecurityGroup",
      "Properties":{
        "GroupDescription":"ELB Security Group",
        "VpcId":{
          "Ref":"VPC"
        },
        "SecurityGroupIngress":[
          {
            "IpProtocol":"tcp",
            "FromPort":80,
            "ToPort":80,
            "CidrIp":"0.0.0.0/0"
          }
        ]
      }
    },
    "EC2SecurityGroup":{
      "Type":"AWS::EC2::SecurityGroup",
      "Properties":{
        "GroupDescription":"EC2 Security Group",
        "VpcId":{
          "Ref":"VPC"
        },
        "SecurityGroupIngress":[
          {
            "IpProtocol":"tcp",
            "FromPort":80,
            "ToPort":80,
            "SourceSecurityGroupId":{
              "Fn::GetAtt":[
                "ELBSecurityGroup",
                "GroupId"
              ]
            }
          },
          {
            "IpProtocol":"tcp",
            "FromPort":22,
            "ToPort":22,
            "CidrIp":{
              "Ref":"SSHLocation"
            }
          }
        ]
      }
    },
    "EC2TargetGroup":{
      "Type":"AWS::ElasticLoadBalancingV2::TargetGroup",
      "Properties":{
        "HealthCheckIntervalSeconds":30,
        "HealthCheckProtocol":"HTTP",
        "HealthCheckTimeoutSeconds":15,
        "HealthyThresholdCount":5,
        "Matcher":{
          "HttpCode":"200"
        },
        "Name":"EC2TargetGroup",
        "Port":80,
        "Protocol":"HTTP",
        "TargetGroupAttributes":[
          {
            "Key":"deregistration_delay.timeout_seconds",
            "Value":"20"
          }
        ],
        "UnhealthyThresholdCount":3,
        "VpcId":{
          "Ref":"VPC"
        }
      }
    },
    "ALBListener":{
      "Type":"AWS::ElasticLoadBalancingV2::Listener",
      "Properties":{
        "DefaultActions":[
          {
            "Type":"forward",
            "TargetGroupArn":{
              "Ref":"EC2TargetGroup"
            }
          }
        ],
        "LoadBalancerArn":{
          "Ref":"ApplicationLoadBalancer"
        },
        "Port":80,
        "Protocol":"HTTP"
      }
    },
    "ApplicationLoadBalancer":{
      "Type":"AWS::ElasticLoadBalancingV2::LoadBalancer",
      "Properties":{
        "Scheme":"internet-facing",
        "Subnets":{
          "Ref":"Subnets"
        },
        "SecurityGroups":[
          {
            "Fn::GetAtt":[
              "ELBSecurityGroup",
              "GroupId"
            ]
          }
        ]
      }
    },
    "LaunchTemplate":{
      "Type":"AWS::EC2::LaunchTemplate",
      "Properties":{
        "LaunchTemplateName":{
          "Fn::Sub":"${AWS::StackName}-launch-template"
        },
        "LaunchTemplateData":{
          "ImageId":{
            "Ref":"LatestAmiId"
          },
          "InstanceType":{
            "Ref":"InstanceType"
          },
          "KeyName":{
            "Ref":"KeyName"
          },
          "SecurityGroupIds":[
            {
              "Ref":"EC2SecurityGroup"
            }
          ],
          "UserData":{
            "Fn::Base64":{
              "Fn::Join":[
                "",
                [
                  "#!/bin/bash\n",
                  "yum update -y\n",
                  "yum install -y httpd\n",
                  "systemctl start httpd\n",
                  "systemctl enable httpd\n",
                  "echo \"<h1>Hello World!</h1>\" > /var/www/html/index.html"
                ]
              ]
            }
          }
        }
      }
    },
    "NotificationTopic":{
      "Type":"AWS::SNS::Topic",
      "Properties":{
        "Subscription":[
          {
            "Endpoint":{
              "Ref":"OperatorEmail"
            },
            "Protocol":"email"
          }
        ]
      }
    },
    "WebServerGroup":{
      "Type":"AWS::AutoScaling::AutoScalingGroup",
      "Properties":{
        "LaunchTemplate":{
          "LaunchTemplateId":{
            "Ref":"LaunchTemplate"
          },
          "Version":{
            "Fn::GetAtt":[
              "LaunchTemplate",
              "LatestVersionNumber"
            ]
          }
        },
        "MaxSize":"3",
        "MinSize":"1",
        "NotificationConfigurations":[
          {
            "TopicARN":{
              "Ref":"NotificationTopic"
            },
            "NotificationTypes":[
              "autoscaling:EC2_INSTANCE_LAUNCH",
              "autoscaling:EC2_INSTANCE_LAUNCH_ERROR",
              "autoscaling:EC2_INSTANCE_TERMINATE",
              "autoscaling:EC2_INSTANCE_TERMINATE_ERROR"
            ]
          }
        ],
        "TargetGroupARNs":[
          {
            "Ref":"EC2TargetGroup"
          }
        ],
        "VPCZoneIdentifier":{
          "Ref":"Subnets"
        }
      }
    }
  }
}
```

## 템플릿 연습
<a name="example-templates-autoscaling-description"></a>

이 템플릿의 첫 번째 부분에서는 `Parameters`를 지정합니다. 각 파라미터마다 CloudFormation이 스택을 프로비저닝 할 실행 시간에 대한 값을 할당해야 합니다. 템플릿 뒷부분에 지정된 리소스는 이러한 값을 참조하고 데이터를 사용합니다.
+ `InstanceType`: Amazon EC2 Auto Scaling에서 프로비저닝하는 EC2 인스턴스의 유형입니다. 지정하지 않으면 기본적으로 `t3.micro`가 사용됩니다.
+ `KeyName`: 인스턴스에 대한 SSH 액세스를 허용하는 기존 EC2 키 페어입니다.
+ `LatestAmiId`: 인스턴스의 Amazon Machine Image(AMI)입니다. 지정하지 않으면 AWS에서 유지 관리하는 AWS Systems Manager 퍼블릭 파라미터를 사용하여 Amazon Linux 2 AMI로 인스턴스가 시작됩니다. 자세한 내용은 **AWS Systems Manager 사용 설명서의 [Finding public parameters](https://docs.aws.amazon.com/systems-manager/latest/userguide/parameter-store-finding-public-parameters.html)를 참조하세요.
+ `OperatorEmail`: 조정 활동 알림을 보낼 이메일 주소입니다.
+ `SSHLocation`: SSH를 인스턴스에 연결하는 데 사용할 수 있는 IP 주소 범위입니다.
+ `Subnets`: 서로 다른 가용 영역에 두 개 이상의 퍼블릭 서브넷을 보유해야 합니다.
+ `VPC`: 퍼블릭 서브넷의 리소스를 인터넷에 연결하는 계정의 Virtual Private Cloud(VPC)입니다.
**참고**  
기본 VPC와 기본 서브넷을 사용하여 인스턴스가 인터넷에 액세스하도록 허용할 수 있습니다. 자체 VPC를 사용 중인 경우, 작업 중인 지역의 각 가용 영역에 매핑된 서브넷이 VPC에 있는지 확인합니다. 로드 밸런서를 생성하려면 사용 가능한 퍼블릭 서브넷이 최소한 두 개 있어야 합니다.

이 템플릿의 다음 부분에서는 `Resources`를 지정합니다. 이 섹션에서는 스택 리소스와 해당 속성을 지정합니다.

[https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-securitygroup.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-securitygroup.html) 리소스 `ELBSecurityGroup` 
+ `SecurityGroupIngress`에는 **모든 IP 주소(“CidrIp”: “0.0.0.0/0")에서 포트 80에 액세스할 수 있도록 하는 TCP 수신 규칙이 포함되어 있습니다.

[https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-securitygroup.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-securitygroup.html) 리소스 `EC2SecurityGroup` 
+ `SecurityGroupIngress`에는 두 가지 수신 규칙, 즉 1) `SSHLocation` 입력 파라미터에 제공하는 IP 주소 범위에서 SSH(포트 22)에 액세스하도록 허용하는 TCP 수신 규칙과 2) 로드 밸런서의 보안 그룹을 지정하여 로드 밸런서에서 액세스하도록 허용하는 TCP 수신 규칙이 포함되어 있습니다. [GetAtt](resources-section-structure.md#resource-properties-getatt) 함수는 논리명이 `ELBSecurityGroup`인 보안 그룹의 ID를 가져오는 데 사용됩니다.

[AWS::ElasticLoadBalancingV2::TargetGroup](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-elasticloadbalancingv2-targetgroup.html) 리소스 `EC2TargetGroup`
+ `Port`, `Protocol` 및 `HealthCheckProtocol`은 `ApplicationLoadBalancer`에서 트래픽을 라우팅하고 Elastic Load Balancing에서 EC2 인스턴스의 상태를 확인하는 데 사용되는 EC2 인스턴스 포트(80) 및 프로토콜(HTTP)을 지정합니다.
+ `HealthCheckIntervalSeconds`는 EC2 인스턴스에서 상태 확인 간에 30초의 간격을 두도록 합니다. `HealthCheckTimeoutSeconds`는 Elastic Load Balancing이 상태를 확인할 대상의 응답을 기다리는 시간의 길이로 정의됩니다(이 예에서는 15초). 제한 시간이 지난 후에는 Elastic Load Balancing이 EC2 인스턴스의 상태 확인을 비정상으로 표시합니다. EC2 인스턴스가 세 번 연속 상태 확인(`UnhealthyThresholdCount`)에 실패할 경우 Elastic Load Balancing은 해당 인스턴스에서 5회 연속 정상 상태 확인(`HealthyThresholdCount`)이 있을 때까지 해당 EC2 인스턴스에 대한 트래픽 라우팅을 중지합니다. 5회 연속 정상 상태 확인 시점에 Elastic Load Balancing은 인스턴스를 정상으로 간주하고 인스턴스에 대한 트래픽 라우팅을 다시 시작합니다.
+ `TargetGroupAttributes`는 대상 그룹의 등록 취소 지연 값을 20초로 업데이트합니다. 기본적으로 Elastic Load Balancing은 등록 취소 프로세스를 완료하기 전에 300초 동안 기다립니다.

[AWS::ElasticLoadBalancingV2::Listener](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-elasticloadbalancingv2-listener.html) 리소스 `ALBListener`
+ `DefaultActions`는 로드 밸런서가 수신하는 포트, 로드 밸런서가 요청을 전달하는 대상 그룹 및 요청을 라우팅하는 데 사용되는 프로토콜을 지정합니다.

[AWS::ElasticLoadBalancingV2::LoadBalancer](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-elasticloadbalancingv2-loadbalancer.html) 리소스 `ApplicationLoadBalancer`
+ `Subnets`은 `Subnets` 입력 파라미터 값을 로드 밸런서 노드가 생성될 퍼블릭 서브넷 목록으로 가져옵니다.
+ `SecurityGroup`은 로드 밸런서 노드에서 수신 트래픽을 제어하기 위해 가상 방화벽 역할을 하는 보안 그룹의 ID를 가져옵니다. [GetAtt](resources-section-structure.md#resource-properties-getatt) 함수는 논리명이 `ELBSecurityGroup`인 보안 그룹의 ID를 가져오는 데 사용됩니다.

[AWS::EC2::LaunchTemplate](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-launchtemplate.html) 리소스 `LaunchTemplate`
+ `ImageId`는 사용할 AMI로 `LatestAmiId` 입력 파라미터 값을 가져옵니다.
+ `KeyName`은 사용할 EC2 키 페어로 `KeyName` 입력 파라미터 값을 가져옵니다.
+ `SecurityGroupIds`는 EC2 인스턴스에서 수신 트래픽을 제어하기 위해 가상 방화벽 역할을 하는 논리명이 `EC2SecurityGroup`인 보안 그룹의 ID를 가져옵니다.
+ `UserData`는 인스턴스가 가동되어 실행된 후에 실행되는 구성 스크립트입니다. 이 예제에서 스크립트는 Apache를 설치하고 index.html 파일을 생성합니다.

[AWS::SNS::Topic](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-sns-topic.html) 리소스 `NotificationTopic`
+ `Subscription`은 조정 활동이 있을 때 알림 수신자의 이메일 주소로 `OperatorEmail` 입력 파라미터 값을 가져옵니다.

[AWS::AutoScaling::AutoScalingGroup](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-autoscaling-autoscalinggroup.html) 리소스 `WebServerGroup`
+ `MinSize` 및 `MaxSize`는 auto scaling의 최소 및 최대 EC2 인스턴스 수를 설정합니다.
+ `TargetGroupARNs`는 논리명이 `EC2TargetGroup`인 대상 그룹의 ARN을 가져옵니다. 이 auto scaling은 규모를 조정하면서 이 대상 그룹에 인스턴스를 자동으로 등록 및 등록 취소합니다.
+ `VPCZoneIdentifier`는 `Subnets` 입력 파라미터 값을 EC2 인스턴스가 생성될 수 있는 퍼블릭 서브넷 목록으로 가져옵니다.

## 1단계: 스택 시작
<a name="example-templates-autoscaling-launch-stack"></a>

스택을 시작하기 전에 Amazon EC2, Amazon EC2 Auto Scaling, AWS Systems Manager, Elastic Load Balancing, Amazon SNS, CloudFormation 등의 서비스를 모두 사용할 수 있는 AWS Identity and Access Management(IAM) 권한이 있는지 확인합니다.

다음 절차에는 파일에서 샘플 스택 템플릿을 업로드하는 절차가 포함됩니다. 로컬 시스템에서 텍스트 편집기를 열고 템플릿 중 하나를 추가합니다. `sampleloadbalancedappstack.template` 이름으로 파일을 저장합니다.

**스택 템플릿을 시작하려면**

1. AWS Management Console에 로그인하여 [https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/)에서 CloudFormation 콘솔을 엽니다.

1. **스택 생성**, **새 리소스 사용(표준)**를 선택합니다.

1. **템플릿 지정**에서 **템플릿 파일 업로드**, **파일 선택**을 차례로 선택하여 `sampleloadbalancedappstack.template` 파일을 업로드하세요.

1. **다음**을 선택합니다.

1. **스택 세부 정보 지정** 페이지에 스택 이름(예: **SampleLoadBalancedAppStack**)을 입력합니다.

1. **파라미터**에서 스택의 매개 변수를 검토하고 **OperatorEmail**, **SSHLocation**, **KeyName**, **VPC**, **서브넷**을 포함하여 기본값이 없는 모든 파라미터의 값을 제공합니다.

1. **다음**을 두 번 선택합니다

1. **검토** 페이지에서 설정을 검토하고 확인합니다.

1. **제출**을 선택합니다.

   CloudFormation 콘솔의 **상태** 열에서 스택의 상태를 볼 수 있습니다. CloudFormation에서 스택이 생성되면 **CREATE\_COMPLETE** 상태가 표시됩니다.
**참고**  
스택을 생성한 후 구독을 확인해야 이메일 주소로 알림 수신을 시작할 수 있습니다. 자세한 정보는 *Amazon EC2 Auto Scaling 사용 설명서*의 [auto scaling 조정 시 Amazon SNS 알림 수신](https://docs.aws.amazon.com/autoscaling/ec2/userguide/ec2-auto-scaling-sns-notifications.html)을 참조하세요.

## 2단계: 샘플 리소스 정리
<a name="example-templates-autoscaling-clean-up"></a>

사용하지 않은 샘플 리소스에 요금이 부과되지 않도록 하려면 스택을 삭제하세요.

**스택을 삭제하려면**

1. CloudFormation 콘솔에서 **SampleLoadBalancedAppStack** 스택을 선택합니다.

1. **삭제**를 선택합니다.

1. 확인 메시지에서 **스택 삭제**를 선택합니다.

   **SampleLoadBalancedAppStack**의 상태가 **DELETE\_IN\_PROGRESS**로 변경됩니다. CloudFormation에서 스택 삭제를 완료하면 목록에서 해당 스택이 제거됩니다.

이 연습의 샘플 템플릿을 사용하여 자체 스택 템플릿을 구축합니다. 자세한 내용은 Amazon EC2 Auto Scaling 사용 설명서**의 [Tutorial: Set up a scaled and load-balanced application](https://docs.aws.amazon.com/autoscaling/ec2/userguide/tutorial-ec2-auto-scaling-load-balancer.html)을 참조하세요.