Amazon Web Services 한국 블로그

AWS CloudFormation을 위한 퍼블릭 레지스트리 소개

AWS CloudFormation AWS Cloud Development Kit(CDK)는 AWS 리소스(예: 컴퓨팅 인프라, 모니터링 도구, 데이터베이스 등)의 확장 가능하고 일관된 프로비저닝을 제공합니다. AWS Partner Network(APN) 멤버, 서드 파티 공급업체 및 오픈 소스 기술에서 리소스를 프로비저닝할 때 클라우드 인프라 정의를 위해 CloudFormation 템플릿을 사용하고 있거나CDK를 채택했는지 여부와 상관없이 동일한 일관성과 확장성을 활용할 수 있기를 원하는 고객들이 많다고 들었습니다.

AWS, APN 파트너, 서드 파티 및 개발자 커뮤니티에서 게시한 검색 가능한 확장 컬렉션(리소스 유형 또는 모듈)을 제공하는CloudFormation에 대한 새로운 퍼블릭 레지스트리를 발표하게 되어 기쁩니다. 이 레지스트리를 사용하면 AWS 제공 리소스를 사용하는 것과 동일한 방식으로CloudFormation 템플릿 및CDK 애플리케이션에서 이러한 확장을 쉽게 검색하고 프로비저닝할 수 있습니다. 확장을 사용하면 더 이상 서드 파티 공급업체의 리소스 유형에 대한 사용자 지정 프로비저닝 로직을 만들고 유지 관리할 필요가 없습니다. 또한 단일 코드형 인프라 도구인 CloudFormation을 사용하여 AWS 및 서드 파티 리소스를 프로비저닝하고 관리할 수 있으므로 인프라 프로비저닝 프로세스를 더욱 간소화할 수 있습니다(CDKCloudFormation을 사용함).

런칭 파트너
수십 여 APN 파트너와 함께 레지스트리를 출시하게 되어 기쁩니다. 현재 사용할 수 있는 35개 이상의 확장 프로그램이 제공됩니다. AWS Quick Start와 함께 이번 출시를 위해 협력한 APN 파트너의 블로그 게시물 및 공지 사항은 아래에서 확인할 수 있습니다(일부는 향후 며칠 내에 추가될 예정).

레지스트리 및 리소스 유형
2019년, CloudFormation은 프라이빗 레지스트리에 대한 지원을 시작했습니다. 이를 통해 AWS 및 서드 파티 공급업체의 공급자를 비롯한 리소스 공급자(Lambda 함수)를 계정에 등록하고 사용할 수 있었습니다. 공급자를 등록한 후 CloudFormation 템플릿의 공급자에서 사용자 지정 프로비저닝 로직으로 구성된 리소스 유형을 사용할 수 있습니다. 리소스 유형은 공급자가 Amazon Simple Storage Service(Amazon S3) 버킷에 업로드했으며, 관련 S3 URL을 참조하여 유형을 사용했습니다. 퍼블릭 레지스트리는 리소스 유형 및 모듈의 소싱에 일관성을 제공하므로 Amazon Simple Storage Service(Amazon S3) 버킷 모음을 더 이상 사용할 필요가 없습니다.

퍼블릭 레지스트리의 서드 파티 리소스 유형도 드리프트 감지와 통합됩니다. 서드 파티 리소스 유형에서 리소스를 생성한 후 CloudFormationAWS 리소스와 마찬가지로 구성 드리프트라고 하는 템플릿 구성에서 리소스에 대한 변경 사항을 감지합니다. 또한AWS Config를 사용하여 레지스트리에서 소비되는 서드 파티 리소스에 대한 규정 준수를 관리할 수 있습니다. 리소스 유형을 기록하도록 AWS Config를 구성하고CloudFormation을 사용하여 생성, 업데이트 및 삭제하면 리소스 유형이 자동으로 구성 항목으로 추적됩니다. 사용하는 리소스 유형이 서드 파티 또는 AWS 리소스인지 여부에 관계없이 구성 모범 사례 확인을 위한 AWS Config 규칙을 작성할 수 있을 뿐만 아니라 리소스 유형에 대한 구성 기록을 볼 수 있습니다.

