chef-boneyard / chef-vault

chef-vault cookbook
https://supermarket.chef.io/cookbooks/chef-vault
Apache License 2.0
60 stars 53 forks source link

How to use chef-vault with Kitchen ? #59

Closed valter-silva-au closed 6 years ago

valter-silva-au commented 7 years ago

Cookbook version

chef-vault', '~> 2.1'

Chef-client version

Chef 12.19.36

Platform Details

Ubuntu 16.04/x86_64-linux

Scenario:

Use chef-vault to secure my SSH keys. However, I want to test my cookbook using Kitchen first.

Steps to Reproduce:

Clone my repository:

https://github.com/valterhenrique/stunning-robot

Access my cookbook folder kitchen_vault, and run:

kitchen converge

Expected Result:

I want to have all the benefits of chef-vault, I want to be able to use with my kitchen environment as well. I guess my items are being retrieved as data bags, and not as vaults.

Actual Result:

kitchen converge
-----> Starting Kitchen (v1.15.0)
-----> Converging <default-ubuntu-1604>...
       Preparing files for transfer
       Preparing dna.json
       Resolving cookbook dependencies with Berkshelf 5.6.2...
       Removing non-cookbook files before transfer
       Preparing data_bags
       Preparing environments
       Preparing nodes
       Preparing clients
       Preparing validation.pem
       Preparing client.rb
-----> Chef Omnibus installation detected (install only if missing)
       Transferring files to <default-ubuntu-1604>
       [2017-03-03T11:58:32+00:00] INFO: Forking chef instance to converge...
       Starting Chef Client, version 12.19.36
       [2017-03-03T11:58:32+00:00] INFO: *** Chef 12.19.36 ***
       [2017-03-03T11:58:32+00:00] INFO: Platform: x86_64-linux
       [2017-03-03T11:58:32+00:00] INFO: Chef-client pid: 4781
       [2017-03-03T11:58:33+00:00] INFO: Setting the run_list to ["recipe[chef-vault]", "recipe[kitchen_vault::default]"] from CLI options
       [2017-03-03T11:58:33+00:00] INFO: Run List is [recipe[chef-vault], recipe[kitchen_vault::default]]
       [2017-03-03T11:58:33+00:00] INFO: Run List expands to [chef-vault, kitchen_vault::default]
       [2017-03-03T11:58:33+00:00] INFO: Starting Chef Run for default-ubuntu-1604
       [2017-03-03T11:58:33+00:00] INFO: Running start handlers
       [2017-03-03T11:58:33+00:00] INFO: Start handlers complete.
       [2017-03-03T11:58:33+00:00] INFO: HTTP Request Returned 404 Not Found: Object not found: 
       resolving cookbooks for run list: ["chef-vault", "kitchen_vault::default"]
       [2017-03-03T11:58:33+00:00] INFO: Loading cookbooks [chef-vault@2.1.1, kitchen_vault@0.1.0]
       Synchronizing Cookbooks:
         [2017-03-03T11:58:33+00:00] INFO: Storing updated cookbooks/kitchen_vault/recipes/default.rb in the cache.
       - chef-vault (2.1.1)
         - kitchen_vault (0.1.0)
       Installing Cookbook Gems:
       Compiling Cookbooks...
       Recipe: chef-vault::default
         * chef_gem[chef-vault] action install[2017-03-03T11:58:33+00:00] INFO: Processing chef_gem[chef-vault] action install (chef-vault::default line 22)
        (up to date)

         ================================================================================
         Recipe Compile Error in /tmp/kitchen/cache/cookbooks/kitchen_vault/recipes/default.rb
         ================================================================================

         RuntimeError
         ------------
         Trying to load a regular data bag item dbpassword from secrets, and databag_fallback is disabled

         Cookbook Trace:
         ---------------
           /tmp/kitchen/cache/cookbooks/chef-vault/libraries/helpers.rb:41:in `chef_vault_item'
           /tmp/kitchen/cache/cookbooks/kitchen_vault/recipes/default.rb:10:in `from_file'

         Relevant File Content:
         ----------------------
         /tmp/kitchen/cache/cookbooks/chef-vault/libraries/helpers.rb:

          34:    # @param [String] id Identifier of the data bag item to load.
          35:    def chef_vault_item(bag, id)
          36:      if ChefVault::Item.vault?(bag, id)
          37:        ChefVault::Item.load(bag, id)
          38:      elsif node['chef-vault']['databag_fallback']
          39:        Chef::DataBagItem.load(bag, id)
          40:      else
          41>>       raise "Trying to load a regular data bag item #{id} from #{bag}, and databag_fallback is disabled"
          42:      end
          43:    end
          44:  
          45:    # Helper method which provides an environment wrapper for a data bag.
          46:    # This allows for easy access to current environment secrets inside
          47:    # of an item.
          48:    # @example
          49:    # item = chef_vault_item_for_environment('secrets', 'bacon')
          50:    # log 'Yeah buddy!' if item['type'] == 'applewood_smoked'

         Platform:
         ---------
         x86_64-linux

         Running handlers:
       [2017-03-03T11:58:33+00:00] ERROR: Running exception handlers
         Running handlers complete
       [2017-03-03T11:58:33+00:00] ERROR: Exception handlers complete
         Chef Client failed. 0 resources updated in 01 seconds
       [2017-03-03T11:58:33+00:00] FATAL: Stacktrace dumped to /tmp/kitchen/cache/chef-stacktrace.out
       [2017-03-03T11:58:33+00:00] FATAL: Please provide the contents of the stacktrace.out file if you file a bug report
       [2017-03-03T11:58:33+00:00] ERROR: Trying to load a regular data bag item dbpassword from secrets, and databag_fallback is disabled
       [2017-03-03T11:58:33+00:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)
