CloudFormation에서 Fn::ForEach 반복 함수를 사용할 수 있게 되었습니다.
안녕하세요 클래스메소드 김재욱(Kim Jaewook) 입니다. 이번에는 CloudFormation에서 Fn::ForEach 반복 함수를 사용할 수 있게 업데이트 되었으므로 정리해 봤습니다.
업데이트 내용
2023년 7월 26일 CloudFormation에서 Fn::ForEach 반복 함수를 사용할 수 있게 업데이트 되었습니다.
AWS CloudFormation은 Fn::ForEach 내장 함수를 사용하는 반복 기능을 발표했습니다. Fn::ForEach를 통해 최소한의 코드 줄로 템플릿의 일부를 복제할 수 있습니다. Fn::ForEach를 사용하여 템플릿 레이아웃을 단순화하고 동료가 코드를 더 쉽고 빠르게 검토할 수 있도록 할 수 있습니다. Fn::ForEach는 잘못된 속성을 업데이트하거나 템플릿에서 여러 대상 속성 업데이트 누락 등의 인적 오류를 줄이는 데 도움이 됩니다.
업데이트 내용을 살펴보면, Fn::ForEach 함수를 통해서 최소한의 코드로 템플릿을 복제할 수 있으며, 업데이트 누락과 오류를 줄이는 데 도움이 된다고 안내하고 있습니다.
보다 상세한 업데이트 내용은 아래 공식 문서를 참고해 주세요.
Fn::ForEach 업데이트 이전에는?
이번 Fn::ForEach 함수가 업데이트되기 이전에는 반복 처리를 할 수 있는 기능이 없었기 때문에 동일한 리소스를 여러 개 생성하기 위해 기존의 내용을 그대로 붙여 넣는 수작업을 진행해야 했습니다.
이렇게 리소스가 동일한 리소스를 여러 개 생성하게 된다면, CloudFormation 코드도 길어지며, 관리하기도 껄끄러워진다는 단점이 있었습니다.
AWSTemplateFormatVersion: 2010-09-09 Description: Create SNS Topic Resources: Topic1: Type: "AWS::SNS::Topic" Properties: TopicName: test1 Topic2: Type: "AWS::SNS::Topic" Properties: TopicName: test2 Topic3: Type: "AWS::SNS::Topic" Properties: TopicName: test3 Topic4: Type: "AWS::SNS::Topic" Properties: TopicName: test4
실제로 같은 내용의 SNS Topic을 생성할 때, 상기 코드와 같이 동일한 코드를 4번 반복해야 합니다.
여기서 SNS Topic의 정책과 그 외 옵션까지 추가한다면 코드도 길어질 것이며, 불필요한 코드로 인해 코드 관리 또한 힘들어질 것입니다.
이번에는 SNS Topic이 아닌, EC2 인스턴스 3대를 생성한다면 어떻게 될까요?
AWSTemplateFormatVersion: 2010-09-09 Description: Create EC2 # ------------------------------------------------------------# # Input Parameters # ------------------------------------------------------------# Parameters: TestProdKeyPair: Description: EC2 Key Pair Type: "AWS::EC2::KeyPair::KeyName" TestProdAMI: Description: Test-prod EC2 AMI Type: String Default: ami-xxxxxx # ------------------------------------------------------------# # Create EC2 Instance Test1 # ------------------------------------------------------------# Resources: Test1ProdEC2: Type: AWS::EC2::Instance Properties: ImageId: !Ref TestProdAMI InstanceType: m5.xlarge KeyName: !Ref TestProdKeyPair DisableApiTermination: true BlockDeviceMappings: - DeviceName: /dev/sda1 Ebs: VolumeSize: 1024 VolumeType: gp3 SubnetId: subnet-xxxxxx SecurityGroupIds: - Fn::ImportValue: !Sub xxxx # ------------------------------------------------------------# # Create EC2 Instance Test2 # ------------------------------------------------------------# Test2ProdEC2: Type: AWS::EC2::Instance Properties: ImageId: !Ref TestProdAMI InstanceType: m5.4xlarge KeyName: !Ref TestProdKeyPair DisableApiTermination: true BlockDeviceMappings: - DeviceName: /dev/sda1 Ebs: VolumeSize: 1024 VolumeType: gp3 SubnetId: subnet-xxxxxx SecurityGroupIds: - Fn::ImportValue: !Sub xxxx # ------------------------------------------------------------# # Create EC2 Instance Test3 # ------------------------------------------------------------# Test2ProdEC3: Type: AWS::EC2::Instance Properties: ImageId: !Ref TestProdAMI InstanceType: c5.2xlarge KeyName: !Ref TestProdKeyPair DisableApiTermination: true BlockDeviceMappings: - DeviceName: /dev/sda1 Ebs: VolumeSize: 1024 VolumeType: gp3 SubnetId: subnet-xxxxxx SecurityGroupIds: - Fn::ImportValue: !Sub xxxx
상기 코드처럼 3대를 생성했음에도 코드가 확연히 길어지고 있음을 알 수 있습니다.
여기서 EC2 인스턴스가 3대가 아니라 5대 7대 등등 점점 더 늘어난다면, 그만큼 코드도 길어지고 관리하기 힘들어질 것입니다.
이런 문제점을 해결하기 위해서는 Fn::ForEach 함수를 사용해, 코드 낭비를 줄이며, 보다 편하게 리소스들을 관리할 수 있습니다.
Fn::ForEach 사용해 보기
먼저 Fn::ForEach를 사용하기 위해서는「AWS::LanguageExtensions」를 선언할 필요가 있습니다.
AWS::LanguageExtensions의 경우 CloudFormation에 기본적으로 포함되지 않은 내장 함수 및 기타 기능을 사용할 수 있도록 해주는 기능입니다.
AWS::LanguageExtensions에 대한 보다 상세한 내용은 아래 공식 문서를 참고해 주세요.
AWSTemplateFormatVersion: 2010-09-09 Transform: 'AWS::LanguageExtensions' Parameters: SNSName: Description: SNS Topic Name Type: CommaDelimitedList Resources: 'Fn::ForEach::Topics': - TopicName - !Ref SNSName - 'SnsTopic${TopicName}': Type: 'AWS::SNS::Topic' Properties: TopicName: !Ref TopicName
Fn::ForEach 함수를 이용해서 각기 다른 이름의 SNS 토픽을 생성합니다.
스택을 생성할 때, 각 SNS 토픽의 이름을 설정합니다.
SNS 콘솔 화면에서 확인해 보면 문제 없이 지정한 이름으로 SNS 토픽이 생성된 것을 확인할 수 있습니다.
AWSTemplateFormatVersion: 2010-09-09 Transform: 'AWS::LanguageExtensions' Mappings: Instances: InstanceType: B: m5.4xlarge C: c5.2xlarge ImageId: A: ami-xxxxxxxx Resources: 'Fn::ForEach::Instances': - Identifier - [A, B, C] - 'Instance${Identifier}': Type: 'AWS::EC2::Instance' Properties: InstanceType: !FindInMap [Instances, InstanceType, !Ref 'Identifier', {DefaultValue: m5.xlarge}] ImageId: !FindInMap [Instances, ImageId, !Ref 'Identifier', {DefaultValue: ami-xxxxxxxx}] SubnetId: subnet-xxxxxxxx Outputs: SecondInstanceId: Description: Instance Id for InstanceB Value: !Ref 'InstanceB' SecondPrivateIp: Description: Private IP for InstanceB Value: !GetAtt [InstanceB, PrivateIp]
다음은 Fn::ForEach 함수로 3개의 EC2 인스턴스를 만드는 코드입니다.
각각 다른 인스턴스 타입으로 EC2 인스턴스가 생성된 것을 확인할 수 있습니다.
OutPut도 문제 없이 출력됩니다.
그 외 예시 코드는 아래 AWS 공식 문서를 참고해 주세요.
본 블로그 게시글을 읽고 궁금한 사항이 있으신 분들은 jaewookkim533@yahoo.com로 보내주시면 감사하겠습니다.