Ansible 获取 AWS SSM Parameter Store 值但无法解密安全字符串

69次阅读
没有评论

问题描述

需要从 AWS SSM Parameter Store 中查找一个值,但如果参数类型是安全字符串,它需要失败。
用户不希望解密安全字符串参数,并且希望检测它们的类型并优雅地失败。
以下是用户提供的 Ansible 代码片段:

- name: Get the value from AWS Parameter Store
  set_fact:
    var_value: "{{ lookup('aws_ssm', var_path, decrypt=False, region=aws_region, aws_access_key=aws_access_key, aws_secret_key=aws_secret_key) }}"
- name: Show the value
  debug:
    msg:
      - "VALUE:  {{ var_value | default( 'FAILED_TO_DECRYPT' ) }}"

然而,当告诉 aws_ssm 模块不要解密安全字符串时,它并不会失败。它返回加密的字符串(没有帮助)。用户无法找到一种检测参数类型的方法。

解决方案

请注意以下操作注意版本差异及修改前做好备份。

方案1

一种方法是使用 decrypt=truedecrypt=false 两次获取值,并进行比较。
以下是在 Ansible 中如何实现的步骤:
1. 使用 lookup 函数两次获取值,一次设置 decrypt=true,一次设置 decrypt=false
2. 将两次获取的值进行比较。
3. 如果两次获取的值不同,并且 permission_to_decrypt 为 false,则失败并显示错误消息。
4. 如果两次获取的值相同,或者 permission_to_decrypt 为 true,则显示值。
以下是一个示例 Ansible 代码片段:

- name: Get the value from AWS Parameter Store
  set_fact:
    var_value_decrypted: "{{ lookup('aws_ssm', var_path, decrypt=true, region=aws_region, aws_access_key=aws_access_key, aws_secret_key=aws_secret_key) }}"
    var_value_as_is: "{{ lookup('aws_ssm', var_path, decrypt=false, region=aws_region, aws_access_key=aws_access_key, aws_secret_key=aws_secret_key) }}"
- name: Fail since the value is encrypted and permission_to_decrypt is false
  debug:
    msg:
      - "VALUE:  FAILED_TO_DECRYPT"
  when: var_value_decrypted != var_value_as_is and not permission_to_decrypt | bool
- name: Show the value
  debug:
    msg:
      - "VALUE:  {{ var_value_decrypted | default( 'KEY_NOT_FOUND' ) }}"
  when: var_value_decrypted == var_value_as_is or permission_to_decrypt | bool

在上面的示例中,我们首先使用 lookup 函数两次获取值,一次设置 decrypt=true,一次设置 decrypt=false。然后,我们将两次获取的值进行比较。如果两次获取的值不同,并且 permission_to_decrypt 为 false,则失败并显示错误消息。如果两次获取的值相同,或者 permission_to_decrypt 为 true,则显示值。
请注意,这种方法需要获取两次值,可能会增加一些额外的开销。如果性能是一个问题,可以考虑其他方法。

方案2

使用脚本或工具来管理容器的启动顺序可能会增加复杂性,并且需要确保容器A和容器B之间的依赖关系正确设置。
另一种方法是编写脚本或使用工具来控制容器的运行顺序。你可以使用docker run命令来手动控制容器的启动顺序,或者使用一些第三方工具来管理容器的依赖关系。

示例:

以下是一个简单的bash脚本示例,可以在容器A启动后启动容器B:

#!/bin/bash
# 启动容器A
docker run -d --name container_a your_image_a
# 等待容器A完全启动
while ! docker exec container_a echo "Container A is ready"; do
  sleep 1
done
# 启动容器B
docker run -d --name container_b your_image_b

在这个示例中,我们首先使用docker run命令启动容器A,并将其命名为container_a。然后,使用一个循环来等待容器A完全启动(这里是通过在容器内运行echo命令来测试)。一旦容器A就绪,我们再使用docker run命令启动容器B,并将其命名为container_b

正文完