Steampunk Spotter

Custom policies: Spotter takes you on a customizable automation journey

April 14, 2023 - Words by  The Spotter team - 5 min read

Card image caption

Let’s face it, what it means to have successful automation varies from one business to another. At Steampunk Spotter, we are acutely aware of this fact. We heard you loud and clear, custom policies are here, available as an enterprise feature. They allow you to create new Spotter checks according to specific policies you might be using, either for yourself or your clients. By using custom policies, you can be sure your Ansible Playbooks act according to all internal or general regulatory standards that you set for yourself.

Use policies of your choice and design

You can easily specify allowed modules and collections, define specific naming conventions, and limit required values on specific modules and entities such as exposed ports, and virtual machine sizes. You can have custom security rules, for example, to comply with Center for Internet Security (CIS), Health Insurance Portability and Accountability Act (HIPAA) standards, or General Data Protection Regulation (GDPR). The sky is the limit.

We support policies written in accordance with the Open Policy Agent (OPA) engine. They are written in Rego, a rule-based language that checks Spotter’s extracted data from Ansible tasks or playbooks that need to meet the defined conditions returning the desired result. You can have all the OPA-compliant policies in one place, including Keeping Infrastructure as Code Secure (KICS) policies, that conform to the same standard. It is so easy to use KICS policies with Spotter. You have access to numerous pre-written Ansible policies that can be easily imported, in the same way as your custom policies.

A custom Spotter scan

You can upload the policies to Spotter via CLI. The results are displayed together with native check results, and you are provided with an all-inclusive playbook scan, all in one place. You can even choose to apply the custom policies only to playbooks within an organization or a single project, which enables you to address specific requirements of a project, making you more efficient.

Before we start our scan, let’s look at the playbook we are working with:

---
- hosts: all
  connection: local
  gather_facts: false

  tasks:
    - name: create security group.
      amazon.aws.ec2_security_group:
        name: "web-app-sec"
        description: "Sec group for app web-app"
        region: "us-central-2"
        access_key: "{{ ec2_access_key }}"
        rules:
          - proto: tcp
            from_port: 22
            to_port: 22
            cidr_ip: 0.0.0.0/0
          - proto: tcp
            to_port: 80
            cidr_ip: 0.0.0.0/0
      register: result_sec_group

    - name: Provision instance
      amazon.aws.ec2_instance:
        name: "VM_for_demo"
        vpc_subnet_id: subnet-5ca1ab1e
        instance_type: t2.micro
        key_name: "prod-ssh-key"
        security_group: default
        volumes:
          - device_name: /dev/sda1
            ebs:
              volume_size: 254
              delete_on_termination: true
        image_id: ami-08c947c038321a605
        network:
          assign_public_ip: false
        tags:
          demo: VM

    - name: Gather information about the instance with a tag 
      amazon.aws.ec2_instance_info:
        filters:
          "tag:demo": VM
      register: instance_id

    - amazon.aws.ec2_snapshot:  
        instance_id: "{{ instance_id }}"
        device_name: /dev/sda1
        description: snapshot of /data from VM_for_demo

    - name: VPC info.
      steampunk.aws.ec2_vpc_info:
        auth:
          access_key: 1qwe23asd2esvngfnghm
          secret_key: "{{ my_secret_key }}"
          region: "{{ my_region }}"
      register: vpcs

Let’s scan the playbook and see what we get before we import any policies:

As we can see, we have one hint. Now, we will import our Rego policies. It is possible to import a folder or just one file. We will import an entire folder, but here is an example of a Rego policy we will be using:

package play

# Check if value of Name attribute starts with uppercase.
SpotterPolicy[result] {
	task := input.tasks[i]
	task_args := task.task_args["amazon.aws.ec2_instance"].security_group

   task_args = "default"
    result := {
		"correlation_id": task.task_id,
		"check_type": "TASK",
		"message": "Instances shouldn't be in default security groups."
	}
}

Let’s import our custom policies and scan the playbook again. Use the spotter set policies command.

 > spotter policies set Policies

Custom policies succesfully included.

> spotter scan playbook.yml

Scanning...success. ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00


Check results:

playbook.yml:2:3: HINT: [H1601] Plays should always be named using the name parameter.

