Неразрешенный параметр Хранить динамическую ссылку SecureString в шаблоне CloudFormation
Согласно AWS, при развертывании инфраструктуры, для которой требуются секреты, то есть пароли или аналогичные, с CloudFormation, одно из популярных решений состоит в использовании SecureStrings хранилища параметров из SSM.
Однако, несмотря на существующую документацию CFN, описывающую пошаговые инструкции по использованию динамических ссылок в шаблонах CFN, мне не удается использовать фактическое значение SecureStrings.
Предполагая следующее представление JSON существующей SecureString, хранящейся в хранилище параметров SSM:
{
"MyRedshiftMasterUserPassword": {
"value": "Abcd2019",
"type": "SecureString"
}
}
и шаблон YAML CFN, который использует его, как указано в документации:
Resources
Redshift:
Type: 'AWS::Redshift::Cluster'
Properties:
NodeType: dc2.large
NumberOfNodes: !Ref RedshiftNodes
ClusterType: multi-node
AutomatedSnapshotRetentionPeriod: !Ref AutomatedSnapshotRetentionPeriod
DBName: datawarehouse_v1
MasterUsername: !Ref RedshiftMasterUsername
MasterUserPassword: '{{resolve:ssm-secure:MyRedshiftMasterUserPassword:1}}'
Приведенное выше решение не работает, поэтому либо я неправильно определяю шаблон, либо поддержка этой функции не реализована должным образом, что мне кажется странным, учитывая, что оно исходит от AWS.
В частности, я столкнулся со следующими ошибками, которые все заканчиваются как UPDATE_FAILED
стек:
- Всякий раз, когда указанное имя параметра для разрешения является достаточно длинным, CloudFormation жалуется:
Параметр MasterUserPassword не является допустимым паролем, поскольку он длиннее 64 символов. (Сервис: AmazonRedshift; Код состояния: 400; Код ошибки: InvalidParameterValue; Идентификатор запроса: 7be9bd43-2927-11e9-aa88-29bbdcae859e)
- Кроме того, даже если конкретно указано, что косые черты могут использоваться в ссылках на шаблоны, например,
/infrastructure/datawarehouse/redshift/MyRedshiftMasterUserPassword
выдается следующая ошибка:
Параметр MasterUserPassword не является действительным паролем. Можно использовать только печатные символы ASCII, за исключением символов '/', '@', '' ', ' ', '\', ''. (Сервис: AmazonRedshift; Код состояния: 400; Код ошибки: InvalidParameterValue)
таким образом, в результате ссылка на SecureString, похоже, не совместима с иерархией SSM Parameter Store (параметры с косой чертой).
- Более того, удаляя любой из ранее сообщенных недопустимых символов из имени параметра, он жалуется на следующее:
Параметр MasterUserPassword должен содержать как минимум 1 заглавную букву. (Сервис: AmazonRedshift; Код состояния: 400; Код ошибки: InvalidParameterValue; Идентификатор запроса: 90a263bd-2929-11e9-80c0-ffcecf297c44)
В конце концов, хотя с помощью основного короткого без косой Parameter name
в шаблоне позволяет стеку завершать операцию обновления. Динамическая ссылка по-прежнему не возникает, так как оказывается, что фактическое используемое значение задается как имя параметра, а не значение, на которое ссылается это, например, MyRedshiftMasterUserPassword
вместо Abcd2019
,
Мне известно, что AWS Secrets Manager также можно использовать, но он не бесплатный.
1 ответ
Открыт случай поддержки с AWS, запрашивающим руководство для этого странного поведения CloudFormation.
По словам команды поддержки, на самом деле это действительно известная ошибка для службы CloudFormation, хотя и не требуется приблизительного времени для ее исправления. Разрешение параметра SSM Parameter Store SecureString при использовании в качестве динамической ссылки в конкретном случае свойства RedshiftMasterUserPassword, несмотря на то, что в документации содержится ссылка, не разрешается должным образом, и вместо этого используется имя параметра.
Кроме того, они предлагают 2 обходных пути, пока проблема исправлена:
- Получить 'MasterUserPassword' для Redshift из входного параметра со свойством
NoEcho
установить в true. Свойство NoEcho позволяет маскировать значение пароля, и вам не нужно хранить пароль в файле шаблона. Однако каждый раз, когда вы обновляете стек, вам нужно вводить пароль в качестве входного параметра. Для справки, фрагмент кода ниже будет полезен.
Второй вариант, который является более универсальным:
- Определите лямбда-резервный пользовательский ресурс в файле шаблона, который запрашивает службу SSM и возвращает пароль в CloudFormation. В этом случае вам нужно написать пользовательский код для лямбда-функции, которая использует вызов API AWS GetParameter для получения значения параметра SSM Secure String и возвращает дешифрованное значение в CloudFormation.
Другие поддерживаемые свойства для динамической ссылки работают нормально.