LoginSignup
0
1

More than 5 years have passed since last update.

Ansible2.6でAWS KMSを使うときにハマったこと

Last updated at Posted at 2018-12-23

はじめに

AnsibleでAWS KMS(以下KMS)を構築&利用しようとして、Ansibleの使用言語であるPythonにハマった話です。
インフラ自動構築ツールとしてのAnsibleの立ち位置や、使い方などは省略させてもらいます。
(Ansible歴が15営業日程度なので、アレレな使い方をしている可能性があります。)

前提条件

Ansibleでしたかったこと

  1. KMSカスタマーマスターキーの構築(以下CMK)
  2. CMKにエイリアスを付与する
  3. CMKをエイリアスから取得する
  4. CMKでEBSを暗号化

ハマった経緯

AnsibleのAWSモジュール一覧を見たところ、KMS構築モジュールがないやんけ!
(え、あるよと思った方、実はこのaws_kmsモジュールはKMSを利用するIAMロール・ユーザーを定める代物です。)
となり、AnsibleからAWS CloudFormation(以下CloudFormation)を呼び(使用モジュール)、Ansibleでしたかったこと1 & 2を実施するという荒技をしました。
aws_kms_factsモジュール(以下aws_kms_facts)で暗号化に使いたいCMKをエイリアスのフィルターで取得し、ec2_volモジュールで暗号化しようとしたときに、ことは起こりました。

実行Ansibleソース

エイリアスからEBS暗号化に使用するCMKを取得する

- name: KMS for EBS
  aws_kms_facts:
    region: "{{ vars.region }}"
    filters:
      alias: "{{ vars.kms_by_cloudformation.kms_ebs_tag }}"
  register: _aws_kms_facts_for_ebs
- debug: var=_aws_kms_facts_for_ebs
- debug: var=_aws_kms_facts_for_ebs.keys

エイリアスからEBS暗号化に使用するCMKを取得した結果の標準出力

_aws_kms_facts_for_ebs.keys[0].key_id を取得したかったのです。
なのに、_aws_kms_facts_for_ebs.keysがないだと。。
参照:https://qiita.com/odashun1015/items/f7bd23336264f022e3a1

ok: [localhost] => {
    "_aws_kms_facts_for_ebs": {
        "changed": false, 
        "failed": false, 
        "keys": [
            {
                "aliases": [
                    "test-kms-ebs"
                ], 
                "aws_account_id": "123456789", 
                "creation_date": "2018-12-21T03:05:33.885000+00:00", 
                "description": "customer master key for ebs", 
                "enabled": true, 
                "grants": [], 
                "key_arn": "arn:aws:kms:eu-west-1:123456789:key/123456789abc-123456789-abc", 
                "key_id": "123456789abc-123456789-abc", 
                "key_manager": "CUSTOMER", 
                "key_state": "Enabled", 
                "key_usage": "ENCRYPT_DECRYPT", 
                "origin": "AWS_KMS", 
                "policies": [
                    "{\n  \"Version\" : \"2012-10-17\",\n  \"Id\" : \"kms-ebs\",\n  \"Statement\" : [ {\n    \"Sid\" : \"Enable IAM User Permissions\",\n    \"Effect\" : \"Allow\",\n    \"Principal\" : {\n      \"AWS\" : \"arn:aws:iam::123456789:root\"\n    },\n    \"Action\" : \"kms:*\",\n    \"Resource\" : \"*\"\n  }, {\n    \"Sid\" : \"Allow access for Key Administrators\",\n    \"Effect\" : \"Allow\",\n    \"Principal\" : {\n      \"AWS\" : \"arn:aws:iam::123456789:user/TestUser\"\n    },\n    \"Action\" : [ \"kms:Create*\", \"kms:Describe*\", \"kms:Enable*\", \"kms:List*\", \"kms:Put*\", \"kms:Update*\", \"kms:Revoke*\", \"kms:Disable*\", \"kms:Get*\", \"kms:Delete*\", \"kms:TagResource\", \"kms:UntagResource\", \"kms:ScheduleKeyDeletion\", \"kms:CancelKeyDeletion\" ],\n    \"Resource\" : \"*\"\n  } ]\n}"
                ], 
                "tags": {
                    "Name": "test-kms-ebs"
                }
            }
        ]
    }
}
ok: [localhost] => {
    "_aws_kms_facts_for_ebs.keys": "<built-in method keys of dict object at 0x2715490>"
}

EBS暗号化⇨エラー発生

- name: Encrypted EBS for App Server 1
  ec2_vol:
    region: "{{ vars.region }}"
    device_name: "{{ vars.ec2_app.volumes.volume_02.device_name }}"
    volume_type: "{{ vars.ec2_app.volumes.volume_02.volume_type }}"
    volume_size: "{{ vars.ec2_app.volumes.volume_02.volume_size }}"
    delete_on_termination: "{{ vars.ec2_app.volumes.volume_02.delete_on_termination }}"
    encrypted: yes
    kms_key_id: "{{ _aws_kms_facts_for_ebs.keys[0].key_id }}"
    tags:
      Name: "{{ vars.ec2_app_01.instance_tags.Name }}"
  register: _ec2_vol_app_01_enc
- debug: var=_ec2_vol_app_01_enc

出現したエラー

TASK [ec2 : Encrypted EBS for App Server 1] ******************************************************************************************************************
fatal: [localhost]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: dict object has no element 0\n\nThe error appears to have been in '/home/test/ansible/roles/ec2/tasks/main.yml': line 67, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- name: Encrypted EBS for App Server 1\n  ^ here\n"}
    to retry, use: --limit @/home/test/ansible/site.retry

[localhost]: FAILED! => {"msg": "The task includes an option with an undefined variable. 

え、aws_kms_facts実行結果で取得できるdictオブジェクトに確かに「keys」というキーはあるよ!
なぜバリューが取れない??。上記参照ページに出会うまで、キー名を変えたりして、方向性の違うことをしてました。

解決策

EBS暗号化を、aws_kms_facts実行結果で取得できるdictオブジェクトのキーをひとつひとつ舐め、「keys」というキーがあれば、そのバリューを取得する処理に変更しました。
EBS暗号化ソースは以下です。

- name: Encrypted EBS for App Server 1
  ec2_vol:
    region: "{{ vars.region }}"
    device_name: "{{ vars.ec2_app.volumes.volume_02.device_name }}"
    volume_type: "{{ vars.ec2_app.volumes.volume_02.volume_type }}"
    volume_size: "{{ vars.ec2_app.volumes.volume_02.volume_size }}"
    delete_on_termination: "{{ vars.ec2_app.volumes.volume_02.delete_on_termination }}"
    encrypted: yes
    kms_key_id: >-
      {% if item.key == 'keys' %}{{ item.value[0].key_id }}{% endif %}
    instance: "{{ _ec2_app_01.tagged_instances[0].id }}"
    tags:
      Name: "{{ vars.ec2_app_01.instance_tags.Name }}"
  with_dict: "{{ _aws_kms_facts_for_ebs }}"
  register: _ec2_vol_app_01_enc
- debug: var=_ec2_vol_app_01_enc

まとめ

Pythonのkeysは特別な意味を持つので、オブジェクト内の「keys」キーは、keys()と間違われないようにしましょう

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1