다음 템플릿에서는 AWS Lambda(Lambda) 함수와 사용자 지정 리소스를 사용하여 기존 보안 그룹 목록에 새 보안 그룹을 추가합니다. 이 함수는 목록에 새 보안 그룹과 기존 보안 그룹이 모두 포함되도록 보안 그룹의 목록을 동적으로 빌드하려는 경우에 유용합니다. 예를 들어, 기존 보안 그룹의 목록을 파라미터 값으로 전달하고, 새 값을 목록에 추가한 다음 모든 값을 EC2 인스턴스에 연결할 수 있습니다. Lambda 함수 리소스 유형에 대한 자세한 내용은 AWS::Lambda::Function을 참조하세요.
이 예제에서 CloudFormation은 AllSecurityGroups
사용자 지정 리소스를 생성할 때 AppendItemToListFunction
Lambda 함수를 간접적으로 호출합니다. CloudFormation은 기존 보안 그룹 목록과 새 보안 그룹(NewSecurityGroup
)을 함수에 전달하고, 해당 함수는 새 보안 그룹을 목록에 추가한 다음 수정된 목록을 반환합니다. CloudFormation은 수정된 목록을 사용하여 모든 보안 그룹을 MyEC2Instance
리소스와 연결합니다.
JSON
{
"AWSTemplateFormatVersion": "2010-09-09",
"Parameters": {
"ExistingSecurityGroups": {
"Type": "List<AWS::EC2::SecurityGroup::Id>"
},
"ExistingVPC": {
"Type": "AWS::EC2::VPC::Id",
"Description": "The VPC ID that includes the security groups in the ExistingSecurityGroups parameter."
},
"InstanceType": {
"Type": "String",
"Default": "t2.micro",
"AllowedValues": [
"t2.micro",
"m1.small"
]
}
},
"Mappings": {
"AWSInstanceType2Arch": {
"t2.micro": {
"Arch": "HVM64"
},
"m1.small": {
"Arch": "HVM64"
}
},
"AWSRegionArch2AMI": {
"us-east-1": {
"HVM64": "ami-0ff8a91507f77f867",
"HVMG2": "ami-0a584ac55a7631c0c"
},
"us-west-2": {
"HVM64": "ami-a0cfeed8",
"HVMG2": "ami-0e09505bc235aa82d"
},
"us-west-1": {
"HVM64": "ami-0bdb828fd58c52235",
"HVMG2": "ami-066ee5fd4a9ef77f1"
},
"eu-west-1": {
"HVM64": "ami-047bb4163c506cd98",
"HVMG2": "ami-0a7c483d527806435"
},
"eu-central-1": {
"HVM64": "ami-0233214e13e500f77",
"HVMG2": "ami-06223d46a6d0661c7"
},
"ap-northeast-1": {
"HVM64": "ami-06cd52961ce9f0d85",
"HVMG2": "ami-053cdd503598e4a9d"
},
"ap-southeast-1": {
"HVM64": "ami-08569b978cc4dfa10",
"HVMG2": "ami-0be9df32ae9f92309"
},
"ap-southeast-2": {
"HVM64": "ami-09b42976632b27e9b",
"HVMG2": "ami-0a9ce9fecc3d1daf8"
},
"sa-east-1": {
"HVM64": "ami-07b14488da8ea02a0",
"HVMG2": "NOT_SUPPORTED"
},
"cn-north-1": {
"HVM64": "ami-0a4eaf6c4454eda75",
"HVMG2": "NOT_SUPPORTED"
}
}
},
"Resources": {
"SecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "Allow HTTP traffic to the host",
"VpcId": {
"Ref": "ExistingVPC"
},
"SecurityGroupIngress": [
{
"IpProtocol": "tcp",
"FromPort": 80,
"ToPort": 80,
"CidrIp": "0.0.0.0/0"
}
],
"SecurityGroupEgress": [
{
"IpProtocol": "tcp",
"FromPort": 80,
"ToPort": 80,
"CidrIp": "0.0.0.0/0"
}
]
}
},
"AllSecurityGroups": {
"Type": "Custom::Split",
"Properties": {
"ServiceToken": {
"Fn::GetAtt": [
"AppendItemToListFunction",
"Arn"
]
},
"List": {
"Ref": "ExistingSecurityGroups"
},
"AppendedItem": {
"Ref": "SecurityGroup"
}
}
},
"AppendItemToListFunction": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Handler": "index.handler",
"Role": {
"Fn::GetAtt": [
"LambdaExecutionRole",
"Arn"
]
},
"Code": {
"ZipFile": {
"Fn::Join": [
"",
[
"var response = require('cfn-response');",
"exports.handler = function(event, context) {",
" var responseData = {Value: event.ResourceProperties.List};",
" responseData.Value.push(event.ResourceProperties.AppendedItem);",
" response.send(event, context, response.SUCCESS, responseData);",
"};"
]
]
}
},
"Runtime": "nodejs20.x"
}
},
"MyEC2Instance": {
"Type": "AWS::EC2::Instance",
"Properties": {
"ImageId": {
"Fn::FindInMap": [
"AWSRegionArch2AMI",
{
"Ref": "AWS::Region"
},
{
"Fn::FindInMap": [
"AWSInstanceType2Arch",
{
"Ref": "InstanceType"
},
"Arch"
]
}
]
},
"SecurityGroupIds": {
"Fn::GetAtt": [
"AllSecurityGroups",
"Value"
]
},
"InstanceType": {
"Ref": "InstanceType"
}
}
},
"LambdaExecutionRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"lambda.amazonaws.com"
]
},
"Action": [
"sts:AssumeRole"
]
}
]
},
"Path": "/",
"Policies": [
{
"PolicyName": "root",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:*"
],
"Resource": "arn:aws:logs:*:*:*"
}
]
}
}
]
}
}
},
"Outputs": {
"AllSecurityGroups": {
"Description": "Security Groups that are associated with the EC2 instance",
"Value": {
"Fn::Join": [
", ",
{
"Fn::GetAtt": [
"AllSecurityGroups",
"Value"
]
}
]
}
}
}
}
YAML
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
ExistingSecurityGroups:
Type: List<AWS::EC2::SecurityGroup::Id>
ExistingVPC:
Type: AWS::EC2::VPC::Id
Description: The VPC ID that includes the security groups in the ExistingSecurityGroups parameter.
InstanceType:
Type: String
Default: t2.micro
AllowedValues:
- t2.micro
- m1.small
Mappings:
AWSInstanceType2Arch:
t2.micro:
Arch: HVM64
m1.small:
Arch: HVM64
AWSRegionArch2AMI:
us-east-1:
HVM64: ami-0ff8a91507f77f867
HVMG2: ami-0a584ac55a7631c0c
us-west-2:
HVM64: ami-a0cfeed8
HVMG2: ami-0e09505bc235aa82d
us-west-1:
HVM64: ami-0bdb828fd58c52235
HVMG2: ami-066ee5fd4a9ef77f1
eu-west-1:
HVM64: ami-047bb4163c506cd98
HVMG2: ami-0a7c483d527806435
eu-central-1:
HVM64: ami-0233214e13e500f77
HVMG2: ami-06223d46a6d0661c7
ap-northeast-1:
HVM64: ami-06cd52961ce9f0d85
HVMG2: ami-053cdd503598e4a9d
ap-southeast-1:
HVM64: ami-08569b978cc4dfa10
HVMG2: ami-0be9df32ae9f92309
ap-southeast-2:
HVM64: ami-09b42976632b27e9b
HVMG2: ami-0a9ce9fecc3d1daf8
sa-east-1:
HVM64: ami-07b14488da8ea02a0
HVMG2: NOT_SUPPORTED
cn-north-1:
HVM64: ami-0a4eaf6c4454eda75
HVMG2: NOT_SUPPORTED
Resources:
SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow HTTP traffic to the host
VpcId: !Ref ExistingVPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
SecurityGroupEgress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
AllSecurityGroups:
Type: Custom::Split
Properties:
ServiceToken: !GetAtt AppendItemToListFunction.Arn
List: !Ref ExistingSecurityGroups
AppendedItem: !Ref SecurityGroup
AppendItemToListFunction:
Type: AWS::Lambda::Function
Properties:
Handler: index.handler
Role: !GetAtt LambdaExecutionRole.Arn
Code:
ZipFile: !Join
- ''
- - var response = require('cfn-response');
- exports.handler = function(event, context) {
- ' var responseData = {Value: event.ResourceProperties.List};'
- ' responseData.Value.push(event.ResourceProperties.AppendedItem);'
- ' response.send(event, context, response.SUCCESS, responseData);'
- '};'
Runtime: nodejs20.x
MyEC2Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: !FindInMap
- AWSRegionArch2AMI
- !Ref AWS::Region
- !FindInMap
- AWSInstanceType2Arch
- !Ref InstanceType
- Arch
SecurityGroupIds: !GetAtt AllSecurityGroups.Value
InstanceType: !Ref InstanceType
LambdaExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- sts:AssumeRole
Path: /
Policies:
- PolicyName: root
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- logs:*
Resource: arn:aws:logs:*:*:*
Outputs:
AllSecurityGroups:
Description: Security Groups that are associated with the EC2 instance
Value: !Join
- ', '
- !GetAtt AllSecurityGroups.Value