Adoptable Cookbooks List

Looking for a cookbook to adopt? You can now see a list of cookbooks available for adoption!
List of Adoptable Cookbooks

Supermarket Belongs to the Community

Supermarket belongs to the community. While Chef has the responsibility to keep it running and be stewards of its functionality, what it does and how it works is driven by the community. The chef/supermarket repository will continue to be where development of the Supermarket application takes place. Come be part of shaping the direction of Supermarket by opening issues and pull requests or by joining us on the Chef Mailing List.

Select Badges

Select Supported Platforms


ama-linux-user-management (1) Versions 0.1.0

Installs/Configures ama-linux-user-management

cookbook 'ama-linux-user-management', '~> 0.1.0'
cookbook 'ama-linux-user-management', '~> 0.1.0', :supermarket
knife supermarket install ama-linux-user-management
knife supermarket download ama-linux-user-management
Quality 50%

Cookbook ama-linux-user-management

Chef cookbook CircleCI branch Coveralls branch Scrutinizer Code Climate

This Chef cookbook is aimed to simplify the process of mapping real people (or bots) and their machine credentials to corresponding linux user accounts, groups, sudo superpowers and stuff.

Cookbook takes quite opinionated approach that may dramatically change in next releases. Until v1.0, every minor release may introduce breaking changes.

How does it work?

In a nutshell, end user of this cookbook specifies clients (represents real people/bots with their roles and ssh keys) and partitions (represents client groups and group abilities on current node) and runs Chef. Clients are filtered according to partitions, and linux user accounts / groups are created according to rules defined in partitions. It is implied that client definitions are the same for all managed nodes, and partitions should vary from node to node - so, for example, clients may contain engineer and developer, but developer would be allowed to visit staging servers only.

Let me see an example

Let's define a client

# That's client ID, it will be used for Linux user account
# if necessary
  # Roles are represented as a tree, with leaves being just null
  # Roles are matched by filters in partitions
      engineer: ~
      infrastructure: ~
      application: ~
      root: ~
      sysctl: ~
      content: AAAAB3NzaC1yc...
      validate: true
      content: ---BEGIN PRIVATE KEY...
      passphrase: admin
        corporate.infrastructure: ~ git
          Port: 22522
          User: john
      validate: true

Client is terribly simple. It's just an ID, a set of roles and optional bunch of public and private keys - first are used to login onto node, others are used to login from node. Roles are used just as user labels, as you will see in a moment - nested structure is implemented only not to add something role if something.thatthing is defined.

Let's add some partitions:

    # don't create linux group for that
    # that will also mean that privileges will be
    # given to users rather than to a group
    group: none
    - cron.application.dashboard
      nopasswd: true
      command: php /var/www/dashboard/bin/console rebuild

    group: none
    # Don't even create accounts, just install the public keys
    account: none
    - access.root + manager.infrastructure
    root: ~

  # default policy will be used - edit for group and for users
    - bot.deploy
    - + manager.application
    - developer.php

Filters are represented as a list of conditions with OR relation: if client matches at least one condition, it matches partition. Conditions are described as a dot-delimited role path: bot.deploy matches bot: { deploy: ~ } and bot: { deploy: { gently: ~ } }, but not just bot: ~.

Given those definitions, engineer client would fall under superuser and www-data partitions (but not sudo-dashboard-cron). So he - Won't get any privilege - His account will be created because www-data mandates so - It will be in present in group www-data - It also would be able to impersonate as root, which means his public keys will be installed on root account

That's quite it: client is id, roles and keys, while partition is filters, policy, privileges and impersonation.

Using all that knowledge

So far only the structure was described, but not how to pass it into Chef. To use this cookbook, you will need to pass described data into ama_linux_user_management resource:

ama_linux_user_management 'default' do
  clients data_bag_items
  partitions node['ama']['user']['partitions']

And that's it. To make things even easier, some shortcuts were added: - If partitions are not set directly, they are fetched out of node['ama']['user']['partitions'] - If clients are not set directly, they are fetched out of data bag with name stored in node['ama']['user']['client-bag'] (clients by default). - For the laziest, this is incorporated under default resource.

What is policy?

Policy defines how specific entity may be treated. There are only three policies available:

  • none: do not bother about entity, do not create it, do not edit it
  • edit: freely create and edit entity, but don't delete it
  • manage: same as edit, but delete entity when it is gone

