Google Cloud Platform Compliance as Code with InSpec

Google Cloud Platform Compliance as Code with InSpec

Validating that resources are aligned with defined organizational standards is critical to operating environments at scale. In this post we'll walk through how we can leverage InSpec (https://www.inspec.io/) to perform validation of Google Cloud resources against a defined control.

Configure GCP Authentication

Before we start diving into InSpec we need to configure our machine to be able to authenticate with GCP. The recommended method is to create a read-only service account specifically for InSpec. The link below provides instructions on how to create a service account.

https://cloud.google.com/docs/authentication/getting-started

Once the service account has been created we can use the JSON file that was created as part of the service account creation process. We just need to store that somewhere on the machine we'll be running InSpec from and then run the command below to utilize those credentials.

export GOOGLE_APPLICATION_CREDENTIALS=/path/to/credentials.json  

InSpec

The first thing we need to do is to generate our InSpec profile using the init command below.

inspec init profile gcp-compliance  

The command should create a directory structure similar to that below except instead of instance and project controls there will be an example control that we'll want to replace with the two shown below.

gcp-compliance/  
├── controls
│   ├── instance.rb
│   └── project.rb
├── inspec.yml
├── libraries
└── README.md

Now that our directory structure has been created we need to update our inpsec.yml which is the metadata file for our InSpec profile. The "depends" section of the yaml file is required as there is currently no native support within InSpec for GCP and it requires utilizing the inspec-gcp library/profile.

name: gcp-compliance  
title: GCP compliance profile  
maintainer: Martez Reed  
copyright_email: [email protected]  
license: Apache-2.0  
summary: Google Cloud Platform compliance  
version: 0.1.0  
depends:  
  - name: gcp
    url: https://github.com/martezr/inspec-gcp/archive/master.tar.gz

That takes care of all the initialization stuff and we can now jump into the code. Let's create our "project.rb" control file to perform compliance on a GCP project.

describe gcp_project('silicon-vertex-398188') do  
  it { should exist }
  its('name') { should eq 'My First Project' }
  its('project_number') { should eq '3934801284823' }
  its('lifecycle_state') { should eq 'ACTIVE' }
end  

With our project control code in place we just need to run the inspec exec command against our gcp-compliance directory.

inspec exec gcp-compliance/

Profile: InSpec Profile (gcp-test)  
Version: 0.1.0  
Target:  local://

  Project silicon-vertex-398188
     ✔  should exist
     ✔  name should eq "My First Project"
     ✔  project_number should eq "1019534334086"
     ✔  lifecycle_state should eq "ACTIVE"

We see that our InSpec tests was able to successfully validate all of the controls we specified for our project. Now that our project controls are working let's add the controls for an instance.

describe gcp_instance(project: 'silicon-vertex-398188', zone: 'us-east1-b', name: 'inspec-test') do  
  it { should exist }
  its('name') { should eq 'inspec-test' }
  its('machine_type') { should eq 'f1-micro' }
  its('cpu_platform') { should eq 'Intel Haswell' }
  its('status') { should eq 'running' }
  it { should have_network_tag('test') }
end  

Let's run the inspec exec command again against our gcp-compliance directory.

inspec exec gcp-compliance/

Profile: InSpec Profile (gcp-test)  
Version: 0.1.0  
Target:  local://


  Project silicon-vertex-398188
     ✔  should exist
     ✔  name should eq "My First Project"
     ✔  project_number should eq "1019534334086"
     ✔  lifecycle_state should eq "ACTIVE"
  Instance inspec-test
     ✔  should exist
     ✔  should have network tag "test"
     ✔  name should eq "inspec-test"
     ✔  machine_type should eq "f1-micro"
     ✔  cpu_platform should eq "Intel Haswell"
     ✔  status should eq "running"

We've just walked through using InSpec to validate the configuration of our GCP project and an instance. The GCP InSpec project has a lot more work to be done to include testing and validation of all the available GCP resource types and attributes.

References

Inspec-GCP Github Page
https://github.com/martezr/inspec-gcp

Google API ruby client
https://github.com/google/google-api-ruby-client

Google Authentication ruby library
https://github.com/google/google-auth-library-ruby

InSpec
https://www.inspec.io/

Subscribe to