mito’s blog

IT技術メインの雑記。思い立ったが吉日。

[Ansible][AWS] SecretsManagerモジュールでユーザとパスワードを登録する(更新2023.02.13)

はじめに

community.awsにあるsecretsmanager_secretモジュールで、ユーザとパスワードを登録します。

community.aws.secretsmanager_secret module – Manage secrets stored in AWS Secrets Manager — Ansible Documentation



環境

  • ansible core: 2.13.7
  • community.aws: 5.0.0

community.awsの最新版は、Ansible Core 2.11.0以前のバージョンをサポートしていません。

Ansible version compatibility Tested with the Ansible Core 2.12, and 2.13 releases, and the current development version of Ansible. Ansible Core versions before 2.11.0 are not supported. In particular, Ansible Core 2.10 and Ansible 2.9 are not supported.


AWS Secrets Managerにユーザとパスワードを登録する

Playbook

ほぼ公式ドキュメント記載のサンプル通りです。
2つのkey:valueを登録するので、json_secretオプションを指定します。
また、ローテーションは指定していないので無効のままです。

注意点として、SecretsManagerのシークレット名は完全に削除されるまで最低7日間の待機期間が必要です。
7日以内に同じシークレット名を再作成することはできないので、短期間で再作成するならユニークな文字列を付与することになります。

---
- hosts: localhost
  gather_facts: no
  
  tasks:
    - name: Add Secrets Manager
      community.aws.secretsmanager_secret:
        name: "web"
        state: present
        secret_type: 'string'
        # json_secretは、登録するJSON形式のデータを指定します。
        # secretと排他関係にあります。secretは、文字列またはバイナリ データを登録するときに指定します。
        json_secret: '{"user":"ec2-user", "password":"12345678"}'


実行ログ

想定通りに登録されました。

 $ ansible-playbook add_secretmanager.yml 
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'

PLAY [localhost] ************************************************************

TASK [Add Secrets Manager] **************************************************
changed: [localhost]

PLAY RECAP ******************************************************************
localhost : ok=1  changed=1  unreachable=0  failed=0  skipped=0  rescued=0  ignored=0   

$ 




AWS Secrets Managerからユーザ、パスワードを取得する

Playbook

登録したなら取り出します。
lookupプラグインを使い、シークレット名を指定します。

---
- hosts: localhost
  gather_facts: no
  
  tasks:
    - debug:
        msg: "{{ lookup('amazon.aws.aws_secret', 'web') }}"


実行ログ

さらっと取得できました。

 $ ansible-playbook get_secretmanager.yml 
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'

PLAY [localhost] ***********************************************************

TASK [debug] ***************************************************************
ok: [localhost] => {
    "msg": {
        "password": "12345678",
        "user": "ec2-user"
    }
}

PLAY RECAP *****************************************************************
localhost : ok=1  changed=0  unreachable=0  failed=0  skipped=0  rescued=0  ignored=0   

$ 


※2023.02.13 追加

AWS Secrets Managerのパスワードを更新する

登録済みのパスワードを更新します。
シークレットに複数のkey:valueが登録されている場合、一部のみの更新・追加はできません。
変更が無いkey:valueは削除され、更新したkey:value、追加したkey:valueのみになります。
そのため、パスワードの更新とともにユーザを再登録します。

Playbook

登録したパスワードを更新します。
ユーザは変更ありませんが、シークレットから取得します。

---
- hosts: localhost
  gather_facts: no
  
  tasks:
    - debug:
        msg: "{{ lookup('amazon.aws.aws_secret', 'web') }}"
      register: result

    - name: change password for Secrets Manager
      community.aws.secretsmanager_secret:
        name: "web"
        state: present
        secret_type: 'string'
        json_secret: "{{ new }}"
      vars:
        new:
          user: "{{ result.msg.user }}"
          password: "oioioioi"    # 更新するパスワード

    - debug:
        msg: "{{ lookup('amazon.aws.aws_secret', 'web') }}"


実行ログ

無事、パスワードが更新できました。

$ ansible-playbook update_secretmanager.yml 
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'

PLAY [localhost] ***********************************************************

TASK [debug] ***************************************************************
ok: [localhost] => {
    "msg": {
        "password": "12345678",
        "user": "ec2-user"
    }
}

TASK [change password for Secrets Manager] *********************************
changed: [localhost]

TASK [debug] ***************************************************************
ok: [localhost] => {
    "msg": {
        "password": "oioioioi",
        "user": "ec2-user"
    }
}

PLAY RECAP *****************************************************************
localhost : ok=3  changed=1  unreachable=0  failed=0  skipped=0  rescued=0  ignored=0   

$ 


AWS Secrets Managerのパスワード更新に失敗するパターン

シークレットに複数のkey:valueが登録されている状態で、パスワードのみ登録(更新)してみます。

Playbook

json_secretに、パスワードのみを指定します。

---
- hosts: localhost
  gather_facts: no
  
  tasks:
    - debug:
        msg: "{{ lookup('amazon.aws.aws_secret', 'web') }}"
      register: result

    - name: change password for Secrets Manager
      community.aws.secretsmanager_secret:
        name: "web"
        state: present
        secret_type: 'string'
        json_secret: "{{ new }}"
      vars:
        new:
          password: "oioioioi"    # 更新するパスワード

    - debug:
        msg: "{{ lookup('amazon.aws.aws_secret', 'web') }}" 


実行ログ

ユーザは削除され、更新したパスワードのみが残ります。

$ ansible-playbook update_secretsmanager.yml
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'

PLAY [localhost] ***********************************************************

TASK [debug] ***************************************************************
ok: [localhost] => {
    "msg": {
        "password": "12345678",
        "user": "ec2-user"
    }
}

TASK [change password for Secrets Manager] *********************************
changed: [localhost]

TASK [debug] ***************************************************************
ok: [localhost] => {
    "msg": {
        "password": "oioioioi"
    }
}

PLAY RECAP *****************************************************************
localhost : ok=3  changed=1  unreachable=0  failed=0  skipped=0  rescued=0  ignored=0   

$ 


備考

AnsibleでのSecretsManagerは、AWS CLIコマンドから見るに値の更新はできなさそうで、すべての値を再登録しかなさそう。