The difference between edit and manage is only what happens if entity gets deleted. Nost of the time, you'll want manage policy for your custom accounts and groups and edit for system users and groups - such as root and www-data.

Wait a second, are you storing all that information in attributes?

Most of that information. All keys - private and public - are not stored, only their digests are used to identify them.

Shooting foots

If you ended up in this part of internet, you're

  • a) Gonna mess with private and public keys. And that stuff is terribly sensitive - of course i've put effort not to expose your keys in state or logs, but i can't prevent you from installing wrong key, forgetting to delete employee who has left and all other ways to make things go south. Be double cautious.
  • b) Gonna install somebody's auth key on root and grant sudo privileges. The warnings are quite the same, i can give you instrument to do this, but most of the time you should evade this as you vampires evade light.
  • c) GONNA END WITH MANAGE POLICY ON ROOT BUT DON'T DO IT. Root account becomes edited the second you try to impersonate it; if, for any reason, all impersonation dependencies vanish, it's gonna be garbage collected and you'll end with a useless brick of a previously happy node. So just keep it edited all the way.
  • d) In danger of hitting not-so-properly tested corner. I sincerely apologize for all the mess but i don't have currently any more time to develop this cookbook further.

Important notes

  • For sudo definition to be working, you have to set ['authorization']['sudo']['include_sudoers_d'] attribute to true. This is required by sudo cookbook.
  • All public keys set not through ssh_authorized_keys cookbook will be deleted.
  • Cookbook uses accumulator pattern - that means that subsequent resource calls would merge rather than overwrite each other. Cookbook stores it's state in attributes, which makes it possible to remember previously managed accounts to wipe them on new run.
  • This cookbook doesn't manage known_hosts because it's certainly not this cookbook's job and it would be serious security issue to import their keys blindly and/or failing whole run because of inaccessible remote node unless user asked to do so.


Contributions are welcome! Please send your pull requests into dev branch. There is whole lot of bad code and unfinished work inside, not even mentioning proper documentation.

Also be aware that this cookbook contains a vendored gem (ama-entity-mapper), which is installed using rake vendor

Dev branch state

CircleCI branch Coveralls branch Scrutinizer


Long story short: this cookbook couldn't be tested the regular way because of scenario diversity, so small not-a-framework had to be developed. This cookbook has regular unit/integration suites (code only) with no peculiarities, but functional (ChefSpec) and acceptance (Test Kitchen) test suites use tests described in YAML. Those suites are located in test/support/cookbooks/alum-testing/files/default/fixture/run-history and simply translate themselves into appropriate matchers. ChefSpec tests simply read that directory out and apply stories one by one, while Test Kitchen is configured using rake command test:acceptance:setup - this will create the required suites and attributes.

Test reporting is done using Allure Framework - and, in fact, due to specifics it's not really possible to test other way. rake test:<type>:with-report will run appropriate tests and generate report in test/report/allure.


MIT License / Created by AMA Team

Dependent cookbooks

ama-ssh-private-keys ~> 0.2.0
ssh ~> 0.10.22
sudo ~> 3.5.0
ssh_authorized_keys ~> 0.3.0

Contingent cookbooks

There are no cookbooks that are contingent upon this one.


All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog and this project adheres to Semantic Versioning.

[0.1.0] 2017-08-09


  • Initial implementation

Collaborator Number Metric

0.1.0 failed this metric

Failure: Cookbook has 1 collaborators. A cookbook must have at least 2 collaborators to pass this metric.

Contributing File Metric

0.1.0 failed this metric

Failure: To pass this metric, your cookbook metadata must include a source url, the source url must be in the form of, and your repo must contain a file

Foodcritic Metric

0.1.0 passed this metric

No Binaries Metric

0.1.0 failed this metric

Failure: Cookbook should not contain binaries. Found:
ama-linux-user-management/test/report/allure/styles.css (size > 1048576 bytes)

Publish Metric

0.1.0 passed this metric

Supported Platforms Metric

0.1.0 passed this metric

Testing File Metric

0.1.0 failed this metric

Failure: To pass this metric, your cookbook metadata must include a source url, the source url must be in the form of, and your repo must contain a file

Version Tag Metric

0.1.0 passed this metric