仅当存在 FindInMap 值时才创建角色? / 如果 Mapping 没有某些键的值怎么办?

Create role only if FindInMap value is present? / What to do if Mapping doesn't have values for some keys?

我有一个角色,只有在映射中有给定键的条目时我才想创建。当我没有为某些键/值输入值时,就会出现混乱(在这种情况下,某些区域没有“XClientPrincipals”的值,所以我得到一个错误。

示例: 地图:

  alpha: ...
  beta:
    Region1:
      YClientPrincipals:
        - 'arn:aws:iam::#########:root'
    Region3:
      XClientPrincipals:
        - 'arn:aws:iam::#########:root'
      YClientPrincipals:
        - 'arn:aws:iam::#########:root'
  prod:
    Region1:
      YClientPrincipals:
        - 'arn:aws:iam::#########:root'
    Region2:
      XClientPrincipals:
        - 'arn:aws:iam::#########:root'
        - 'arn:aws:iam::#########:root'
      YClientPrincipals:
        - 'arn:aws:iam::#########:root'
    Region3:
      XClientPrincipals:
        - 'arn:aws:iam::#########:root'
        - 'arn:aws:iam::#########:root'
      YClientPrincipals:
        - 'arn:aws:iam::#########:root'

角色:

  # Role definition for LMSortPlanningWorkflow - https://issues.amazon.com/LMCP-3533
  XClientRole:
    Type: AWS::IAM::Role
    Condition: IsBetaOrProd # Don't create external client roles in Alpha
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Action: 'sts:AssumeRole'
            Effect: Allow
            Principal:
              AWS:
                'Fn::FindInMap': [ { Ref: 'Domain' }, { Ref: 'Region' }, 'XClientPrincipals' ]
      RoleName: { 'Fn::Sub': 'XClientRole' }
      ManagedPolicyArns:
        - Ref: SomeApiCallPolicy

问题在于 XClientPrincipals 仅适用于某些区域,我们只需要在这些区域中创建角色(测试版和生产版的角色有所不同)。如果我没有在地图中为我们拥有的每个可能的域和区域组合提供某些内容,则在为该域 + 区域部署时会出错,因为它无法在地图中找到任何内容。但是,如果我为该域 + 区域指定一个空数组,那也是一个错误,因为委托人需要一个值。有没有办法创建一个条件,如果它可以首先在地图中找到值,则只创建角色?

我很确定我可以创建一个条件来只创建角色并拼出可接受的域和区域值(第一个和第二个键),这些值应该评估为真,但实际映射比这个,所以如果能够做这样的条件就太好了:

  RunLambdaInVPC:
    Fn::Not: [ {Ref: FindInMap .... }, null]

但我认为我还没有看到任何这样的例子,也没有想出一种方法来让这样的东西发挥作用。

是的,您可以根据某个映射的值有条件地创建资源。
这是一个示例,显示了如何在 Condition 中使用区域映射的值,然后可以使用该值来确定是否应创建资源:

AWSTemplateFormatVersion: "2010-09-09"
Mappings: 
  RegionMap: 
    us-east-1: 
      "HVM64": "ami-0ff8a91507f77f867"
    us-west-1: 
      "HVM64": "ami-0bdb828fd58c52235"
  IsProdMapping: 
    us-east-1: 
      "prod": "True"
    us-west-1: 
      "prod": "False"

Resources:
  EC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !FindInMap [RegionMap, !Ref "AWS::Region", HVM64]
      InstanceType: t3.nano
      SubnetId: !Ref Subnet
  RootRole:
    Type: 'AWS::IAM::Role'
    Condition: CreateIAMRole
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - ec2.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      Path: /
      Policies:
        - PolicyName: root
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action: '*'
                Resource: '*'
Conditions:
  CreateIAMRole: !Equals 
    - !FindInMap [IsProdMapping, !Ref "AWS::Region", "prod"]
    - "True"
Parameters:
  VPC:
    Type: AWS::EC2::VPC::Id
    Description: The VPC where you want to deploy
  Subnet:
    Type: AWS::EC2::Subnet::Id
    Description: The subnet where you want to deploy

如果我在 us-east-1 中部署此模板,则会创建 RootRole
如果我在 us-west-1 中部署此模板,RootRole 而不是 创建的。