퍼블릭 레지스트리는 또한 유형 구성을 지원하므로 계정 및 리전별로 API 키와 OAuth 토큰을 사용하여 서드 파티 리소스 유형을 구성할 수 있습니다. 설정이 완료되면 구성이 안전하게 저장되고 업데이트될 수 있습니다. 또한 서드 파티 리소스 유형을 구성하는 중앙 집중식 방법을 제공합니다.

퍼블릭 레지스트리에 확장 게시
확장 게시자는 AWS Marketplace 판매자 또는 GitHub 또는 BitBucket 사용자로서 검증되어야 하며, 확장 프로그램은 모범 사례에 따라 검증됩니다. 확장 프로그램(리소스 유형 또는 모듈)을 레지스트리에 게시하려면 먼저 언급된 계정 유형 중 하나를 사용하여 AWS 리전에 등록해야 합니다.

등록한 후에는 다음 확장 프로그램을 동일한 리전의 프라이빗 레지스트리에 게시합니다. 그런 다음 확장 프로그램이 게시 요구 사항을 충족하는지 테스트해야 합니다. 리소스 유형 확장의 경우 해당 유형에 대해 정의된 모든 계약 테스트를 통과해야 함을 의미합니다. 모듈에는 다양한 요구 사항이 적용되며 설명서에서 자세한 내용을 확인할 수 있습니다. 테스트가 완료되면 해당 리전의 퍼블릭 레지스트리에 확장 프로그램을 게시할 수 있습니다. 확장 게시에 대한 자세한 내용은 사용 설명서를 참조하세요.

퍼블릭 레지스트리에서 확장 프로그램 사용
AWS Quick Starts가 제공하는 Kubernetes와 관련된 몇 가지 확장 프로그램을 사용해 클러스터에 대한 구성을 변경하기로 결정했습니다. 개인적으로, 저는 Kubernetes와 그 API에 대해 많은 경험을 가지고 있지 않기 때문에 확장 프로그램을 통해 상당한 시간과 노력을 절약할 수 있는 방법을 살펴볼 수 있는 좋은 기회였습니다. 이 게시물을 작성하는 과정에서 Kubernetes API(염두에 두고 있던 변화를 달성하는 일반적인 방법)를 사용하기 위해서는 많은 경험이 있는 사람들도 노력이 필요하다는 것을 알게 되었습니다.

이 예에서는 Kubernetes 클러스터가 필요했기 때문에 이 자습서를 따라 Amazon Elastic Kubernetes Service (EKS)에서 관리형 노드(Linux 노드 유형)를 사용하여 하나를 설정했습니다. 내 클러스터를 준비한 상태에서 두 가지 구성을 변경하고 싶습니다.

먼저 클러스터에 새 네임스페이스를 추가하고 싶습니다. 네임스페이스는 네임스페이스가 제공하는 격리 덕분에 충돌 없이 동일한 클러스터의 다른 네임스페이스에 동일한 리소스 집합을 배포할 수 있는 파티셔닝 구조입니다. 둘째, Kubernetes의 패키지 관리자인 Helm을 설정하여 사용하고 싶습니다. Helm을 사용하여 클러스터 지표를 수집하기 위해 Prometheus 헬름-차트 리포지토리에서 kube-state-metrics 패키지를 설치하겠습니다. 이전에는 CloudFormation을 사용해 클러스터와 컴퓨팅 리소스를 프로비저닝하여 이러한 두 가지 구성 작업을 수행할 수 있었지만 API 또는 다양한 맞춤형 도구 체인으로 전환해야 했습니다. 레지스트리와 이러한 두 확장 프로그램을 사용하면 이제 CloudFormation을 사용하여 모든 작업을 수행 할 수 있습니다(물론 앞서 언급했듯이 CDK와 함께 확장 프로그램을 사용할 수도 있습니다 나중에 보여 드릴 것임).

