Если дистрибутив выбран, найдите на карте облачную информацию - PullRequest
1 голос
/ 10 октября 2019

Я пытаюсь создать скрипт CloudFormation, который позволяет пользователю выбирать дистрибутив Linux из трех вариантов (ubuntu, redhat, centos). На основе опции, которую выбирает пользователь, я хочу выбрать правильный AMI для региона, в котором создается стек CloudFormation, из существующего сопоставления. Наконец, я хочу использовать этот специфичный для региона AMI в качестве идентификатора изображения для экземпляра EC2.

У меня есть сопоставления для каждого распределения с AMI для сопоставленного региона.

Я хотел бы иметьвсе это автоматизировано, поэтому я могу использовать только один скрипт CloudFormation, а не один для каждой ОС.

У меня есть веб-приложение, которое в зависимости от предпочтений клиента будет работать в Ubuntu, CentOS или Red Hat. Я не хочу поддерживать три отдельных скрипта CloudFormation для каждого дистрибутива, особенно учитывая, что единственная реальная вещь, которая будет отличаться в каждом, - это ImageId для экземпляра EC2.

Я знаю, чтоВероятно, мне следовало бы воспользоваться условными функциями CloudFormation, но я пока не нашел способа сделать это.

Я не смог найти в Интернете ничего, что могло бы помочь. Это либо потому, что это действительно просто, никто ничего не опубликовал об этом, либо это невозможно, я чувствую, что это может быть последнее, но хотел бы увидеть некоторые другие взгляды.

Вот выдержка из того, что я естьВ настоящее время работает с.

Parameters:
  ApplicationServerLinuxDistribution:
    Type: "String"
    AllowedValues:
      - ubuntu
      - redhat
      - centos

Mappings:
# Ubuntu 18.04 AMIs
  AWSUbuntuAMIRegionMap:
    ap-northeast-1:
      HVM64: "ami-0cd744adeca97abb1"
    ap-northeast-2:
      HVM64: "ami-00379ec40a3e30f87"
# Red Hat 8 AMIs
  AWSRedHatAMIRegionMap:
    ap-northeast-1:
      HVM64: "ami-0c45b9b8b241f629f"
    ap-northeast-2:
      HVM64: "ami-090f71670acf741d8"
# CentOS 7 AMIs
  AWSCentOSAMIRegionMap:
    ap-northeast-1:
      HVM64: "ami-045f38c93733dd48d"
    ap-northeast-2:
      HVM64: "ami-06cf2a72dadf92410"

Resources:
   ApplicationServer:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: 

Итак, чтобы было ясно, что я хочу, если пользователь находится в eu-west-1 и выбирает Ubuntu, я хочу запросить мою карту Ubuntu Region / AMI для AMI eu-west-1,и используйте этот AMI для создания экземпляра EC2, и если пользователь выбирает Red Hat или CentOS, сделайте то же самое, но вместо этого для этих карт.

Ответы [ 2 ]

1 голос
/ 11 октября 2019

Вы почти у цели, но поскольку Fn :: FindInMap может возвращать только значение, соответствующее ключам в двухуровневой карте, я бы удалил свойство HVM64 из карты:

  AMIRegionMap:
    ap-northeast-1: 
      ubuntu: "ami-0cd744adeca97abb1"
      redhat: "ami-0c45b9b8b241f629f"
      centos: "ami-045f38c93733dd48d"
    ap-northeast-2: 
      ubuntu: "ami-00379ec40a3e30f87"
      redhat: "ami-090f71670acf741d8"
      centos: "ami-06cf2a72dadf92410"

Тогдав разделе Ресурсы вы можете использовать псевдопараметр AWS::Region вместе с параметром ApplicationServerLinuxDistribution для доступа к нужному вам AMI:

Resources:
   ApplicationServer:
    Type: "AWS::EC2::Instance"
    Properties:
      ImageId: !FindInMap [AMIRegionMap, !Ref "AWS::Region", !Ref ApplicationServerLinuxDistribution]

Регион должен использоваться как ключ первого уровня, если используется какключ второго уровня, с которым вы столкнетесь Mappings attribute name 'ap-northeast-1' must contain only alphanumeric characters. Документация гласит:

Имя может содержать только буквенно-цифровые символы (A-Za-z0-9).

Но не ясно, относится ли это только к клавишам второго уровня!

0 голосов
/ 12 октября 2019

Это было на самом деле намного проще, чем я думал, и может быть сделано вообще без использования условных выражений.

Решение

# Define the distribution's a user can choose from.
Parameters:
  LinuxDistributionSelection:
    Type: "String"
    AllowedValues:
      - ubuntu
      - centos
      - redhat

# Create a single map where each Region is a TopLevelKey, and each Parameter is a SecondLevelKey with the AMI as the key's value.
Mappings:
  AMIMapping:
    ap-east-1:
      ubuntu: "ami-59780228"
      centos: "null"
      redhat: "ami-7b374d0a"
    ap-northeast-1:
      ubuntu: "ami-04a1c725d8678428c"
      centos: "ami-045f38c93733dd48d"
      redhat: "ami-0c45b9b8b241f629f"
    ap-northeast-2:
      ubuntu: "ami-0df5bf8255e3a317f"
      centos: "ami-06cf2a72dadf92410"
      redhat: "ami-090f71670acf741d8"

# Query the map
Resources:
   ApplicationServer:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !FindInMap [AMIMapping, !Ref "AWS::Region", !Ref LinuxDistributionSelection ]

Почему это работает?

Это работает, потому что вы можете иметь несколько SecondLevelKey под TopLevelKey, поскольку документация Fn::FindInMap гласит: здесь . Таким образом, AMI для каждого распределения в каждом регионе могут быть просто парами ключ / значение под ключом региона. Пример ниже.

Fn::FindInMap: [ MapName, TopLevelKey=<region>, SecondLevelKey=<parameter-reference> ]

CloudFormation может затем логически обрабатывать вещи. Поэтому, когда вам нужно получить AMI для параметра ImageId экземпляра EC2 в зависимости от того, что выбрал пользователь, вы указываете CloudFormation запросить карту региона с помощью !FindInMap (сокращение Fn::FindInMap). Затем CloudFormation будет ссылаться на регион, в котором вы запускаете скрипт, используя !Ref "AWS::Region", и, наконец, CloudFormation может ссылаться на выбранный параметр с помощью !Ref LinuxDistributionSelection.

!FindInMap [AMIMapping, !Ref "AWS::Region", !Ref LinuxDistributionSelection ]

Я надеюсь, что мой ответ достаточен и объясняетэто достаточно хорошо для тех, кто борется с той же проблемой. Это мой первый ответ, поэтому, пожалуйста, будьте добры, и не стесняйтесь критиковать его, если он вводит в заблуждение или если я неправильно понял, что на самом деле происходит здесь.

...