我有两个Cloudformation模板
环境
)创建弹性beanstek环境和相关侦听器规则来切流量到该环境的程序我面临的问题是环境
模板创建了一个AWS::ElasticBeanstalk::Environment
,随后创建了一个新的CFN堆栈,其中包含ASG和目标组(或弹性豆茎所熟知的进程)等内容。这些资源不是用于创建环境的 AWS 拥有的 CFN 模板的输出。
设置时
- Namespace: aws:elasticbeanstalk:environment
OptionName: LoadBalancerIsShared
Value: true
在我的elastic beanstalk环境的optionsettings中,没有创建负载平衡器,这很好。然后,我尝试将一个侦听器规则附加到我的负载平衡器侦听器上。
ListenerRule:
Type: AWS::ElasticLoadBalancingV2::ListenerRule
Properties:
Priority: 1
ListenerArn:
Fn::ImportValue: !Sub '${NetworkStackName}-HTTPS-Listener'
Actions:
- Type: forward
TargetGroupArn: WHAT_GOES_HERE
Conditions:
- Field: host-header
HostHeaderConfig:
Values:
- mywebsite.com
DependsOn:
- Environment
这里的问题是,据我所知,我没有访问由elastic beanstalk环境资源创建的目标组的ARN的权限。如果我创建一个目标组,那么它不会链接到elastic beanstalk,也不会出现任何实例。
我找到了这个页面,上面写着
Elastic Beanstalk 为您的环境创建的资源具有名称。可以使用这些名称通过函数获取有关资源的信息,或修改资源的属性以自定义其行为。
但是因为它们在不同的堆栈中(我事先不知道其中的名称),而不是模板的输出,我不知道如何掌握它们。
--
编辑:
Marcin在他们的回答中向我指出了自定义资源的方向。我已经稍微扩展了它并使其正常工作。实现在几个方面略有不同
describeenvironment_resources
返回资源列表,但似乎不是所有资源。在我的实现中,我获取了自动缩放组,并使用Physical Resource ID使用Cloudformation API查找堆栈中它所属的其他资源const AWS = require('aws-sdk');
const cfnResponse = require('cfn-response');
const eb = new AWS.ElasticBeanstalk();
const cfn = new AWS.CloudFormation();
exports.handler = (event, context) => {
if (event['RequestType'] !== 'Create') {
console.log(event[RequestType], 'is not Create');
return cfnResponse.send(event, context, cfnResponse.SUCCESS, {
Message: `${event['RequestType']} completed.`,
});
}
eb.describeEnvironmentResources(
{ EnvironmentName: event['ResourceProperties']['EBEnvName'] },
function (err, { EnvironmentResources }) {
if (err) {
console.log('Exception', e);
return cfnResponse.send(event, context, cfnResponse.FAILED, {});
}
const PhysicalResourceId = EnvironmentResources['AutoScalingGroups'].find(
(group) => group.Name
)['Name'];
const { StackResources } = cfn.describeStackResources(
{ PhysicalResourceId },
function (err, { StackResources }) {
if (err) {
console.log('Exception', e);
return cfnResponse.send(event, context, cfnResponse.FAILED, {});
}
const TargetGroup = StackResources.find(
(resource) =>
resource.LogicalResourceId === 'AWSEBV2LoadBalancerTargetGroup'
);
cfnResponse.send(event, context, cfnResponse.SUCCESS, {
TargetGroupArn: TargetGroup.PhysicalResourceId,
});
}
);
}
);
};
云形成模板
LambdaBasicExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: sts:AssumeRole
Path: /
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AWSCloudFormationReadOnlyAccess
- arn:aws:iam::aws:policy/AWSElasticBeanstalkReadOnly
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
GetEBLBTargetGroupLambda:
Type: AWS::Lambda::Function
Properties:
Handler: index.handler
Description: 'Get ARN of EB Load balancer'
Timeout: 30
Role: !GetAtt 'LambdaBasicExecutionRole.Arn'
Runtime: nodejs12.x
Code:
ZipFile: |
... code ...
ListenerRule:
Type: AWS::ElasticLoadBalancingV2::ListenerRule
Properties:
Priority: 1
ListenerArn:
Fn::ImportValue: !Sub '${NetworkStackName}-HTTPS-Listener'
Actions:
- Type: forward
TargetGroupArn:
Fn::GetAtt: ['GetEBLBTargetGroupResource', 'TargetGroupArn']
Conditions:
- Field: host-header
HostHeaderConfig:
Values:
- mydomain.com
我在做这件事时学到的东西,希望能帮助其他人
据我所知,我无权访问由弹性 beanstalk 环境资源创建的目标组的 ARN
没错。克服这个问题的方法是通过自定义资源。事实上,我为我之前的一个答案开发了完全工作的、非常相似的资源,因此您可以查看它并采用您的模板。该资源返回EB负载均衡器的ARN,但您可以修改它以获取EB目标组的ARN。