확장 프로그램을 사용하기 전에 내 계정에서 활성화해야 합니다. 단일 계정에 대해서는 콘솔을 사용하여 활성화하는 것이 쉽지만, 얼마 후AWS Organizations를 사용하고 전체 조직에서 다양한 서드 파티 확장 프로그램을 활성화하거나 특정 조직 단위(OU)에 대해 활성화하려는 경우 CloudFormation에서 서비스 관리형 StackSets를 사용하여 활성화할 수 있습니다. 서비스 관리형 StackSet에 제출된 템플릿에서 리소스 유형 AWS::CloudFormation::TypeActivation을 사용하여, 활성화할 서드 파티 확장 프로그램을 식별하는 Amazon 리소스 이름(ARN)을 전달하여 전체 조직 또는 특정 OU를 대상으로 지정할 수 있습니다. CDK를 사용하면 (AWS Organizations 사용 여부에 관계없이) 몇 줄의 코드만으로 매우 쉽게 확장 프로그램을 활성화할 수 있기 때문에 앞서 언급한 TypeActivation 리소스 유형을 역시 이용합니다.

확장 프로그램을 활성화하려면 CloudFormation 콘솔로 이동하여 탐색 모음에서 퍼블릭 확장을 클릭합니다. 이렇게 하면 Registry:Public 확장 프로그램 홈 페이지로 이동되며, 여기에서 서드 파티 리소스 유형 확장 프로그램 보기로 전환합니다.

레지스트리에서 서드 파티 유형 보기

내가 원하는 확장은 AWSQS::Kubernetes::ResourceAWSQS::Kubernetes::Helm입니다. 리소스 확장은 구성 변경 사항을 설명하는 매니페스트를 클러스터에 적용하는 데 사용됩니다. 여기서는 매니페스트가 네임스페이스를 생성하도록 요청합니다. AWSQS::Kubernetes::Resource 확장의 이름을 클릭하면 확장의 스키마, 구성 세부 정보 및 버전을 볼 수 있는 페이지로 이동합니다.

리소스 확장 프로그램의 세부 정보 보기

사용 중인 확장 프로그램을 비활성화하거나 게시자가 확장 프로그램을 철회하면 어떻게 됩니까? 스택이 의존하는 확장을 비활성화하면 해당 확장에서 만든 리소스는 영향을 받지 않지만 읽기, 업데이트, 삭제 및 목록과 같은 추가 스택 작업을 수행할 수 없습니다(확장이 다시 활성화될 때까지 실패함). 게시자는 레지스트리에서 확장 프로그램을 철회하도록 요청해야 합니다(‘삭제’ API는 없음). 요청이 승인된 경우에도 철회 전에 확장 프로그램을 활성화한 고객은 계정에서 확장 프로그램의 스냅샷을 효과적으로 사용하여 생성/읽기/업데이트/삭제/목록 작업을 수행할 수 있습니다.

활성화를 클릭하면 확장 프로그램 내부 코드를 실행할 때CloudFormation이 수임할 실행 역할의 ARN을 지정해야 하는 페이지로 이동됩니다. 이 사용자 가이드 주제에 따라 역할을 만들지만 기본 신뢰 관계는 참조를 위해 아래에 나와 있습니다.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "resources.cloudformation.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

또한 사용 중인 리소스 유형에 대한 권한을 내 실행 역할에 추가합니다. 내가 선택한 유형에 필요한 권한에 대한 자세한 내용은 GitHub, HelmKubernetes에서 찾을 수 있습니다(GitHub 예제는 신뢰 관계를 포함한다는 점에 유의).

