vague memory

うろ覚えを無くしていこうともがき苦しむ人の備忘録

Ansible で AWS Systems Manager パラメータストア (ついでにシークレットマネージャー) から値を取得(Collection版)

ansible の version は 9.5.1(core 2.16.6) での試行です。

バージョンが上がりドキュメントが移動していたので、 Ansible で AWS Systems Manager パラメータストア (ついでにシークレットマネージャー) から値を取得 の再掲です。



Amazon.Aws collection を利用します。

Requirements 記載の通り、 botocore,boto3 が必要になります。インストールされていない状態だと下記エラーとなります。

fatal: [localhost]: FAILED! => {"msg": "An unhandled exception occurred while running the lookup plugin 'amazon.aws.aws_ssm'. Error was a <class 'ansible_collections.amazon.aws.plugins.module_utils.exceptions.AnsibleBotocoreError'>, original message: Failed to import the required Python library (botocore and boto3)

Parameter Store

amazon.aws.ssm_parameter プラグインで行えます。

  • DescribeParameters
-----------------------------------------------------------------------
|                         DescribeParameters                          |
+-----------------------------------------------------+---------------+
|                        Name                         |     Type      |
+-----------------------------------------------------+---------------+
|  /dev/example-ansible-secretsmanager-secure-string  |  SecureString |
|  /dev/example-ansible-secretsmanager-string         |  String       |
|  /dev/example-ansible-secretsmanager-string-list    |  StringList   |
+-----------------------------------------------------+---------------+

tasks 例

  pre_tasks:
    - name: 'set ssm parameter store values'
      set_fact:
        uw2:
          string: "{{ lookup('amazon.aws.aws_ssm', '/dev/example-ansible-secretsmanager-string', region='us-west-2') }}"
          securestring: "{{ lookup('amazon.aws.aws_ssm', '/dev/example-ansible-secretsmanager-secure-string', region='us-west-2') }}"
          stringlist: "{{ lookup('amazon.aws.aws_ssm', '/dev/example-ansible-secretsmanager-string-list', region='us-west-2') }}"
          #not_exist: "{{ lookup('amazon.aws.aws_ssm', 'dummy') }}"
          not_exist: "{{ lookup('amazon.aws.aws_ssm', 'dummy', on_missing='warn') }}"
          #not_exist: "{{ lookup('amazon.aws.aws_ssm', 'dummy', on_missing='skip') }}"

  tasks:
    - name: 'output ssm parameter store values'
      debug:
        msg:
          - "us2: {{ uw2 }}"
          - "uw2.string: {{ uw2.string }}"
          - "uw2.securestring: {{ uw2.securestring }}"
          - "uw2.stringlist: {{ uw2.stringlist }}"
          - "uw2.not_exist: {{ uw2.not_exist }}"

実行結果

存在しないパラメータは ResourceNotFound エラーになります。

TASK [set ssm parameter store values] ****************************************************************************************************************
fatal: [localhost]: FAILED! => {"msg": "Failed to find SSM parameter dummy (ResourceNotFound)"}

エラーを回避するには on_missing オプションを利用します。

TASK [set ssm parameter store values] ****************************************************************************************************************
[WARNING]: Skipping, did not find SSM parameter dummy
ok: [localhost]

TASK [output ssm parameter store values] *************************************************************************************************************
ok: [localhost] => {
    "msg": [
        "us2: {'string': '文字列', 'securestring': '秘密の文字列', 'stringlist': 'リスト1,リスト2,リスト3', 'not_exist': ''}",
        "uw2.string: 文字列",
        "uw2.securestring: 秘密の文字列",
        "uw2.stringlist: リスト1,リスト2,リスト3",
        "uw2.not_exist: "
    ]
}

Secrets Manager

Secrets Manager からの取得と、SSM経由で取得する方法の2パターンが利用できます。

  • GetSecretValue
-----------------------------------------------------------------------------------------------
|                                       GetSecretValue                                        |
+--------------------------------------+------------------------------------------------------+
|                 Name                 |                    SecretString                      |
+--------------------------------------+------------------------------------------------------+
|  /dev/example-ansible-secretsmanager |  {"Environment":"dev","dev/test_secret":"testtest"}  |
+--------------------------------------+------------------------------------------------------+

secretsmanager_secret

amazon.aws.secretsmanager_secret プラグインを利用します。

tasks例

  pre_tasks:
    - name: 'set secrets'
      set_fact:
        uw2:
          secret1: "{{ lookup('amazon.aws.aws_secret', '/dev/example-ansible-secretsmanager', region='us-west-2') }}"
          #not_exist: "{{ lookup('amazon.aws.aws_secret', 'dummy', region='us-west-2') }}"
          not_exist: "{{ lookup('amazon.aws.aws_secret', 'dummy', region='us-west-2', on_missing='warn') }}"
        options:
          bypath: "{{ lookup('amazon.aws.aws_secret', '/dev/example-ansible-secretsmanager', region='us-west-2', bypath=true) }}"
          nested: "{{ lookup('amazon.aws.aws_secret', '/dev/example-ansible-secretsmanager.Environment', region='us-west-2', nested=true) }}"

  tasks:
    - name: 'output secrets'
      debug:
        msg:
          - "us2: {{ uw2 }}"
          - "uw2.secret1: {{ uw2.secret1 }}"
          - "uw2.secret1.Environment: {{ uw2.secret1.Environment }}"
          - "uw2.secret1['dev/test_secret']: {{ uw2.secret1['dev/test_secret'] }}"
          - "uw2.not_exist: {{ uw2.not_exist }}"

    - name: 'output options'
      debug:
        msg:
          - "options: {{ options }}"
          - "options.bypath: {{ options.bypath }}"
          - "options.nested: {{ options.nested }}"

実行結果

存在しないパラメータは ResourceNotFound エラーになります。

TASK [set secrets] ***********************************************************************************************************************************
fatal: [localhost]: FAILED! => {"msg": "Failed to find secret dummy (ResourceNotFound)"}

エラーを回避するには on_missing オプションを利用します。

bypathnested オプションを指定することで、取得形式を変えられます。(詳細はドキュメント参照)

TASK [set secrets] ***********************************************************************************************************************************
[WARNING]: Skipping, did not find secret dummy
ok: [localhost]

TASK [output secrets] ********************************************************************************************************************************
ok: [localhost] => {
    "msg": [
        "us2: {'secret1': {'Environment': 'dev', 'dev/test_secret': 'testtest'}, 'not_exist': []}",
        "uw2.secret1: {'Environment': 'dev', 'dev/test_secret': 'testtest'}",
        "uw2.secret1.Environment: dev",
        "uw2.secret1['dev/test_secret']: testtest",
        "uw2.not_exist: []"
    ]
}

TASK [output options] ********************************************************************************************************************************
ok: [localhost] => {
    "msg": [
        "options: {'bypath': {'/dev/example-ansible-secretsmanager': '{\"Environment\":\"dev\",\"dev/test_secret\":\"testtest\"}'}, 'nested': 'dev'}",
        "options.bypath: {'/dev/example-ansible-secretsmanager': '{\"Environment\":\"dev\",\"dev/test_secret\":\"testtest\"}'}",
        "options.nested: dev"
    ]
}

aws_ssm_parameter

SSM経由で SecretsManager を参照します。

tasks例

予約パス /aws/reference/secretsmanager/ を含めて指定します。

  pre_tasks:
    - name: 'set secrets'
      set_fact:
        uw2:
          ref_secret: "{{ lookup('amazon.aws.aws_ssm', '/aws/reference/secretsmanager//dev/example-ansible-secretsmanager', region='us-west-2') }}"

  tasks:
    - name: 'output secrets'
      debug:
        msg:
          - "us2: {{ uw2 }}"
          - "uw2.ref_secret: {{ uw2.ref_secret }}"
          - "uw2.ref_secret.Environment: {{ uw2.ref_secret.Environment }}"
          - "uw2.ref_secret['dev/test_secret']: {{ uw2.ref_secret['dev/test_secret'] }}"

実行結果

TASK [set secrets] ***********************************************************************************************************************************
ok: [localhost]

TASK [output secrets] ********************************************************************************************************************************
ok: [localhost] => {
    "msg": [
        "us2: {'ref_secret': {'Environment': 'dev', 'dev/test_secret': 'testtest'}}",
        "uw2.ref_secret: {'Environment': 'dev', 'dev/test_secret': 'testtest'}",
        "uw2.ref_secret.Environment: dev",
        "uw2.ref_secret['dev/test_secret']: testtest"
    ]
}

余談: no_log オプション

値をログに出したく無い場合は no_log を指定しましょう。

tasks例

  pre_tasks:
    - name: 'set secrets'
      set_fact:
        uw2:
          secret1: "{{ lookup('amazon.aws.aws_secret', '/dev/example-ansible-secretsmanager', region='us-west-2') }}"
      no_log: true

  tasks:
    - name: 'output secrets'
      debug:
        msg:
          - "us2: {{ uw2 }}"
      no_log: true

実行結果 (-v オプション指定で no_log 無し)

TASK [set secrets] ***********************************************************************************************************************************
ok: [localhost] => {"ansible_facts": {"uw2": {"secret1": {"Environment": "dev", "dev/test_secret": "testtest"}}}, "changed": false}

TASK [output secrets] ********************************************************************************************************************************
ok: [localhost] => {
    "msg": [
        "us2: {'secret1': {'Environment': 'dev', 'dev/test_secret': 'testtest'}}"
    ]
}

実行結果 (-v オプション指定で no_log 有り)

TASK [set secrets] ***********************************************************************************************************************************
ok: [localhost] => {"censored": "the output has been hidden due to the fact that 'no_log: true' was specified for this result", "changed": false}

TASK [output secrets] ********************************************************************************************************************************
ok: [localhost] => {"censored": "the output has been hidden due to the fact that 'no_log: true' was specified for this result"}