tquid commented 6 years ago

You need to set databag_fallback in your .kitchen.yml:

suites:
  - name: default
    run_list:
      - recipe[foo::bar]
      ...
    data_bags_path: 'test/integration/data_bags' # This is relative to the directory with .kitchen.yml
    attributes:
      chef-vault:
        databags_fallback: true

With that switch turned on, it should operate as intended: if an encrypted vault exists, it uses that; if not, it falls back to using an unencrypted data bag found at the data_bags_path.

valter-silva-au commented 6 years ago

Thank you @tquid !

jaypipes commented 5 years ago

Hello. I'm having this exact same issue and the proposed solution isn't working for me. I'm hoping you might be able to advise me.

I have a .kitchen.yaml file that looks like this:

---
driver:
  name: dokken
  chef_version: 12.14.89

transport:
  name: dokken

provisioner:
  name: dokken

verifier:
  name: inspec

platforms:
  - name: ylinux6
    driver:
      hostname: kitchen-ylinux6
      image: docker-registry.ops.yahoo.com:4443/ylinux/ylinux6:6.8.4

suites:
  - name: default
    run_list:
      - recipe[openstack-yahoo-database::default]
      - recipe[openstack-yahoo-database::db_node]
    data_bags_path: 'test/integration/data_bags' # relative to the directory with .kitchen.yml
    attributes:
      chef-vault:
        databags_fallback: true

I have a data bag called test/integration/data_bags/vault_dev.json that looks like this:

$ cat test/integration/data_bags/vault_dev.json 
{
    "db_passwords": {
        "mysql_root": "password",
        "failover": "password"
    }
}

However, when I attempt to converge the cookbook in question, I'm getting a failure to find the vault item:

UNKNOWN-10-89-84-X:cookbook-openstack-yahoo-database jpipes$ kitchen converge
-----> Starting Kitchen (v1.20.0)
-----> Converging <default-ylinux6>...
       Creating kitchen sandbox in /Users/jpipes/.dokken/kitchen_sandbox/6bc16b7f27-default-ylinux6
       Preparing dna.json
       Resolving cookbook dependencies with Berkshelf 6.3.1...
       Removing non-cookbook files before transfer
       Preparing data_bags
       Preparing validation.pem
       Preparing client.rb
Starting Chef Client, version 12.14.89
Creating a new client identity for default-ylinux6 using the validator key.
resolving cookbooks for run list: ["openstack-yahoo-database::default", "openstack-yahoo-database::db_node"]
Synchronizing Cookbooks:
  - openstack-yahoo-database (0.0.71)
  - openstack-common (15.1.1)
  - openstack-yahoo-common (0.0.191)
  - database (6.1.1)
  - mysql (8.5.1)
  - mysql-multi (2.1.7)
  - mysql2_chef_gem (2.1.0)
  - cron (3.0.0)
  - openstack-yahoo-ats (0.0.57)
  - apt (5.1.0)
  - mariadb (1.5.4)
  - yum (3.13.0)
  - yum-epel (2.1.2)
  - poise-python (1.7.0)
  - memcached (5.1.1)
  - postgresql (7.1.0)
  - chef-sugar (4.0.1)
  - openssl (8.5.2)
  - build-essential (8.1.1)
  - compat_resource (12.19.1)
  - selinux_policy (2.1.0)
  - yum-scl (0.2.0)
  - poise (2.8.2)
  - poise-languages (2.1.2)
  - runit (4.3.0)
  - seven_zip (3.0.0)
  - mingw (2.1.0)
  - inifile_chef_gem (0.1.0)
  - poise-archive (1.5.0)
  - packagecloud (1.0.0)
  - windows (5.0.0)