확장 프로그램을 활성화할 때, 기본 이름(내 템플릿 또는 CDK 애플리케이션에서 해당 유형의 이름)을 사용하도록 선택하거나 새 이름을 입력할 수 있습니다. 선택한 이름은 내 계정 내에서 고유해야 하므로, 기본 이름으로 확장 버전을 활성화한 후 다른 버전을 활성화하려면 이름을 변경해야 합니다. 세부 정보를 입력하고 내 버전 관리 전략을 선택한 후(확장 프로그램은 시맨틱 버전 관리를 사용하므로, 사소한 버전 변경에 대해 자동 업데이트를 수락하거나 특정 버전으로 ‘잠그도록’ 선택할 수 있음) 확장 활성화를 클릭하면 프로세스가 완료됩니다.

레지스트리에서 확장 활성화

이로써 첫 번째 확장에 대한 프로세스가 완료되고, AWSQS::Kubernetes::Helm 확장에 대해 동일한 단계를 따릅니다. 활성화된 확장으로 이동하면 활성화된 모든 확장 프로그램의 목록을 볼 수 있습니다.

활성화된 확장 프로그램 목록 보기

업데이트할 권한 세트가 하나 더 있습니다. 리소스 유형은 나를 대신하여 Kubernetes API를 호출하므로 방금 사용한 실행 역할을 참조하도록 내 클러스터의 aws-auth ConfigMap을 업데이트해야 합니다. 그렇지 않으면 사용 중인 리소스 유형을 통한 호출이 실패합니다. 이를 위해 명령 프롬프트에서 kubectl edit cm aws-auth -n kube-system 명령을 실행합니다. 텍스트 편집기가 열리면 ConfigMap을 아래에 표시된 내 CFNRegistryExtensionExecRole을 참조하는 새 그룹으로 업데이트합니다(예시문의 계정 ID와 역할 이름을 본인의 계정 ID와 역할 이름으로 변경).

apiVersion: v1
data:
  mapRoles: |
    - groups:
      - system:bootstrappers
      - system:nodes
      rolearn: arn:aws:iam::111122223333:role/myAmazonEKSNodeRole
      username: system:node:{{EC2PrivateDNSName}}
    - groups:
      - system:masters
      rolearn: arn:aws:iam::111122223333:role/CfnRegistryExtensionExecRole
      username: cfnresourcetypes
kind: ConfigMap
metadata:
  creationTimestamp: "2021-06-04T20:44:24Z"
  name: aws-auth
  namespace: kube-system
  resourceVersion: "6355"
  selfLink: /api/v1/namespaces/kube-system/configmaps/aws-auth
  uid: dc91bfa8-1663-45d0-8954-1e841913b324

이제 확장을 사용하여 새 네임스페이스, Helm 및 kube-state-metrics 패키지로 내 클러스터를 구성할 준비가 되었습니다. 스택 생성 시 지정하려는 요소에 대한 파라미터(업데이트할 클러스터 이름 및 네임스페이스 이름)를 추가하여, 확장을 사용하는 CloudFormation 템플릿을 생성합니다. KubeStateMetrics 리소스의 속성은 Helm에서 설치할 패키지를 참조합니다.

AWSTemplateFormatVersion: "2010-09-09"
Parameters:
  ClusterName:
    Type: String
  Namespace:
    Type: String
Resources:
  KubeStateMetrics:
    Type: AWSQS::Kubernetes::Helm
    Properties:
      ClusterID: !Ref ClusterName
      Name: kube-state-metrics
      Namespace: !GetAtt KubeNamespace.Name
      Repository: https://prometheus-community.github.io/helm-charts
      Chart: prometheus-community/kube-state-metrics
  KubeNamespace:
    Type: AWSQS::Kubernetes::Resource
    Properties:
      ClusterName: !Ref ClusterName
      Namespace: default
      Manifest: !Sub |
        apiVersion: v1
        kind: Namespace
        metadata:
          name: ${Namespace}
          labels:
            name: ${Namespace}

CloudFormation 콘솔의 스택 페이지에서 스택 생성을 클릭하고 내 템플릿을 업로드한 다음 선언된 내 파라미터의 이름과 값을 내 스택에 지정합니다.

활성화된 내 확장 프로그램을 사용하여 스택 시작

