如何从 CfnMapping.FindInMap("MappingName", Aws.REGION) 设置 Instance.MachineImage?

How to set Instance.MachineImage from CfnMapping.FindInMap("MappingName", Aws.REGION)?

我正在尝试使用最新的 .NET CDK 创建一个堆栈,其中根据部署堆栈的区域在部署时指定实例 AMI。对于常规的 CloudFormation,我可以使用 Mappings、AWS::Region 和 FindInMap 函数来做到这一点,但是对于 CDK、GenericLinuxImage 或 LookupMachineImage 似乎不接受 Aws.REGION 和 CfnMapping.FindInMap() 的输出 - 延迟值,和 AMI 及其区域必须在合成时知道,这不是我需要的。

使用 GenericLinuxImage 时出现“Unable to determine AMI from AMI map since stack is region-agnostic”错误。

是否可以使用 CfnMapping.FindInMap() 和 Aws.REGION 来指定实例自定义 AMI?

我要重现其行为的 CFN 片段:

Mappings:
  RegionMap:
    us-east-1: 
      AmiId: ami-XXXXXXXXXXX
...

Resources:
  ...
  InstanceMachine:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: t3a.large
      ImageId: !FindInMap
        - RegionMap
        - !Ref 'AWS::Region'
        - AmiId

谢谢, 弗拉德

2021/04/27更新

我已经从 aws cdk upstream 解决了这个问题。 cdk版本>=v1.89.0应该没问题。

修复如下:https://github.com/aws/aws-cdk/commit/fbe7e89ba764093ddec9caa7de3ca921f3dc68ac


旧回复

在我研究了 cdk 源代码之后。你可以这样写。 下面是打字稿的版本,你云写一个.Net版本。

import * as ec2 from '@aws-cdk/aws-ec2';
import { Construct, Stack, StackProps, CfnMapping, Aws } from '@aws-cdk/core';

export class MyStack extends Stack {
  constructor(scope: Construct, id: string, props: StackProps = {}) {
    super(scope, id, props);

    const regionMap = new CfnMapping(this, 'RegionMap', {
      mapping: {
        'cn-north-1': { ami: 'ami-cn-north-1' },
        'cn-northwest-1': { ami: 'ami-cn-northwest-1' },
      },
    });

    class MyImage implements ec2.IMachineImage {
      public getImage(_: Construct): ec2.MachineImageConfig {
        return {
          imageId: regionMap.findInMap(Aws.REGION, 'ami'),
          userData: ec2.UserData.forLinux(),
          osType: ec2.OperatingSystemType.LINUX,
        };
      }
    }

    const vpc= new ec2.Vpc(this, 'VPC');

    new ec2.Instance(this, 'Instance', {
      vpc,
      instanceType: new ec2.InstanceType('t2.micro'),
      machineImage: new MyImage(),
    });
  }
}