Installing Cookbook Gems:
Compiling Cookbooks...
[2018-08-16T19:34:55+00:00] WARN: PostgresqlDatabase already exists!  Deprecation class overwrites Custom resource postgresql_database from cookbook postgresql
[2018-08-16T19:34:55+00:00] WARN: Chef::Provider::AptRepository already exists!  Cannot create deprecation class for LWRP provider apt_repository from cookbook apt
[2018-08-16T19:34:55+00:00] WARN: AptRepository already exists!  Deprecation class overwrites Custom resource apt_repository from cookbook apt
[2018-08-16T19:34:55+00:00] WARN: Chef::Provider::YumRepository already exists!  Cannot create deprecation class for LWRP provider yum_repository from cookbook yum
[2018-08-16T19:34:55+00:00] WARN: YumRepository already exists!  Deprecation class overwrites Custom resource yum_repository from cookbook yum
Recipe: openstack-yahoo-common::ostk_rhel_setup
  * chef_gem[chef-vault] action install (up to date)
Recipe: openstack-yahoo-database::db_node
  * chef_gem[chef-vault] action install (up to date)

  ================================================================================
  Recipe Compile Error in /opt/kitchen/cache/cookbooks/openstack-yahoo-database/recipes/default.rb
  ================================================================================

  ChefVault::Exceptions::KeysNotFound
  -----------------------------------
  vault_dev/db_passwords_keys could not be found

  Cookbook Trace:
  ---------------
    /opt/kitchen/cache/cookbooks/openstack-yahoo-common/libraries/password_helper.rb:9:in `get_vault_secret'
    /opt/kitchen/cache/cookbooks/openstack-yahoo-database/recipes/db_node.rb:50:in `from_file'
    /opt/kitchen/cache/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/run_context.rb:347:in `load_recipe'
    /opt/kitchen/cache/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/run_context.rb:303:in `block in include_recipe'
    /opt/kitchen/cache/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/run_context.rb:302:in `each'
    /opt/kitchen/cache/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/run_context.rb:302:in `include_recipe'
    /opt/kitchen/cache/cookbooks/openstack-yahoo-database/recipes/default.rb:6:in `from_file'
    /opt/kitchen/cache/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/run_context.rb:347:in `load_recipe'

  Relevant File Content:
  ----------------------
  /opt/kitchen/cache/cookbooks/openstack-yahoo-common/libraries/password_helper.rb:

    2:    def get_vault_secret(vault_databag, vault_item)
    3:      begin
    4:        require 'chef-vault'
    5:      rescue LoadError
    6:        Chef::Log.warn("Missing gem 'chef-vault'")
    7:      end
    8:      ::Chef::Log.info "Loading vault secret #{vault_item} from #{vault_databag}"
    9>>     ::ChefVault::Item.load(vault_databag, vault_item)
   10:    end
   11:  
   12:    # Monkey patch upstream rabbit_transport_url
   13:    # Shortcut to get the transport_url for rabbitmq
   14:    def rabbit_transport_url(service)
   15:      ::Chef::Log.info 'Oath shortcut to get the transport_url for rabbitmq'
   16:      mq_user = node['openstack']['mq'][service]['rabbit']['userid']
   17:      vault_databag = node['openstack']['yahoo_common']['vault_name']
   18:      vault_item = node['openstack']['yahoo_common']['vault_item_user_passwords']

  Platform:
  ---------
  x86_64-linux

  Running handlers:
[2018-08-16T19:34:56+00:00] ERROR: Running exception handlers
  Running handlers complete
[2018-08-16T19:34:56+00:00] ERROR: Exception handlers complete
  Chef Client failed. 0 resources updated in 39 seconds
