gony-dev 님의 블로그

Section 18. AWS CloudFormation 본문

AWS

Section 18. AWS CloudFormation

minarinamu 2024. 10. 16. 13:38

AWS CloudFormation

CloudFormation은 코드를 사용하여 AWS 인프라의 모든 리소스를 정의하는 방법이다.
원하는 것을 선언하고  선언문을 말하면 CloudFormation은 사용자가 지정한 정확한 구성을 사용하여 올바른 순서로 해당 항목을 생성한다.

수동 구성이나 수동 작업이 필요없으며 자동으로 프로비저닝 된다.

CloudFormation이 어떻게 구성되어 있는지 확인하고 싶다면 'Application Composer'를 사용하여 이 인프라를 시각화하여 볼 수 있다.

 

1. CloudFormation을 사용하는 이유?

  1. 코드로 표현된 인프라이다.
    • 이 말은 리소스가 수동으로 생성되지 않기에 제어 측면에서 매우 뛰어남을 뜻한다.
    • Git 등을 사용하여 버전 제어에 사용될 수 있다.
    • 인프라에 대한 모든 변경 사항은 코드 변경을 통해 검토된다.
  2. 비용
    • 스택 내의 모든 리소스에는 식별자로 태그가 지정되므로 스택이 어떻게 얼마나 청구되는지 쉽게 확인할 수 있다.
    • 리소스 비용을 추정할 수 있다.
    • 절약 전략을 세울 수 있다.
  3. 생산성
    • 클라우드에서 인프라를 즉시 파괴후 재창조할 수 있기에 좋다.
    • 템플릿에 대한 다이어그램을 자동으로 생성할 수 있다.
    • 선언적 프로그래밍이다.(리소스 생성 순서와 조정 작업을 고민할 필요가 없다.)
  4. 관심사 분리 원칙
    • 많은 애플리케이션과 계층에 대해 많은 CloudFormation 스택을 생성할 수 있다.
    • VPC, Network, App 스택을 원할 수 있다.
  5. 재구성 불필요
    • 불필요하게 새로 만들 필요가 없는데, 웹의 기존 템플릿과 설명서를 활용하여 CloudFormation 템플릿을 신속히 작성할 수 있기 때문이다.

2. CloudFormation 작동 원리

  • 템플릿들은 S3에 업로드되어 CloudFormation에 참조되어야 한다.
    • 그 후에 스택이 생성된다.
    • CloudStack은 AWS 리소스로 구성되어 있으며 AWS에서 생성할 수 있는 모든 종류의 것이 될 수 있습니다.
  • 템플릿을 업데이트하려는 경우 이전 템플릿을 편집할 수 없다!
    • 만일 원한다면 새 버전의 템플릿을 AWS에 다시 업로드한 다음 스택을 업데이트해야 한다.
  • 스택은 이름으로 식별되며, 스택을 지운다면 CloudFormation으로 생성된 모든 단일 아티팩트와 리소스가 삭제된다.

스택을 업데이트하는 옵션

3. CloudFormation Templates를 배포하는 방법

  • Manual way
    1. Application Composer나 코드 편집기를 사용하여 템플릿을 생성하고 콘솔을 사용하여 파라미터 등을 입력하는 수동적인 방법이다.
    2. 전체 과정을 볼 수 있다는 점에서 유용하다.

  • Automated way
    1. 템플릿을 YAML 파일로 편집한 다음, 템플릿을 배포하기 위한 AWS CLI를 사용하거나 지속성 전달 도구를 사용하여 배포할 수 있다.
    2. 이는 흐름과 인프라를 완전히 자동화하려는 경우 권장된다.

4. Building Blocks

  • 템플릿 구성요소
    1. AWSTemplateFormatVersion | 템플릿을 읽는 방법을 정의
    2. Description | 템플릿에 대한 설명
    3. Resource | 템플릿에 선언된 모든 AWS 리소스를 정의하는 필수적 섹션이다.
    4. Parameter | 템플릿에 대한 동적 입력
    5. Mappings | 템플릿에 대한 정적 변수
    6. Outputs | 템플릿에서 생성된 내용에 대해 참조를 얻는 것
    7. Conditionals | 리소스 생성을 수행하기 위한 조건 목록
  • 템플릿 도우미
    1. References
    2. Functions

