Category Archives: security

Salt Recipe for Creating a MySQL User with Grants for Scalyr

Salt is a great tool for managing the configuration of many servers. And when you have many servers, you should also be monitoring them with a tool like Dataset (aka Scalyr). The scalyr agent can monitor many things, but in this example, I’m going to show you how to create a MySQL user for the scalyr agent with just the right amount of permissions.

Salt Formula

{% set scalyr_user = salt['pillar.get']('scalyr:mysql:user', 'scalyr-agent-monitor') %}
mysql_scalyr_user:
  mysql_user.present:
    # - host: localhost
    - name: {{ scalyr_user }}
    - password: {{ pillar['scalyr']['mysql']['password'] }}
  mysql_grants.present:
    - grant: 'process, replication client'
    - database: '*.*'
    # - host: localhost
    - user: {{ scalyr_user }}
    - require:
      - mysql_user: {{ scalyr_user }}

Salt uses yaml with jinja templating to define states. This template does the following:

  1. Creates a MySQL user for scalyr
  2. Grants permissions for that scalyr user to access MySQL process & replication metrics on all databases

You can view the full range of options for the mysql_user and mysql_grants states if you need to customize it more.

Pillar Configuration

The above salt recipe requires a corresponding pillar configuration that looks like this:

scalyr:
  mysql:
    user: scalyr-agent-monitor
    password: RANDOM_PASSWORD

Scalyr Agent Configuration

Then in your scalyr agent JSON, you can use a template like this:

{
  logs: [{
    path: "/var/log/mysql/error.log",
    attributes: {parser: "mysql_error"}
  }, {
    path: "/var/log/mysql/slow.log",
    attributes: {parser: "mysql_slow"}
  }],
  monitors: [{
    module: "scalyr_agent.builtin_monitors.mysql_monitor",
    database_username: "{{ salt['pillar.get']('scalyr:mysql:user') }}",
    database_password: "{{ salt['pillar.get']('scalyr:mysql:password') }}",
    database_socket: "/var/run/mysqld/mysqld.sock"
  }]
}

How to use it

If you’re already familiar with salt, then hopefully this all makes sense. Let’s say you named your state mysql_user in a scalyr state directory. Then you could apply it like this:

salt SERVER_ID state.sls scalyr.mysql_user

And now you have a MySQL user just for scalyr. This same idea can likely be applied to any other MySQL monitoring program.

If you’d like some help automating your server configuration and monitoring using tools and formulas like this, contact us at Streamhacker Technologies.

Using Lastpass with Ansible Vault

Ansible is a framework that helps with automating deployments, among other things. It has a feature called Ansible Vault that enables you to encrypt secrets in your ansible files. These vault encrypted secrets can only be decrypted if you provide the correct password. This means you can store things like database passwords and other sensitive settings in your repository, in a secure manner. For password access to your secrets, you are given 3 options:

  1. Ansible asks you to enter a password every time the secrets are needed
  2. You provide a file that has the password in it
  3. You leave everything decrypted until you’re ready to commit your changes, then you encrypt them using option 1 or 2 (and later decrypt when you want to make changes).

Entering a password all the time gets annoying real quick, but having a password file laying around does not seem all that secure. Plus it’s hard to share securely if you’re collaborating with others. Option 3 requires you to not make a mistake and accidentally commit decrypted secrets. What if there was a better way?

Lastpass is a great place to store your passwords, and generate secure ones, but it is annoying to lookup, copy, then paste the password back in ansible, and you need to add —ask-vault-pass to every ansible command. However, Lastpass has a neat command line utility that you can use to get a password saved in Lastpass. With some minor scripting, you can integrate this with the ansible password file, so that you don’t have a plaintext password file laying around. I learned a lot about how to do this from How to use Ansible Vault with LastPass but decided that simple scripting worked better for me than install a ruby gem.

  1. Install lastpass-cli
  2. Create a bash script we’ll call lpass_vault.sh. This must be located wherever you run ansible from, and be executable
  3. #!/bin/bash
    PASSWORD=`lpass show --password "ansible vault"`
    echo $PASSWORD
    
  4. Create an entry in your Lastpass account with the Name "ansible vault". This is what is referenced in the script above.
  5. Add the following to environment. You could add it to the bottom of bin/activate if you’re using python virtualenv:
  6. export ANSIBLE_VAULT_PASSWORD_FILE=`command -v ./lpass_vault.sh`
    
  7. Then run lpass login to ensure lastpass is setup
  8. Now you can run ansible with vault encrypted secrets, and at worst you’ll be prompted for your lastpass master password.

This isn’t only more convenient for an individual, it can also be great for teams: you can check vault encrypted secrets into a shared repository, then share the password in Lastpass. Now nothing is exposed in the repository, and the only people that can access the secrets are those with the Lasspass password.