[2018-08-16T19:34:56+00:00] FATAL: Stacktrace dumped to /opt/kitchen/cache/chef-stacktrace.out
[2018-08-16T19:34:56+00:00] FATAL: Please provide the contents of the stacktrace.out file if you file a bug report
[2018-08-16T19:34:56+00:00] ERROR: vault_dev/db_passwords_keys could not be found
[2018-08-16T19:34:56+00:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)
>>>>>> ------Exception-------
>>>>>> Class: Kitchen::ActionFailed
>>>>>> Message: 1 actions failed.
>>>>>>     Converge failed on instance <default-ylinux6>.  Please see .kitchen/logs/default-ylinux6.log for more details
>>>>>> ----------------------
>>>>>> Please see .kitchen/logs/kitchen.log for more details
>>>>>> Also try running `kitchen diagnose --all` for configuration

Any ideas? Thanks much in advance for any help!

-jay

tquid commented 5 years ago

Hi @jaypipes, your databag doesn't have the right format. All databag files have to have an "id" key, and its value has to match the filename (without ".json"). So your file should look like:

{
    "id": "vault_dev",
    "db_passwords": {
        "mysql_root": "password",
        "failover": "password"
    }
}
jaypipes commented 5 years ago

Hmm, that didn't seem to work, @tquid

UNKNOWN-10-89-84-X:cookbook-openstack-yahoo-database jpipes$ cat test/integration/data_bags/vault_dev.json 
{
    "id": "vault_dev",
    "db_passwords": {
        "mysql_root": "password",
        "failover": "password"
    }
}
UNKNOWN-10-89-84-X:cookbook-openstack-yahoo-database jpipes$ kitchen converge
-----> Starting Kitchen (v1.20.0)
-----> Converging <default-ylinux6>...
       Creating kitchen sandbox in /Users/jpipes/.dokken/kitchen_sandbox/6bc16b7f27-default-ylinux6
       Preparing dna.json
       Resolving cookbook dependencies with Berkshelf 6.3.1...
       Removing non-cookbook files before transfer
       Preparing data_bags
       Preparing validation.pem
       Preparing client.rb
Starting Chef Client, version 12.14.89
Creating a new client identity for default-ylinux6 using the validator key.
resolving cookbooks for run list: ["openstack-yahoo-database::default", "openstack-yahoo-database::db_node"]
Synchronizing Cookbooks:
  - openstack-yahoo-database (0.0.71)
  - openstack-common (15.1.1)
  - openstack-yahoo-common (0.0.191)
  - database (6.1.1)
  - mysql (8.5.1)
  - mysql-multi (2.1.7)
  - mysql2_chef_gem (2.1.0)
  - cron (3.0.0)
  - openstack-yahoo-ats (0.0.57)
  - apt (5.1.0)
  - mariadb (1.5.4)
  - yum (3.13.0)
  - yum-epel (2.1.2)
  - poise-python (1.7.0)
  - memcached (5.1.1)
  - postgresql (7.1.0)
  - chef-sugar (4.0.1)
  - openssl (8.5.2)
  - build-essential (8.1.1)
  - compat_resource (12.19.1)
  - selinux_policy (2.1.0)
  - yum-scl (0.2.0)
  - poise (2.8.2)
  - poise-languages (2.1.2)
  - runit (4.3.0)
  - seven_zip (3.0.0)
  - mingw (2.1.0)
  - inifile_chef_gem (0.1.0)
  - poise-archive (1.5.0)
  - packagecloud (1.0.0)
  - windows (5.0.0)
Installing Cookbook Gems:
Compiling Cookbooks...
[2018-08-16T20:36:06+00:00] WARN: PostgresqlDatabase already exists!  Deprecation class overwrites Custom resource postgresql_database from cookbook postgresql
[2018-08-16T20:36:06+00:00] WARN: Chef::Provider::AptRepository already exists!  Cannot create deprecation class for LWRP provider apt_repository from cookbook apt
[2018-08-16T20:36:06+00:00] WARN: AptRepository already exists!  Deprecation class overwrites Custom resource apt_repository from cookbook apt
[2018-08-16T20:36:06+00:00] WARN: Chef::Provider::YumRepository already exists!  Cannot create deprecation class for LWRP provider yum_repository from cookbook yum
[2018-08-16T20:36:06+00:00] WARN: YumRepository already exists!  Deprecation class overwrites Custom resource yum_repository from cookbook yum
Recipe: openstack-yahoo-common::ostk_rhel_setup
  * chef_gem[chef-vault] action install (up to date)
