Tech ONTAP Blogs

StorageGRID Automation: A Resolution You Can Keep

dblackwe
NetApp
69 Views

If you’re looking for a New Year’s resolution that you can keep, we have you covered! If you didn’t know, NetApp has been a certified provider of Ansible modules since Red Hat first offered certification. While many are familiar with the ONTAP modules in Ansible, there are also powerful modules available for StorageGRID!

The NetApp team recently released a new Ansible collection,version 21.16.0, for StorageGRID. Whether you’re new to automation or need to automate your StorageGRID environment, now is a perfect time to start using these modules or expand your use of automation. For those new to these modules, here's an example along with explanations of the options you can use to further your automation journey.

Onboarding a New Tenant

A typical workflow involves onboarding a new tenant. This could be a department in your company, a customer if you are a service provider, or simply a way to demarcate access. Adding a tenant involves:

  1. Providing a name for the tenant.
  2. Setting a password for its root account.
  3. Creating a bucket to store objects.
  4. Creating a group to hold users.
  5. Adding a user to the group.
  6. Generating an access key pair for the user and displaying it for their records.

We can accomplish all these tasks with a single Ansible playbook. A playbook is a collection of tasks for Ansible to run, written in the YAML format. Here’s what such a playbook might look like:

---
- name: Onboarding
  hosts: localhost
  gather_facts: false
  vars:
    grid_user: root
    grid_password: mypassword
    grid_address: https://1.2.3.4
    t_default_pass: tenant_default

  tasks:
  - name: generate auth token for grid module on StorageGRID
    netapp.storagegrid.na_sg_grid_login:
      hostname: "{{ grid_address }}"
      username: "{{ grid_user }}"
      password: "{{ grid_password }}"
      validate_certs: false
    register: auth
  - name: create a tenant account
    netapp.storagegrid.na_sg_grid_tenant:
      state: present
      api_url: "{{ grid_address }}"
      auth_token: "{{ auth.na_sa_token }}"
      name: "tenant-1"
      protocol: "s3"
      management: true
      allow_platform_services: false
      use_own_identity_source: false
      tenant_password: "{{ t_default_pass }}"
      validate_certs: false
    register: tenant
  - name: generate auth token for grid modules on new tenant
    netapp.storagegrid.na_sg_grid_login:
      hostname: "{{ grid_address }}"
      username: "{{ grid_user }}"
      password: "{{ t_default_pass }}"
      tenant_id: "{{tenant.resp.id }}"
      validate_certs: false
    register: auth1
  - name: create a s3 bucket
    netapp.storagegrid.na_sg_org_container:
      state: present
      api_url: "{{ grid_address }}"
      auth_token: "{{ auth1.na_sa_token }}"
      name: bucket1
      validate_certs: false
  - name: create a group
    netapp.storagegrid.na_sg_org_group:
      state: present
      api_url: "{{ grid_address }}"
      auth_token: "{{ auth1.na_sa_token }}"
      display_name: users
      unique_name: group/users
      management_policy:
        manage_all_containers: false
        manage_endpoints: false
        manage_own_s3_credentials: false
        root_access: false
        s3_console: false
        view_all_containers: false
      s3_policy: {"Statement":[{"Effect":"Allow", "Action":"s3:*", "Resource":"arn:aws:s3:::*"}]}
      validate_certs: false
  - name: create a tenant user
    netapp.storagegrid.na_sg_org_user:
      state: present
      api_url: "{{ grid_address }}"
      auth_token: "{{ auth1.na_sa_token }}"
      full_name: user1
      unique_name: user/user1
      member_of: "group/users"
      disable: false
      validate_certs: false
  - name: create a s3 key
    netapp.storagegrid.na_sg_org_user_s3_key:
      state: present
      api_url: "{{ grid_address }}"
      auth_token: "{{ auth1.na_sa_token }}"
      unique_user_name: user/user1
      validate_certs: false
    register: key
  - name: report s3 key
    debug:
      msg: "{{ key.resp.accessKey }} : {{ key.resp.secretAccessKey }}"

 

Breaking It Down

An Ansible playbook starts by giving the “play” a name. A play is a collection of tasks aimed at a single system or group of systems. You can have multiple plays per playbook. This playbook only has one play:

---
- name: Onboard Tenant
  hosts: localhost
  gather_facts: false

---: Indicates the start of the YAML file.

  • - name: Onboard Tenant: Names our play. This name can be anything.
  • hosts: localhost: Specifies that the tasks will run on the localhost.
  • gather_facts: false: Saves time by not collecting information about the localhost, as it’s not relevant to our StorageGRID work.

Variables Section

  vars:
    grid_user: root
    grid_password: mypassword
    grid_address: https://1.2.3.4
    t_default_pass: tenant_default

This section defines variables that will be used throughout the playbook. The keys can be anything meaningful to you and future maintainers.

Using Variables with {{ }}

In Ansible, variables are used to store values that can be reused throughout your playbook. They help make your playbook more flexible and easier to maintain. Variables are referenced using the {{ }} syntax, which tells Ansible to replace the placeholder with the actual value of the variable.

Here’s an example task that uses variables:

  - name: Generate auth token for grid module on StorageGRID
    netapp.storagegrid.na_sg_grid_login:
      hostname: "{{ grid_address }}"
      username: "{{ grid_user }}"
      password: "{{ grid_password }}"
      validate_certs: false
    register: auth

  • hostname: "{{ grid_address }}": The {{ grid_address }} syntax tells Ansible to replace this with the value of the grid_address variable defined in the vars section.
  • username: "{{ grid_user }}": Similarly, this will be replaced with the value of grid_user.
  • Register: auth: This saves the output of the task so that information can be used later.

Important Points about Using Variables:

  1. Consistency: Ensure that the variable names used within {{ }} match exactly with those defined in the vars section.
  2. No Extra Spaces: Be careful with spaces. “{{ grid_address }}” is correct, but “ {{ grid_address }} has an extra space before the variable which may cause issues.
  3. Quotes and Braces: Variables are typically used within double quotes to ensure proper parsing, especially when dealing with strings.

Example of a Task Using Registered Variables

  - name: Create a tenant account
    netapp.storagegrid.na_sg_grid_tenant:
      state: present
      api_url: "{{ grid_address }}"
      auth_token: "{{ auth.na_sa_token }}"
      name: "tenant-1"
      protocol: "s3"
      management: true
      allow_platform_services: false
      use_own_identity_source: false
      tenant_password: "{{ t_default_pass }}"
      validate_certs: false
    register: tenant

  • api_url: "{{ grid_address }}": Uses the grid_address variable.
  • auth_token: "{{ auth.na_sa_token }}": Uses the auth.na_sa_token variable, which was registered from the output of a previous task.

By using variables, you can easily change values in one place (the vars section) without needing to update every occurrence throughout your playbook. This makes your playbook more maintainable and adaptable to different environments or configurations.

As you can see by linking different modules together you can create a full workflow that can quickly achieve desired results.  Ansible can be installed on any Linux system or used with the Red Hat Ansible Automation Platform. The StorageGRID modules are certified and therefore part of both the free Ansible Galaxy module set and the Ansible Automation Platform set.

Check Ansible Galaxy - netapp.storagegrid for full documentation on all the modules available for StorageGRID and leave a comment on how you’re keeping up with your New Year’s resolution of automating StorageGRID with Ansible.

Public