我有一个组织帐户,下面有几个管理帐户。每个管理帐户中包含多个vpc。每个托管帐户中的一个VPC将有一个标签"servicename":"true";而该帐户中的其他帐户将具有"ServiceName"; "False"标签。
我正在尝试创建一个堆栈集,该堆栈专用于创建一个带有入口规则的安全组,我需要动态分配"vpcid";该安全组的属性为"vpcid"。ServiceName":"True">
显然,如果我没有在VpcId字段中指定VPC ID,它会创建安全组,但将其附加到该帐户的默认VPC上。我也不能手动指定VPC,因为它将在多个帐户中运行。留给我的唯一选择是通过运行某种函数来提取"vpcid"来搜索和分配vpc。
当我在指定VPC ID的测试环境中运行它时,堆栈本身工作良好。所以,这只是一个问题得到"VpcId"动态。
最后,我希望做一些类似于这样的事情:
{
"Parameters": {
"MyValidVPCID": {
"Description": "My Valid VPC ID where ServiceName tag equals true. Do some Lambda Kung Fu to get the VPC ID using something that would let me parse the equivalent of aws ec2 describe-vpcs command.",
"Type": "String"
}
},
"Resources": {
"SG": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "Security Group Desc.",
"Tags": [
{
"Key": "Key1",
"Value": "ABC"
},
{
"Key": "Key2",
"Value": "DEF"
}
],
"VpcId" : { "Ref" : "MyValidVPCID" }
}
},
"SGIngressRule01":
{
"Type": "AWS::EC2::SecurityGroupIngress",
"DependsOn": "SG",
"Properties": {
"GroupId" : { "Fn::GetAtt": [ "SG", "GroupId" ] },
"Description": "Rule 1 description",
"IpProtocol": "tcp",
"FromPort": 123,
"ToPort": 456,
"CidrIp": "0.0.0.0/0"
}
}
}
我真的不知道这是否是一个可行的方法,或者需要什么额外的步骤来恢复基于标签的VpcId。这就是为什么如果我能从曾经使用过CloudFormation的人那里得到一些建议,这会对我有很大帮助。
获得"VpcId"动态。
你必须使用自定义资源。您必须将其创建为lambda函数它将接受您想要的任何输入参数,并使用AWS SDK,将查询或修改堆栈中的VPC/安全组。
感谢Marcin为我指出了使用自定义资源的正确方向。对于那些想知道使其工作的基本代码是什么样子的人来说,它看起来像这样:
Resources:
FunctionNameLambdaFunctionRole:
Type: "AWS::IAM::Role"
Properties:
RoleName: FunctionNameLambdaFunctionRole
Path: "/"
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: sts:AssumeRole
FunctionNameLambdaFunctionRolePolicy:
Type: "AWS::IAM::Policy"
Properties:
PolicyName: admin3cx
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action: "*"
Resource: "*"
Roles:
- Ref: FunctionNameLambdaFunctionRole
FunctionNameLambdaFunctionCode:
Type: "AWS::Lambda::Function"
DeletionPolicy: Delete
DependsOn:
- FunctionNameLambdaFunctionRole
Properties:
FunctionName: FunctionNameLambdaFunctionCode
Role: !GetAtt FunctionNameLambdaFunctionRole.Arn
Runtime: python3.7
Handler: index.handler
MemorySize: 128
Timeout: 30
Code:
ZipFile: |
import boto3
import cfnresponse
ec2 = boto3.resource('ec2')
client = boto3.client('ec2')
def handler(event, context):
responseData = {}
filters =[{'Name':'tag:ServiceName', 'Values':['True']}]
vpcs = list(ec2.vpcs.filter(Filters=filters))
for vpc in vpcs:
responseVPC = vpc.id
responseData['ServiceName'] = responseVPC
cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, "CustomResourcePhysicalID")
FunctionNameLambdaFunctionInvocationCode:
Type: "Custom::FunctionNameLambdaFunctionInvocationCode"
Properties:
ServiceToken: !GetAtt FunctionNameLambdaFunctionCode.Arn
SGFunctionName:
Type: "AWS::EC2::SecurityGroup"
Properties:
GroupDescription: Description
VpcId: !GetAtt FunctionNameLambdaFunctionInvocationCode.ServiceName
...
一些东西已经编辑,我做了切换到YAML。代码将明显地改进。关键是要确保我能够根据CloudFormation堆栈内Lambda函数中的过滤器获得返回值。