Recipe: openstack-yahoo-database::db_node
  * chef_gem[chef-vault] action install (up to date)

  ================================================================================
  Recipe Compile Error in /opt/kitchen/cache/cookbooks/openstack-yahoo-database/recipes/default.rb
  ================================================================================

  ChefVault::Exceptions::KeysNotFound
  -----------------------------------
  vault_dev/db_passwords_keys could not be found

  Cookbook Trace:
  ---------------
    /opt/kitchen/cache/cookbooks/openstack-yahoo-common/libraries/password_helper.rb:9:in `get_vault_secret'
    /opt/kitchen/cache/cookbooks/openstack-yahoo-database/recipes/db_node.rb:50:in `from_file'
    /opt/kitchen/cache/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/run_context.rb:347:in `load_recipe'
    /opt/kitchen/cache/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/run_context.rb:303:in `block in include_recipe'
    /opt/kitchen/cache/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/run_context.rb:302:in `each'
    /opt/kitchen/cache/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/run_context.rb:302:in `include_recipe'
    /opt/kitchen/cache/cookbooks/openstack-yahoo-database/recipes/default.rb:6:in `from_file'
    /opt/kitchen/cache/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/run_context.rb:347:in `load_recipe'

  Relevant File Content:
  ----------------------
  /opt/kitchen/cache/cookbooks/openstack-yahoo-common/libraries/password_helper.rb:

    2:    def get_vault_secret(vault_databag, vault_item)
    3:      begin
    4:        require 'chef-vault'
    5:      rescue LoadError
    6:        Chef::Log.warn("Missing gem 'chef-vault'")
    7:      end
    8:      ::Chef::Log.info "Loading vault secret #{vault_item} from #{vault_databag}"
    9>>     ::ChefVault::Item.load(vault_databag, vault_item)
   10:    end
   11:  
   12:    # Monkey patch upstream rabbit_transport_url
   13:    # Shortcut to get the transport_url for rabbitmq
   14:    def rabbit_transport_url(service)
   15:      ::Chef::Log.info 'Oath shortcut to get the transport_url for rabbitmq'
   16:      mq_user = node['openstack']['mq'][service]['rabbit']['userid']
   17:      vault_databag = node['openstack']['yahoo_common']['vault_name']
   18:      vault_item = node['openstack']['yahoo_common']['vault_item_user_passwords']

  Platform:
  ---------
  x86_64-linux

  Running handlers:
[2018-08-16T20:36:08+00:00] ERROR: Running exception handlers
  Running handlers complete
[2018-08-16T20:36:08+00:00] ERROR: Exception handlers complete
  Chef Client failed. 0 resources updated in 43 seconds
[2018-08-16T20:36:08+00:00] FATAL: Stacktrace dumped to /opt/kitchen/cache/chef-stacktrace.out
[2018-08-16T20:36:08+00:00] FATAL: Please provide the contents of the stacktrace.out file if you file a bug report
[2018-08-16T20:36:08+00:00] ERROR: vault_dev/db_passwords_keys could not be found
[2018-08-16T20:36:08+00:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)
>>>>>> ------Exception-------
>>>>>> Class: Kitchen::ActionFailed
>>>>>> Message: 1 actions failed.
>>>>>>     Converge failed on instance <default-ylinux6>.  Please see .kitchen/logs/default-ylinux6.log for more details
>>>>>> ----------------------
>>>>>> Please see .kitchen/logs/kitchen.log for more details
>>>>>> Also try running `kitchen diagnose --all` for configuration

Do you think it could be due to the fact that the vault keys are loaded from a library? In my case, there is this password_helper library in a dependent cookbook that has the get_vault_secret function you can see in the output above...

tquid commented 5 years ago

Are you using chef_vault_item() in your own recipe? The failover doesn't work if you don't use that helper method, iirc.

jaypipes commented 5 years ago

This is what is in the get_vault_secret function in the password_helper.rb library:

    ::ChefVault::Item.load(vault_databag, vault_item)

is that the same as what you refer to as chef_vault_item()?

tquid commented 5 years ago

I don't think that is the same. Is password_helper.rb your own thing or part of the chef_vault library? I don't know the internals very well. If it's your own thing try chef_vault_item(vault_databag, vault_item) instead.