CloudFormation - Resources

  • 리소스는 CloudFormation 템플릿의 핵심이다.(유일한 필수 섹션!!!!!!!)
  • 리소스는 템플릿의 일부로 생성 및 구성될 다양한 AWS 구성 요소를 나타낸다.
  • AWS가 리소스 생성, 업데이트, 삭제를 자동으로 파악한다.(700개 이상의 리소스가 있음).
  •  리소스 유형 식별자는 다음과 같다.
    • service-provider::service-name::data-type-name
    • 서비스 공급자 뒤에 콜론이 2개 붙고, 서비스 이름 뒤에 콜론이 2개 붙고 데이터 유형 이름이 나온다.
  • 많은 수의 리소스를 넣을 수 있으며 리소스에 대한 설명은 아래 사이트에 있다.
    • https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html

CloudFormation - Parameters

  • 파라미터는 CloudFormation 템플릿에 입력을 제공하는 방법이다.
  • 템플릿을 회사 전체에서 재사용하여 많은 사람들이 다양한 파라미터를 설정할 수 있게 하고 싶다면 파라미터에 대해 잘 알아야 한다.
    • 그 이유는 파라미터는 선입력으로 받을 수 없기 때문이다.
  • 파라미터는 유형을 활용하여 템플릿에서 오류가 나는 것을 방지할 수도 있다.

1. 파라미터를 사용해야 하는 시기?

 

어느 것이 파라미터이여야 하는지 아닌지를 정의할 때, "이 CloudFormation 리소스 구성이 향후 변경될 가능성이 있는가?"에 대해 물어보아야한다.

  • 만일 그렇다면, 해당 값을 업데이트할 때마다 콘텐츠를 변경하기 위해 템플릿을 다시 업로드할 필요가 없도록 파라미터로 만드는 것이 좋다.
  • 미리 결정할 수 없는 경우에는 파라미터로 만들어야 한다.

2. 파라미터 설정

  1. 유형
    1. String
    2. Number
    3. 다양한 목록 유형들
    4. AWS 특정 파라미터
  2.  설명
  3. 제약 조건 설명
  4. 최소 및 최대 길이, 값
  5. 허용되는 패턴의 정규 표현식 등

아래 사진을 보면 AllowedValues 파라미터 예시가 나와있다.

  • 지금 예시는 허용되는 값을 t2.micro, t2.small, t2.medium으로 정의했으며, 기본값은 t2.micro이고 이 파라미터는 EC2 인스턴스에서 재사용된다.
  • 이 덕분에 우리는 드롭다운을 갖게되고 사용자는 이 세 가지 값 중 하나만 선택할 수 있으므로 우리는 제어권, 사용자는 선택권을 가진다.

  • 파라미터를 참조하는 방법
    • 파라미터는 템플릿 내에 어디에나 사용될 수 있다.
    • "!Ref MyVPC"에서 느낌표를 붙임으로서 약칭으로 사용한다.
    • 위의 함수를 사용하면 파라미터를 참조할 수 있을 뿐만 아니라 템플릿 내의 다른 요소도 참조할 수 있다.

3. 가상 파라미터

  • AWS는 모든 CloudFormation 템플릿에서 가상 파라미터를 제공한다.
  • 굳이 만들지 않아도 이미 존재하는 것들로 기본적으로 활성화 되어 있다.
  • 아래를 예시로 들어 AWS::AccountId에 Ref 함수를 사용하면 반환 값은 실제 계정 ID가 된다.


CloudFormation - Mappings

  • 매핑이라는 것은 CloudFormation 템플릿 내의 고정 변수를 말한다.
  • 서로 다른 환경을 구별하려는 경우에 이를 사용하면 편리하게 작업할 수 있다.
  • 모든 값은 템플릿 내에 하드 코딩되어 있으며 매핑 형식은 아래와 같다.
Mappings:
	Mapping01:
    	Key01:
        	Name: Value01
        Key02:
        	Name: Value02
        Key03:
        	Name: Value03

Mapping vs. Parameters

  • 매핑리전, 가용영역, AWS 계정이나 환경 등과 같은 변수에서 도출할 수 있는 모든 값을 미리 알고 있을 때 적합하다.
    • 이러한 변수들은 템플릿을 더 안전히 제어할 수 있다.
  • 파라미터는 사용자가 원하는 것과 런타임에 생각하는 것에 따라 실제로 달라지는 값이 있는 경우에 적합하다.
    • 사용자에게 최대 자유도를 부여하기 위함이다!