playbook.yml:7:7: ERROR: [E2300::EU_Region] Region should be set to europe (eu-...).
playbook.yml:7:7: ERROR: [E2300::CapitalLetter] Task names must start with a capital letter.
playbook.yml:7:7: ERROR: [E2300] Variable name inside key access_key should start with create security group._.
playbook.yml:7:7: ERROR: [E2300::IncorrectValue] ec2_group.rules[0] SSH' (Port:22) should not be public.
playbook.yml:7:7: ERROR: [E2300::IncorrectValue] ec2_group.rules[1] shouldn't open the http port (80).
playbook.yml:23:7: ERROR: [E2300::DefaultSecurityGroup] Instances shouldn't be in default security groups.
playbook.yml:23:7: ERROR: [E2300::EndWithDot] Task names must end with a dot.
playbook.yml:23:7: ERROR: [E2300::AWS_VMSize] Volume size should be set to less then 128GB.
playbook.yml:41:7: ERROR: [E2300::EndWithDot] Task names must end with a dot.
playbook.yml:47:7: ERROR: [E2300::TaskName] Each task must have a corresponding name attribute.
playbook.yml:47:7: HINT: [H1600] Tasks should always be named using the name parameter.
playbook.yml:52:7: ERROR: [E2300::PlainText_Variable] Access key should be written as a variable.

Scan summary:

Spotter took 3.724 s to scan your input.
It resulted in 11 error(s), 0 warning(s) and 7 hint(s).

Overall status: ERROR

Visit https://spotter.steampunk.si/organization/rB6YVxEKT_ehbEgLeVSlZQ/projects/Y3NfvNDQRCqEzfUZxnrbVg/scans/Wg7jgyR6RGq1l2VW0DwIog/ to view this scan result.

> 

And there we go, all the custom policies are included in the scan, displayed as errors. They give us all the information needed to fix our playbook accordingly.

Let’s fix the errors, and then run the scan again:

 > spotter scan playbook.yml
    
    Scanning...success. ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
    
    
    Scan summary:
    
    Spotter took 0.602 s to scan your input.
    
    It resulted in 0 error(s), 0 warning(s) and 0 hint(s).
    
    Can rewrite 0 file(s) with 0 change(s).
    
    Overall status: SUCCESS
    
    Visit https://spotter.steampunk.si/organization/rB6YVxEKT_ehbEgLeVSlZQ/projects/Y3NfvNDQRCqEzfUZxnrbVg/scans/4yrRAWweS1S2hLrcguVkOA/ to view this scan result.
    
    > 
    

Voila, success!

To clear policies, you can use the spotter clear policies command.

This is the finished playbook:

---
    - hosts: all
      connection: local
      gather_facts: false
    
      tasks:
        - name: Create security group.
          amazon.aws.ec2_security_group:
            name: "web-app-sec"
            description: "Sec group for app web-app"
            region: "eu-central-2"
            access_key: "{{ ec2_access_key }}"
            rules:
              - proto: tcp
                from_port: 22
                to_port: 22
                cidr_ip: 192.120.0.0/16
              - proto: tcp
                to_port: 443
                cidr_ip: 0.0.0.0/0
          register: result_sec_group
    
        - name: Provision instance.
          amazon.aws.ec2_instance:
            name: "VM_for_demo"
            vpc_subnet_id: subnet-5ca1ab1e
            instance_type: t2.micro
            key_name: "prod-ssh-key"
            security_group: "web-app-sec"
            volumes:
              - device_name: /dev/sda1
                ebs:
                  volume_size: 64
                  delete_on_termination: true
            image_id: ami-08c947c038321a605
            network:
              assign_public_ip: false
            tags:
              demo: VM
    
        - name: Gather information about the instance with a tag. 
          amazon.aws.ec2_instance_info:
            filters:
              "tag:demo": VM
          register: instance_id
    
        - name: EC2 Snapshot. 
          amazon.aws.ec2_snapshot:  
            instance_id: "{{ instance_id }}"
            device_name: /dev/sda1
            description: snapshot of /data from VM_for_demo
    
        - name: VPC info.
          steampunk.aws.ec2_vpc_info:
            auth:
              access_key: "{{ my_access_key }}"
              secret_key: "{{ my_secret_key }}"
              region: "{{ my_region }}"
          register: vpcs

Tailor-made: Automation that fits you

If you are thinking about how to achieve corporate standards and security compliance of your Ansible Playbooks, Spotter is here to help. We integrated an OPA-compliant policy definition engine, generating OPA-based policies to be included in Spotter with minimum additional effort. You can design custom policies to achieve automation you can trust with a custom fit.

Register for free, and try out Spotter for yourself, or let us know what you think, here.

Interested in Spotter, but don’t know how to start? Explore our Getting started guide.