Skip to content

Commit

Permalink
refactor: introduce and use step_(cli|ca)_user for step calls
Browse files Browse the repository at this point in the history
  • Loading branch information
maxhoesel committed Mar 29, 2021
1 parent acd1369 commit 8ac26d3
Show file tree
Hide file tree
Showing 21 changed files with 631 additions and 521 deletions.
221 changes: 180 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,69 +1,208 @@
# maxhoesel.smallstep

![Release](https://img.shields.io/github/v/release/maxhoesel/ansible-collection-smallstep)
![Build Status](https://img.shields.io/github/workflow/status/maxhoesel/ansible-collection-smallstep/CI/devel)
![CI Status (Roles)](https://img.shields.io/github/workflow/status/maxhoesel/ansible-collection-smallstep/CI%20Roles/devel)
![CI Status (Modules)](https://img.shields.io/github/workflow/status/maxhoesel/ansible-collection-smallstep/CI%20Modules/devel)
![License](https://img.shields.io/github/license/maxhoesel/ansible-collection-smallstep)

An Ansible collection for managing Smallstep CLI and CA applications.

This collection contains role and modules to help you install, configure, and maintain both the step client and the CA server from Ansible.

## Components
---
**NOTE**

Currently, the following components are available:
This collection (and the upstream `step-cli`/`step-ca` packages) are still under active development and do not have an official stable release yet.
Breaking changes may occur between minor releases (e.g. 0.2 -> 0.3) if they are needed to keep up with upstream changes.

#### Modules
---

- ca_provisioner: Add and remove provisioners on a step-ca server
- ca_claims: Manage claims of providers on a step-ca server

#### Roles
An Ansible collection for managing Smallstep CLI and CA applications.

- ca_server: Install and initialize a step-ca server
- step_client: Install and initialize the step-cli client
This collection contains role and modules to help you install, configure, and maintain both the step-cli client and the CA server using Ansible.

## Installation

Before installing the collection, make sure that the following dependencies are met on the controller:
### Dependencies

- Ansible 2.9 or newer
- ansible-base, either the most recent release or the release before
- Python 3.6 or newer

NOTE: Individual roles/modules may have additional requirements. Please see the role/module documentation for more details.

#### From Ansible-Galaxy

Installation via the official ansible-galaxy repository is currently not possible, due to [this issue](https://github.com/ansible/galaxy/issues/2519).

#### Repo install

To install the collection directly from this repository, run:

```ansible-galaxy install https://github.com/maxhoesel/ansible-collection-smallstep```

#### Tarball install
Individual roles and modules may have additional dependencies, please check their respective documentation.

You can also install a specific version of this collection manually by downloading a tarball from the [releases](https://github.com/maxhoesel/ansible-collection-smallstep/releases).
### Install via ansible-galaxy

## Testing
Install this role via ansible-galaxy:

All components of this collection are automatically tested against a broad set of Ansible and Python versions on the controller.
`ansible-galaxy collection install maxhoesel.smallstep`

### Testing Matrix
You can also install the most recent version of this collection by referencing this repository:

#### Ansible Versions
`ansible-galaxy collection install git+https://github.com/maxhoesel/ansible-collection-smallstep`

- Current Release
- Previous Release
- Upcoming Release
## Usage

#### Python Versions
In addition to a set of modules that wrap around `step-cli` commands, allowing to perform typical `step-cli`/`ca` operations,
this collection also contains several roles that perform typical tasks related to `step-cli` and `step-ca`. They are:

- Lowest supported version by this collection (3.6)
- Current Python release
- `step_ca`: Install and initialize a step certificate authority on a host
- `step_bootstrap_host`: Initialize a host to trust an existing step CA and create a service user for communicating with the CA via `step-cli`
- `step_acme_cert`: Generate and install and ACME certificate for a host from an existing step CA. Also sets up automatic renewal.
- `step_cli`: Install the `step-cli` client on a host. This role is used by `step_ca` and `step_bootstrap_host` and
it is recommended that you use these roles unless you really only want `step-cli` for some reason


### Basic setup

In this scenario you want to create an internal CA for a group of hosts to trust and get TLS certs from.
Your inventory will probably look a little like the one below:

```
all:
children:
step_ca:
my-ca.localdomain
clients:
hosta.localdomain
hostb.localdomain
hostc.localdomain
```

First, you will need to create a step CA on the CA host.
Below is a simple example for how to do so (check the `step_ca` docs for more details):

`ca.yml`:

```yaml
- hosts: step_ca
become: yes
tasks:
# Install and initialize the CA server.
# There are a lot of configuration options, see the step_ca README for details
- name: Install step-ca
include_role:
name: maxhoesel.smallstep.step_ca
vars:
step_ca_name: Foobar Internal CA
step_ca_root_password: "incredibly secret password"
step_ca_intermediate_password: "very secret password"

# The CA root cert fingerprint is used by clients to verify the authenticity of your CA.
# You can save the output of this task and then pass it on to any client that you want to trust the CA.
- name: Get root CA fingerprint
command: `step-cli certificate fingerprint /etc/step-ca/certs/root_ca.crt`
register: root_ca_fp
- name: Show root CA fingerprint
debug:
msg: "Fingerprint of root cert: {{ root_ca_fp.stdout }}"
```
Now that your CA is up and running, it's time to configure the clients to trust the CA:
`clients.yml`:

```yaml
- hosts: clients
become: yes
tasks:
- name: Bootstrap the hosts to trust the CA
include_role:
name: maxhoesel.smallstep.step_bootstrap_host
vars:
# These values point the hosts to your newly created CA
step_bootstrap_ca_url: https://my-ca.localdomain
step_bootstrap_fingerprint: "your root CA certs fingerprint"
# `step` is the default service user created by step_bootstrap_host. This user
# is configured to access the CA and can be used to get certs, check the CA status and so on.
- name: Verify that everything is working
command: step-cli ca health
changed_when: no
become_user: step
```
At this point, your CA is up and running and your hosts are configured to trust it. You're ready to go!
You can take a look at the available modules to further configure your CA and hosts if you whish to do so.
### About step-cli config and service users
Most of the modules in this collection wrap around the `step-cli` command, which reads its configuration from
$STEPPATH (~/.step) by default. Alternatively, it is possible to pass required configuration parameters via command-line args.

This collection makes things easy for you by installing a cli and ca user with the `step_bootstrap_host` and `step_ca` roles respectively
These users are named `step` and `step-ca` and can access the CA remotely/locally without any further configuration required.

You can also pass the required parameters via module args (e.g. `ca_url` for remote access or `ca_config` if the CA is local), but
this is not recommended.

---
**NOTE**

Some modules can be run both remotely via the client and directly on the CA (e.g. `step_ca_certificate`), while others are remote/local-only
(e.g. `step_ca_bootstrap` is remote-only, while `step_ca_provisioner` is local-only). See the module documentation for details.
---

```yaml
- hosts: all
become: yes
tasks:
- name: Run a step-cli command
command: step-cli ca health
become_user: step
- name: Run a module instead
maxhoesel.smallstep.step_ca_certificate:
# module args
become_user: step
- name: run a module against a local CA
maxhoesel.smallstep.step_ca_provisioner:
# module args
become_user: step-ca
```

### Getting ACME certs from the CA

One possible use case for a internal CA is to issue short-lived host certificates via the ACME protocol.
This collection has a role specifically for that - `step_acme_cert`. Below is a simple example for setting
up an ACME workflow.

---
**NOTE**

Make sure that you are familiar with the way ACME works. You will need a functioning DNS environment at the very least
to make use of ACME certs.
---

`acme.yml`:

```yaml
- hosts: step_ca
become: yes
tasks:
- name: Add an ACME provisioner to the CA
maxhoesel.smallstep.step_ca_provisioner:
name: ACME
type: ACME
become_user: step-ca
notify: reload step-ca
handlers:
- name: reload step-ca
systemd:
name: step-ca
state: reloaded
- hosts: clients
become: yes
tasks:
# This will download a certificate to /etc/step/ that you can then use in other applications.
# See the step_acme_cert README for more options
- name: Configure an ACME cert + renewal
include_tasks:
name: maxhoesel.smallstep.step_acme_cert
vars:
step_acme_cert_ca_provisioner: ACME
become_user: step
```

## License & Author

Created & Maintained by Max Hösel (@maxhoesel)

GPL 3.0 or later
Licensed under the GPL 3.0 or later
1 change: 0 additions & 1 deletion roles/step_acme_cert/molecule/default/prepare.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
maxhoesel.smallstep.step_ca_provisioner:
name: ACME
type: ACME
ca_config: "{{ step_ca_path }}/config/ca.json"
become: yes
become_user: "{{ step_ca_user }}"

Expand Down
13 changes: 10 additions & 3 deletions roles/step_bootstrap_host/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,19 @@ This role is intended to be run on regular hosts in your network that you want t
- Can be an absolute path or a command (make sure the executable is in $PATH) for all users
- Default: `step-cli`

##### `step_service_user`
##### `step_cli_version`
- Set the version of step to install
- Can be a version tag (e.g. `0.15.3`), or `latest` to always install the most recent version
- Note that the role will query the GitHub API if this value is set to `latest`. Try setting
a specific version if you are running into rate limiting issues
- Default: `latest`

##### `step_cli_user`
- Name of the service user that will be able to communicate with the CA
- Default: `step`

##### `step_service_user_home`
- Home directory of the service user. Used to store `step-cli` configuration
##### `step_cli_user_path`
- Configuration directory for the service user. Used to store `step-cli` configuration
- Default: `/etc/step`

##### `step_bootstrap_ca_url`
Expand Down
4 changes: 2 additions & 2 deletions roles/step_bootstrap_host/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
step_cli_executable: step-cli

step_service_user: step
step_service_user_home: /etc/step
step_cli_user: step
step_cli_user_path: /etc/step

#step_bootstrap_ca_url:
#step_bootstrap_fingerprint:
Expand Down
4 changes: 2 additions & 2 deletions roles/step_bootstrap_host/molecule/default/converge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
include_role:
name: step_bootstrap_host
vars:
step_service_user: step-molecule
step_service_user_home: /etc/step-molecule
step_cli_user: step-molecule
step_cli_user_path: /etc/step-molecule
step_bootstrap_ca_url: https://step-ca.localdomain
step_bootstrap_fingerprint: 345bf77397642dc9211a3820af0b1816c4afa430ad249ae705f1456b4bafa046
30 changes: 15 additions & 15 deletions roles/step_bootstrap_host/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,26 @@

- name: service user is present
user:
name: "{{ step_service_user }}"
name: "{{ step_cli_user }}"
shell: /bin/bash
password: "*"
home: "{{ step_service_user_home }}"
home: "{{ step_cli_user_path }}"

- name: step directory is present
file:
path: "{{ step_service_user_home }}/step"
owner: "{{ step_service_user }}"
group: "{{ step_service_user }}"
path: "{{ step_cli_user_path }}/step"
owner: "{{ step_cli_user }}"
group: "{{ step_cli_user }}"
mode: "750"
state: directory

- name: steppath symlink is present
file:
src: "{{ step_service_user_home }}/step"
dest: "{{ step_service_user_home }}/.step"
src: "{{ step_cli_user_path }}"
dest: "{{ step_cli_user_path }}/.step"
state: link
owner: "{{ step_service_user }}"
group: "{{ step_service_user }}"
owner: "{{ step_cli_user }}"
group: "{{ step_cli_user }}"
mode: "750"

- name: service user is bootstrapped
Expand All @@ -31,22 +31,22 @@
fingerprint: "{{ step_bootstrap_fingerprint }}"
step_cli_executable: "{{ step_cli_executable }}"
become: yes
become_user: "{{ step_service_user }}"
become_user: "{{ step_cli_user }}"

- name: check if cert is already installed
stat:
path: "{{ step_service_user_home }}/.cert_installed"
path: "{{ step_cli_user_path }}/.cert_installed"
register: step_bootstrap_installed

- block:
- name: root cert is installed
command: "step-cli certificate install {{ step_service_user_home }}/.step/certs/root_ca.crt --all"
command: "step-cli certificate install {{ step_cli_user_path }}/.step/certs/root_ca.crt --all"

- name: Write install file
copy:
content: This file tells step_bootstrap_host that the root cert is already installed on the local system
dest: "{{ step_service_user_home }}/.cert_installed"
owner: "{{ step_service_user }}"
group: "{{ step_service_user }}"
dest: "{{ step_cli_user_path }}/.cert_installed"
owner: "{{ step_cli_user }}"
group: "{{ step_cli_user }}"
mode: "750"
when: step_bootstrap_install_cert and not step_bootstrap_installed.stat.exists
12 changes: 11 additions & 1 deletion roles/step_ca/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,20 @@ This role performs the following actions:
##### `step_ca_version`
- Set the version of step-ca to install
- Can be a version tag (e.g. `0.15.3`), or `latest` to always install the most recent version
- Note that the role will query the GitHub API if this value is set to `latest`. Try setting
a specific version if you are running into rate limiting issues
- Default: `latest`

##### `step_cli_version`
- Set the version of step to install
- Can be a version tag (e.g. `0.15.3`), or `latest` to always install the most recent version
- Note that the role will query the GitHub API if this value is set to `latest`. Try setting
a specific version if you are running into rate limiting issues
- Default: `latest`

##### `step_ca_user`
- User under which the step-ca server will run
- Default: `step`
- Default: `step-ca`

##### `step_ca_path`
- Directory under which to place step-ca configuration files
Expand Down Expand Up @@ -127,6 +136,7 @@ These variables need to be set as a group
- hosts: all
roles:
- role: maxhoesel.smallstep.step_ca
become: yes
vars:
step_ca_name: Foo Bar Private CA
step_ca_root_password: "very secret password"
Expand Down
Loading

0 comments on commit 8ac26d3

Please sign in to comment.