CloudFormation - Outputs

  • 출력 섹션은 선택 사항으로 선택적 출력 값을 선언하면 이 값들을 다른 스택으로 가져올 수 있다.
  • 예를 들어 내포낸 출력(VPC ID)이 있는 네트워크 스택을 연결할 수 있고, 다른 애플리케이션 스택에서 내보낸 출력 값을 참조할 수 있다.
    • 또한 콘솔이나 CLI를 사용하여 출력 값을 볼 수도 있다.

  • 이 방법은 스택 간 협업을 수행하는 최선의 방법이며 전문가들이 자신의 스택을 관리하고 협업할 수 있게 한다.
  • 다음은 출력 예시가 있다.
    • 하나의 템플릿의 일부로 SSH 보안 그룹을 생성하고 있으며, 다음 보안 그룹 에 대한 참조가 있는 출력을 생성한다.
    • Export에는 해당 출력을 내보내서 사용될 이름을 생성한다.
Outputs:
  StackSSHSecurityGroup:
    Description: The SSH Security Group for our Company
    Value: !Ref MyCompanyWideSSHSecurityGroup
    Export:
      Name: SSHSecurityGroup

CloudFormation - Conditions

  • CloudFormation 조건은 조건에 기반하는 출력이나 리소스의 생성을 통제하는데 사용된다.
  • 아래의 그림을 통해 설명을 진행하겠다.
    • 두 환경의 차이점은 이들 중 하나는 EBS 볼륨이 있고, 다른 하나는 없다는 것이다.
    • 원하는 대로 조건을 만들 수 있는데, 환경(개발이나 테스트)이나 리전, 파라미터 값을 기반으로 조건을 만든다.
  • 각 조건은 서로 참조할 수 있으며 파라미터 값이나 매핑도 참조할 수 있다.


CloudFormation - Intrinsic Functions

함수에는 Ref, Fn::GetAtt, Fn::FindInMap, Fn::ImportValue, Fn::Join,  Fn::ForEach 등의 함수가 있고
조건 함수로는 If, Not, Equals가 있으며
이 외에 Fn::Base64, Fn::Cidr, Fn::GetAZs, Fn::Select 등이 있다.

우리는 이 함수들 중 몇 가지를 알아볼 예정이다.
  1. Fn::Ref
    • 참조를 얻기 위해 활용된다.
      • 파라미터에 대한 참조일 수도 있고 리소스에 대한 참조일 수도 있다.
    • 약어는 항상 느낌표와 함께 !Ref와 같이 사용된다.
  2. Fn::GetAtt
    • 속성 값을 얻기 위한 함수
    • 속성을 가져오는 경우 Ref보다 더 많은 정보를 얻을 수 있다.
      • AZ, Id, PrivateDnsName, PublicDnsName 등등..
    • 만일 EC2 인스턴스의 AZ를 가져오고 싶다면 아래처럼 코드를 작성하면 된다.
      • Resources:
          EC2Instance:
            Type: AWS::EC2::Instance
            Properties:
              ImageId: ami-0742b4e673072066f
              InstanceType: t2.micro
              
        EBSVolume:
          Type: AWS::EC2::Volume
          Condition: CreateProdResources
          Properties:
            Size: 100
            AvailabilityZone: !GetAtt EC2Instance.AvailabilityZone
  3. Fn::FindInMap
    • 특정 맵의 특정 키에서 직접 값을 가져오는 함수이다.
    • !FindInMap [MapName, TopLevelKey, SecondLevelKey]의 형태
  4. Fn::ImportValue
    • 다른 스택에서 내보낸 값을 가져오는 데 사용되는 함수이다.
  5. Fn::Base64
    • 문자열을 Base64 형태로 변환한다.
    • !Base64 "ValueToEncode"

CloudFormation - Rollbacks

스택을 생성했지만 스택 생성이 실패하는 경우에는 두 가지 옵션이 있다.
1. 기본값 | 모든 것이 롤백되어 삭제, CloudFormation 생성 로그를 통해 실패 이유를 알 수 있다.
2. 옵션 | 리소스 중 하나에 문제가 있어 이를 유지하기 위해 롤백을 비활성화하여 스택 생성 중 발생한 문제를 해결함.

스택 업데이트에 문제가 있는 경우에 스택은 이전에 알려진 마지막 작업 상태로 자동 롤백되어 새로 생성된 모든 항목을 삭제한다.
- 로그를 보면 무슨 일이 일어났는지 알 수 있다.