다른 설정을 기본값으로 두고 다음을 클릭하여 나머지 마법사를 진행하고 스택 생성을 클릭하여 프로세스를 완료합니다.

스택 생성이 완료되면 kubectl 명령줄 도구를 사용하여 변경 사항을 확인합니다. 먼저 kubectl get namespaces 명령을 사용하여 새로운 네임스페이스인 newsblog-sample-namespace가 존재하는지 확인합니다. 그런 다음 kubectl get all --namespace newsblog-sample-namespace 명령을 실행하여 kube-state-metrics 패키지가 설치되어 있는지 확인합니다.

변경 사항이 적용된 확장 프로그램 확인

확장 프로그램은 AWS Cloud Development Kit에도 사용할 수 있습니다. 새 레지스트리를 사용하는 이 예시를 마무리하기 위해 TypeScript의CDK 애플리케이션 스니펫의 예제를 아래에 포함했으며 이 예제는 앞에서 소개한 YAML 템플릿과 동일한 확장을 사용하여 동일한 효과를 얻습니다(CDK에서 지원하는 언어(C#, Java 또는 Python)를 사용하여 작성 가능).

import {Stack, Construct, CfnResource} from '@aws-cdk/core';
export class UnoStack extends Stack {
  constructor(scope: Construct, id: string) {
    super(scope, id, props);
    const clusterName = 'newsblog-cluster';
    const namespace = 'newsblog-sample-namespace';

    const kubeNamespace = new CfnResource(this, 'KubeNamespace', {
      type: 'AWSQS::Kubernetes::Resource',
      properties: {
        ClusterName: clusterName,
        namespace: default
        Manifest: this.toJsonString({
          apiVersion: 'v1',
          kind: 'Namespace',
          metadata: {
            name: namespace,
            labels: {
              name: namespace,
            }
          },
        }),
      },
    });
    
    new CfnResource(this, 'KubeStateMetrics', {
      type: 'AWSQS::Kubernetes::Helm',
      properties: {
        ClusterID: clusterName,
        Name: 'kube-state-metrics',
        Namespace: kubeNamespace.getAtt('Name').toString(),
        Repository: 'https://prometheus-community.github.io/helm-charts',
        Chart: 'prometheus-community/kube-state-metrics',
      },
    });
  }
};

이 게시물의 앞부분에서 언급했듯이 Kubernetes API와 Kubernetes에 대한 전반적인 경험은 많지 않습니다. 그러나 퍼블릭 레지스트리의 리소스 유형을 CloudFormation과 함께 사용함으로써 API 또는 맞춤형 도구 체인에 의존하지 않고도 친숙한 환경을 사용하여 내 클러스터를 쉽게 구성할 수 있었습니다.

CloudFormation 퍼블릭 레지스트리 시작하기
퍼블릭 레지스트리의 요금은 기존 레지스트리 및 프라이빗 리소스 유형과 동일합니다. 고유 AWS 리소스 유형 사용에 대해서는 추가 요금이 부과되지 않습니다. 서드 파티 리소스 유형의 경우 매월 실행하는 처리기 작업(추가, 삭제, 목록 등)의 수에 따라 요금이 부과됩니다. 자세한 내용은 AWS CloudFormation 요금 페이지를 참조하세요. 새로운 퍼블릭 레지스트리는 미국 동부(버지니아 북부, 오하이오), 미국 서부(오레곤, 캘리포니아 북부), 캐나다(중부), 유럽(아일랜드, 프랑크푸르트, 런던, 스톡홀름, 파리, 밀라노), 아시아 태평양(홍콩, 뭄바이, 오사카, 싱가포르, 시드니, 서울, 도쿄), 남아메리카(상파울루), 중동(바레인) 및 아프리카(케이프타운) AWS 리전에서 사용할 수 있습니다.

AWS CloudFormation 사용 설명서확장 프로그램 개발을 위한 사용 설명서에서 자세한 내용을 참조하여 확장 프로그램 게시 또는 사용을 시작하세요.

— Steve