在Cloudformation模板中组合Fn :: Split和Fn :: Select

时间:2018-10-28 17:12:39

标签: amazon-cloudformation

我正在尝试将Fn :: Select和Fn :: Split与Fn :: ImportValue函数组合在堆栈模板中,如下所示:

 Resources:
  ALBDashboard:
   Type: AWS::CloudWatch::Dashboard
   Properties:
    DashboardName: ALB-Dashboard
    DashboardBody: !Sub
    - |
        {
        "widgets": [
            {
                "type": "metric",
                "x": 0,
                "y": 21,
                "width": 9,
                "height": 3,
                "properties": {
                    "metrics": [
                        [ "AWS/ApplicationELB", "RequestCount", "TargetGroup", "targetgroup/GeneratorTG/ca775e3193d3b120", "LoadBalancer", "app/Dev-Invoicegen-ALB-Internet/8ac95b5b6900fa0c", "AvailabilityZone", "${AvailabilityZone1}", { "stat": "Sum" } ],
                        [ "...", "${AvailabilityZone2}", { "stat": "Sum" } ],
                        [ "...", "${AvailabilityZone3}", { "stat": "Sum" } ]
                    ],
                    "view": "singleValue",
                    "region": "${AWS::Region}",
                    "period": 300,
                    "title": "Request Count GeneratorTG 5 min - Sum"
                }
            },
  - TargetGroup:
       Fn::Select: [5, Fn::Split: [":", Fn::ImportValue: !Sub "${EnvironmentName}-WebTGARN" ]]

但继续出现以下错误:

Template format error: YAML not well-formed

但是根据此博客看来,这是正确的:

https://garbe.io/blog/2017/07/17/cloudformation-hacks/

另一方面,如果我尝试这样做,它将起作用:

  -  TargetGroup1:
        Fn::Select:
        - 5
        - Fn::Split:
          - ":"
          - Fn::ImportValue: !Sub "${EnvironmentName}-WebTGARN"

有人可以告诉我错误在哪里吗?

merci A

2 个答案:

答案 0 :(得分:0)

这对我有用。

from flask import has_request_context  # How to check if in a Flask session
from sqlalchemy import inspect
from sqlalchemy.orm import class_mapper
from sqlalchemy.orm.attributes import get_history
from sqlalchemy.event import listen

from YOUR_SESSION_MANAGER import get_user  # This would be something in Pyramid
from my_project import models  # Where your models are defined

def get_object_changes(obj):
    """ Given a model instance, returns dict of pending
    changes waiting for database flush/commit.

    e.g. {
        'some_field': {
            'before': *SOME-VALUE*,
            'after': *SOME-VALUE*
        },
        ...
    }
    """
    inspection = inspect(obj)
    changes = {}
    for attr in class_mapper(obj.__class__).column_attrs:
        if getattr(inspection.attrs, attr.key).history.has_changes():
            if get_history(obj, attr.key)[2]:
                before = get_history(obj, attr.key)[2].pop()
                after = getattr(obj, attr.key)
                if before != after:
                    if before or after:
                        changes[attr.key] = {'before': before, 'after': after}
    return changes

def my_model_change_listener(mapper, connection, target):
    changes = get_object_changes(target)
    changes.pop("modify_ts", None)  # remove fields you don't want to track

    user_id = None
    if has_request_context():
        # Call your function to get active user and extract id
        user_id = getattr(get_user(), 'id', None)

    if user_id is None:
        # What do you want to do if user can't be determined
        pass

    # You now have the model instance (target), the user_id who is logged in,
    # and a dictionary of changes.

    # Either do somthing "quick" with it here or call an async task (e.g.
    # Celery) to do something with the information that may take longer
    # than you want the request to take.

# Add the listener
listen(models.MyModel, 'after_update', my_model_change_listener)

在使用YAML CFN模板时,我倾向于使用!而不是Fn ::,而且运气更好。

答案 1 :(得分:0)

在yaml中使用长格式Cloudformation函数时,不能在同一行上使用嵌套函数。必须将它们放在新的一行。

我不确定确切的问题是什么,但是我认为这与yaml有点挑剔,因为冒号支持不带引号的术语,因为这是它找到字典键的方式。 Fn::Select:带有冒号,!Select没有。抛弃Cloudformation也不是Yaml,它变得更加模糊。您的工作示例不会在同一行上嵌套Fn::个项目,因此可以避免该问题。

如果您真的很想拥有“一个班轮”,则可以尝试将该行转换为json-yaml是json的超集,因此有效的json是有效的yaml。我没有尝试过,但是我认为这可以避免出现“嵌套Fn:: in yaml”问题。