롤백 실패의 경우 이는 스택 업데이트가 있음을 나타낸다.
롤백을 했지만 도중 오류가 발생하면 이것은 스택에 문제가 있음을 나타내는 것이다. 이 경우 리소스를 수동으로 수정해야 한다.
이 때, ContinueUpdateRollbackAPI를 실행하여 롤백을 다시 시도하도록 할 수 있다!!

CloudFormation - Service Role

  • CloudFormation은 사용자가 생성하는 CloudFormation 전용 IAM 역할을 사용할 수 있다!
    • 또한 사용자를 대신하여 CloudFormation이 스택 리소스를 실제로 생성, 업데이트, 삭제가 되게끔 한다.
  • 사용자에게 스택 리소스를 다룰 수 있는 기능을 부여하고 싶지만, 리소스로 직접 작업할 권한이 없는 경우 서비스 역할을 사용하면 된다.
  • 사용 사례로는 최소 권한 원칙을 달성하고 싶거나, 사용자에게 스택 리소스를 생성할 수 있는 모든 권한을 부여하지 않고 CloudFormation에서 서비스 역할을 호출할 수 있는 권한만 부여하고자 하는 경우이다.
  • 이 작업을 수행하려면 사용자는 반드시 iam:PassRole이라는 이름의 권한을 가져야만 한다.

CloudFormation이 IAM 리소스를 생성하거나 업데이트 하려면 반드시 Capability를 제공해야만 한다는 점을 유의!!


CloudFormation - DeletionPolicy

1. DeletionPolicy Delete

  • Deletion Policy
    • CloudFormation 템플릿이 삭제될 때나 리소스가 CloudFormation 템플릿으로부터 삭제될 때 발생하는 일을 제어하고자 사용되는 정책이다.
    • DeletionPolicy=Retain이라 정의할 수 있고 모든 리소스에 명시할 수 있다.(기본값은 DeletionPolicy=Delete이다.)
    • DeletionPolicy=Snapshot은 삭제되기 직전에 스냅샷을 만들며, EBS Volume, ElastiCache Cluster, RDS DBInstance, RDS DBCluster에만 적용된다.

2. DeletionPolicy Retain

  • 스택을 삭제해도 보안 그룹을 잃지 않는다!

3. DeletionPolicy Snapshot

  • 리소스가 삭제되기 전에 최종 스냅샷을 생성한다.
  • EBS Volume, ElastiCache Cluster, RDS DBInstance, RDS DBCluster, Redshift Cluster, Neptune DBCluster 등에 사용된다.


CloudFormation Stack Policies

  • CloudFormation 스택 업데이트가 있으면 어떤 작업이든 모든 리소스에서 허용된다.
  • 때에 따라 스택이나 스택의 일부를 업데이트로부터 보호하고 싶을 수 있는데 이때 스택 정책을 이용한다!

 

  • 스택 정책은 JSON문서이며, 스택 업데이트 중에 특정 리소스에 허용되는 업데이트 작업을 정의한다.
  • 스택 정책의 목표는 의도치 않은 업데이트로부터 리소스를 보호하는데에 있다.


CloudFormation - Custom Resources

  • 사용자 지정 리소스를 사용한다면 아직 CloudFormation에서 지원되지 않는 리소스를 정의하거나
  • 자체 온프레미스 리소스 또는 타사 리소스와 같이 CloudFormation 외부에 있을 수 있는 리소스에 대한 사용자 지정 프로비저닝 로직을 정의할 수 있다.

 

  • 사용자 지정 리소스를 정의하려면 템플릿에서 정의해야 하고 그 유형은 "Custom::MyCustomResourceTypeName"이다.
  • 가장 일반적인 람다 함수나 SNS 토픽이 이를 뒷받침한다.

사용자 지정 리소스를 정의하는 방법

서비스 토큰은 람다 ARN이나 SNS ARN이며, CloudFormation이 요청을 보내는 곳을 식별한다. 서비스 토큰은 같은 지역에 있어야 한다는 점을 기억하면 될 것 같다.

 

사용사례를 통해 이 원리를 잘 이해해 보자.

사용자 지정 리소스로 람다를 호출해 S3 버킷을 비우는 과정.

 

참고. StackSets와 종료 방지 정도는 알아두자.