Могу ли я заставить CloudFormation разрешать значения из Secrets Manager? - PullRequest
1 голос
/ 09 января 2020

Ниже (сокращенно шаблон CloudFormation) я пытаюсь настроить AWS лямбда-функцию для получения значения из AWS Secrets Manager, внедренного в его среду:

Resources:
  Function:
    Type: AWS::Serverless::Function
    Properties:
      Environment:
        Variables:
          SECRET_KEY: !Sub '{{resolve:secretsmanager:${Secret}:SecretString:KEY}}'

  Secret:
    Type: AWS::SecretsManager::Secret
    Properties:
      Name: 'very-secret-thing'
      SecretString: '{"KEY":"dummy"}'

При создании стека с использованием этого шаблона, все идет как положено. Затем я go и изменяю значение секрета вне CloudFormation, так как я бы не хотел, чтобы секрет проверялся в системе контроля версий. Это вполне возможно, и документация подразумевает, что значение секрета не будет затронуто при последующих обновлениях стека CloudFormation, если я не буду изменять фиктивное значение для SecretString в шаблоне.

Итак, после установки фактического секрета в консоли AWS мне нужно инициировать повторное развертывание функции Lambda, чтобы новое значение секрета было разрешено CloudFormation и установлено в среде функции. Как мне это сделать?

Выполнение aws cloudformation deploy завершается неудачно с сообщением: Без изменений для развертывания.

Я подозреваю, что CloudFormation сравнивает «сырую» версию шаблон с тем, что было развернуто последним, без предварительного разрешения ссылок на Secrets Manager. Это тот случай? И есть ли какая-то хитрость для принудительного разыменования ранее?

Сноска. Мне хорошо известно, что использование Secrets Manager таким образом приведет к отображению секретного значения в AWS Lambda Console, и что получение значения от Secrets Manager во время выполнения будет более безопасным подходом. Это просто выходит за рамки того, что я надеюсь сделать.

Ответы [ 2 ]

1 голос
/ 05 февраля 2020

Вы можете искусственно изменить что-то еще на ресурсе AWS::Serverless::Function, чтобы принудительно обновлять его при развертывании.

Скажем, например, отметку времени:

Parameters:
  DeployTimestamp: { Type: String }

Resources:
  Function:
    Type: AWS::Serverless::Function
    Properties:
      Environment:
        Variables:
          SECRET_KEY: !Sub '{{resolve:secretsmanager:${Secret}:SecretString:KEY}}'
          SECRET_KEY_UPDATED: !Ref DeployTimestamp

Если вы выполняете развертывание из сценария, тогда вы будете делать что-то вроде aws cloudformation deploy --parameter-overrides "DeployTimestamp=$(date)", чтобы каждый раз менять значение.

Недостатком этого, конечно, является то, что функция будет обновлять каждое развертывание, даже если секрет не обновлен. Если это вас беспокоит, вы можете получить более интересную информацию и ввести aws secretsmanager describe-secret --query LastChangedDate в качестве параметра вместо текущего времени.

0 голосов
/ 09 января 2020

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

Если вы читаете секрет вне обработчика (то есть во время инициализации), число операций чтения равно сведено к минимуму. Если это java лямбда-соединение с базой данных, вы также можете использовать менеджер секретов jdb c wrapper , который автоматически извлечет секрет.

...