Динамические ссылки для указания значений Secret Manager в облачной информации AWS - PullRequest
0 голосов
/ 03 декабря 2018

Можем ли мы в любом случае передать динамические ссылки в Secret Manager в пользовательские данные запуска конфигурации AWS?

Вот фрагмент кода, который я пробовал:

"SampleLaunchConfig": {
            "Type": "AWS::AutoScaling::LaunchConfiguration",
             "Properties": {
                "ImageId": {
                    "Fn::FindInMap": [
                        "AWSRegionArch2AMI",
                        {
                            "Ref": "AWS::Region"
                        },
                        "AMI"
                    ]
                },
                "UserData": {
                    "Fn::Base64": {
                        "Fn::Join": [
                            "",
                            [
                                "#!/bin/bash -xe\n",
                                "yum update -y\n",
                                "useradd -p <<pwd>>{{resolve:secretsmanager:Credentials:SecretString:userName}}\n",
                                "\n"
                            ]
                        ]
                    }
                }
        }
    }

Кажется, ошибка при получении useradd: неверное имя пользователя '{{resol: secretsmanager: Credentials: SecretString: userName}}'

Как передать секретное значение Secret Manager в пользовательские данные облачной информации?

Ответы [ 4 ]

0 голосов
/ 23 августа 2019

Вариант ответа @ JoeB:

Resources:
  SampleLaunchConfig:
    Type: AWS::AutoScaling::LaunchConfiguration
    Properties:
      ImageId: !FindInMap [ AWSRegionArch2AMI, !Ref: 'AWS::Region', AMI ]
      UserData:
        Fn::Base64: !Sub |
          #!/bin/bash -xe
          exec > >(tee /var/log/user-data.log | logger -t user-data) 2>&1

          yum update -y
          yum install -y jq

          username=$(aws secretsmanager get-secret-value --secret-id Credentials \
                                                         --query SecretString \
                                                         --region ${AWS::Region} --output text | jq -r .userName)
          password=$(aws secretsmanager get-secret-value --secret-id Credentials \
                                                         --query SecretString \
                                                         --region ${AWS::Region} --output text | jq -r .passwordKey)
          useradd -p "$password" $username

UserData в JSON больно смотреть в эти дни.

Я также добавил технику для разделения логики UserData на свою собственную.файл журнала, в противном случае он помещается в cloud-init.log, который также является болезненным для чтения.

0 голосов
/ 13 февраля 2019

Кажется, что {{resolve:...}} динамические ссылки раскрываются только в определенных контекстах внутри шаблона.

В документах AWS нет точной информации о том, где именно в шаблоне вы можете использовать эти ссылки.Нынешняя формулировка в отношении {{resolve:secretsmanager:...}} гласит:

«Динамическую ссылку на секретный менеджер можно использовать во всех свойствах ресурса»

Однако это противоречит вашему примеру,и я также наблюдал, что динамические ссылки не могут быть разрешены внутри данных CloudFormation :: Init.

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

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/dynamic-references.html#dynamic-references-secretsmanager

0 голосов
/ 10 апреля 2019

Я могу подтвердить, что ответ @ JoeB «предупреждение не проверено» работает с оговоркой, что рассматриваемая машина должна иметь разрешение на чтение секрета.Вам понадобится что-то вроде

  MyInstancePolicy:
    Type: AWS::IAM::Policy
    Properties:
      PolicyName: MyPolicy
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          -
            Effect: Allow
            Action:
              - secretsmanager:GetSecretValue
            Resource: !Join
              - ''
              - - !Sub "arn:aws:secretsmanager:${AWS::Region}:"
                - !Sub "${AWS::AccountId}:secret:Credentials-??????"

Обратите внимание на пару вещей:

В отличие от контейнеров S3, вы не можете сделать arn:aws:secretsmanager:::secret....Если вы не хотите явно указывать регион и учетную запись, вам нужно использовать подстановочный знак.Похоронен в нижней части Использование политик на основе идентификаторов (IAM Policies) для Secrets Manager

Если вас не волнует регион или учетная запись, владеющая секретом, вы должныукажите подстановочный знак * (не пустое поле) для полей региона и номера идентификатора учетной записи ARN.

Возможно, менее важно и с меньшей вероятностью приведет к неожиданным сбоям, но все же стоит отметить:

Использование '??????'в качестве подстановочного знака, соответствующего 6 случайным символам, которые назначены Secrets Manager, позволяет избежать проблемы, которая возникает, если вместо этого использовать подстановочный знак '*'.Если вы используете синтаксис «another_secret_name- *», он сопоставляет не только предполагаемый секрет с 6 случайными символами, но также совпадает с «another_secret_name-a1b2c3».С использованием '??????'Синтаксис позволяет безопасно предоставлять разрешения для секрета, который еще не существует.

0 голосов
/ 05 декабря 2018

Я не уверен, почему это не правильно для вас.Однако вы, вероятно, не хотите, чтобы CFN раскрывал ваш секрет в пользовательских данных, потому что пароль был бы встроен в скрипт пользовательских данных в кодировке base64, который отображается в консоли EC2.

Вместо этого вы должны воспользоваться преимуществамифакт, что у вас есть скрипт, который выполняется на хосте и диспетчере секретов вызовов во время выполнения скрипта (предупреждение не проверено):

"SampleLaunchConfig": {
        "Type": "AWS::AutoScaling::LaunchConfiguration",
         "Properties": {
            "ImageId": {
                "Fn::FindInMap": [
                    "AWSRegionArch2AMI",
                    {
                        "Ref": "AWS::Region"
                    },
                    "AMI"
                ]
            },
            "UserData": {
                "Fn::Base64": {
                    "Fn::Join": [
                        "",
                        [
                            "#!/bin/bash -xe\n",
                            "yum update -y\n",
                            "yum install -y jq\n",
                            !Sub "useradd -p `aws --region ${AWS::Region} secretsmanager get-secret-value --secret-id Credentials --query SecretString --output text | jq -r .passwordKey` `aws --region ${AWS::Region} secretsmanager get-secret-value --secret-id Credentials --query SecretString --output text | jq -r .userName`\n",
                            "\n"
                        ]
                    ]
                }
            }
    }
}

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

...