Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RESOURCE-505 Soumyo/azure blob service #674

Merged
merged 11 commits into from
Nov 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 130 additions & 0 deletions docs-chef-io/content/inspec/resources/azure_blob_service.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
+++
title = "azure_blob_service Resource"
platform = "azure"
draft = false
gh_repo = "inspec-azure"

[menu.inspec]
title = "azure_blob_service"
identifier = "inspec/resources/azure/azure_blob_service Resource"
parent = "inspec/resources/azure"
+++

Use the `azure_blob_service` Chef InSpec audit resource to test the properties of an Azure Storage account’s Blob service.

## Azure REST API Version, Endpoint, and HTTP Client Parameters

{{% inspec_azure_common_parameters %}}

## Installation

{{% inspec_azure_install %}}

## Syntax

An `azure_blob_service` resource block identifies an Azure Blob Service by `resource_group`, or the `storage_account_name`.

```ruby
describe azure_blob_service(resource_group: 'RESOURCE_GROUP', storage_account_name: 'STORAGE_ACCOUNT_NAME') do
it { should exist }
end
```

## Parameters

`resource_group`
: Azure resource group where the targeted resource resides.

`storage_account_name`
: Name of the Storage account to test.

## Properties

`identity`
: The identity of the managed cluster, if configured. It is a [managed cluster identity object](https://docs.microsoft.com/en-us/rest/api/aks/managedclusters/get#managedclusteridentity).

`id`
: Fully qualified resource ID for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}

`name`
: The name of the resource

`properties.automaticSnapshotPolicyEnabled`
: Deprecated in favor of isVersioningEnabled property.

`properties.changeFeed`
: The blob service properties for change feed events.

`properties.containerDeleteRetentionPolicy`
: The blob service properties for container soft delete.

`properties.cors`
: Specifies CORS rules for the Blob service. You can include up to five CorsRule elements in the request. If no CorsRule elements are included in the request body, all CORS rules will be deleted, and CORS will be disabled for the Blob service.

`properties.defaultServiceVersion`
: DefaultServiceVersion indicates the default version to use for requests to the Blob service if an incoming request’s version is not specified. Possible values include version 2008-10-27 and all more recent versions.

`properties.deleteRetentionPolicy`
: The blob service properties for blob soft delete.

`properties.isVersioningEnabled`
: Versioning is enabled if set to true.

`properties.lastAccessTimeTrackingPolicy`
: The blob service property to configure last access time based tracking policy.

`properties.restorePolicy`
: The blob service properties for blob restore policy.

`sku`
: Sku name and tier.

`type`
: The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or "Microsoft.Storage/storageAccounts"

See [Azure's documentation on Blob service](https://learn.microsoft.com/en-us/rest/api/storagerp/blob-services/get-service-properties?tabs=HTTP) for a full list of available properties. Any attribute in the response may be accessed with the key names separated by dots (`.`).

## Examples

### Test sku name in the Blob Service

```ruby
describe azure_blob_service(resource_group: 'RESOURCE_GROUP', storage_account_name: 'STORAGE_ACCOUNT_NAME') do
its('sku.name') { should eq 'Standard_RAGRS' }
end
```

### Test that type

```ruby
describe azure_blob_service(resource_group: 'RESOURCE_GROUP', storage_account_name: 'STORAGE_ACCOUNT_NAME') do
its('type') { should eq 'Microsoft.Storage/storageAccounts/blobServices' }
end
```

See [integration tests](../../test/integration/verify/controls/azure_blob_service.rb) for more examples.

## Matchers

This InSpec audit resource has the following special matchers. For a full list of available matchers, please visit [Universal Matchers page](https://docs.chef.io/inspec/matchers/).

### exists

The control passes if the filter returns at least one result. Use `should_not` if you expect zero matches.

```ruby
describe azure_blob_service(resource_group: 'RESOURCE_GROUP', storage_account_name: 'STORAGE_ACCOUNT_NAME') do
it { should exist }
end
```


```ruby
describe azure_blob_service(resource_group: 'RESOURCE_GROUP', storage_account_name: 'STORAGE_ACCOUNT_NAME') do
it { should_not exist }
end
```

## Azure Permissions

{{% azure_permissions_service_principal role="contributor" %}}
106 changes: 106 additions & 0 deletions docs-chef-io/content/inspec/resources/azure_blob_services.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
+++
title = "azure_blob_services Resource"
platform = "azure"
draft = false
gh_repo = "inspec-azure"

[menu.inspec]
title = "azure_blob_services"
identifier = "inspec/resources/azure/azure_blob_services Resource"
parent = "inspec/resources/azure"
+++

Use the `azure_blob_services` Chef InSpec audit resource to test the properties and configuration of multiple Azure storage accounts' Blob services.

## Azure REST API Version, Endpoint, and HTTP Client Parameters

{{% inspec_azure_common_parameters %}}

## Installation

{{% inspec_azure_install %}}

## Syntax

An `azure_blob_services` resource block returns all Azure Blob Service, either within a Resource Group (if provided) or within an entire Subscription.

```ruby
describe azure_blob_services(resource_group: 'RESOURCE_GROUP_NAME', storage_account_name: 'STORAGE_ACCOUNT_NAME') do
it { should exist }
end
```

## Parameters

`resource_group`
: Azure resource group where the targeted resource resides.

`storage_account_name`
: Name of the Storage account to test.

## Properties

`ids`
: Fully qualified resource ID for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}

: **Field**: `id`

`names`
: The name of the resource.

: **Field**: `name`

`properties`
: The property of the resource.

: **Field**: `properties`

`skus`
: Sku name and tier.

: **Field**: `sku`

`types`
: The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or "Microsoft.Storage/storageAccounts"

: **Field**: `type`

{{% inspec_filter_table %}}

See [Azure's documentation on Blob services](https://learn.microsoft.com/en-us/rest/api/storagerp/blob-services/list?tabs=HTTP) for a full list of available properties.

## Examples

### Test that an example Resource Group has the named storage account

```ruby
describe azure_blob_services(resource_group: 'RESOURCE_GROUP_NAME', storage_account_name: 'STORAGE_ACCOUNT_NAME') do
its('names') { should include('STORAGE_ACCOUNT_NAME') }
end
```

See [integration tests](../../test/integration/verify/controls/azure_blob_services.rb) for more examples.

## Matchers

{{% inspec_matchers_link %}}

### exist

The control passes if the filter returns at least one result. Use `should_not` if you expect zero matches.

```ruby
describe azure_blob_services(resource_group: 'RESOURCE_GROUP_NAME', storage_account_name: 'STORAGE_ACCOUNT_NAME') do
it { should exist }
end
```

```ruby
describe azure_blob_services(resource_group: 'RESOURCE_GROUP_NAME', storage_account_name: 'STORAGE_ACCOUNT_NAME') do
it { should_not exist }
end
```

## Azure Permissions

{{% azure_permissions_service_principal role="contributor" %}}
25 changes: 25 additions & 0 deletions libraries/azure_blob_service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
require 'azure_generic_resource'

class AzureBlobService < AzureGenericResource
name 'azure_blob_service'
desc 'Verifies settings for an Azure API Blob Service.'
example <<-EXAMPLE
describe azure_blob_service(resource_group: 'resource-group-name', storage_account_name: 'storage-account-name') do
it { should exist }
end
EXAMPLE

def initialize(opts = {})
raise ArgumentError, 'Parameters must be provided in an Hash object.' unless opts.is_a?(Hash)
opts[:resource_provider] = specific_resource_constraint('Microsoft.Storage/storageAccounts', opts)
opts[:required_parameters] = %i(storage_account_name)
opts[:name] = 'default'
opts[:resource_path] = [opts[:storage_account_name], 'blobServices'].join('/')
opts[:method] = 'get'
super(opts, true)
end

def to_s
super(AzureBlobService)
end
end
38 changes: 38 additions & 0 deletions libraries/azure_blob_services.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
require 'azure_generic_resources'

class AzureBlobServices< AzureGenericResources
name 'azure_blob_services'
desc 'Verifies settings for an Azure API Blob Services resource'
example <<-EXAMPLE
describe azure_blob_services(resource_group: 'resource-group-name', storage_account_name: "storage-account-name") do
it { should exist }
end
EXAMPLE

def initialize(opts = {})
raise ArgumentError, 'Parameters must be provided in an Hash object.' unless opts.is_a?(Hash)

opts[:resource_provider] = specific_resource_constraint('Microsoft.Storage/storageAccounts', opts)
opts[:required_parameters] = %i(storage_account_name)
opts[:resource_path] = [opts[:storage_account_name], 'blobServices'].join('/')

super(opts, true)

return if failed_resource?
# Define the column and field names for FilterTable.
# In most cases, the `column` should be the pluralized form of the `field`.
# @see https://github.com/inspec/inspec/blob/master/docs/dev/filtertable-usage.md
table_schema = [
{ column: :ids, field: :id },
{ column: :names, field: :name },
{ column: :types, field: :type },
{ column: :properties, field: :properties },
{ column: :skus, field: :sku },
]
AzureGenericResources.populate_filter_table(:table, table_schema)
end

def to_s
super(AzureBlobServices)
end
end
17 changes: 15 additions & 2 deletions terraform/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,6 @@ output "log_profile_name" {
value = azurerm_monitor_log_profile.log_profile.name
}


output "postgresql_server_name" {
value = azurerm_postgresql_server.postgresql.name
}
Expand Down Expand Up @@ -589,13 +588,27 @@ output "inspec_hpc_cache_name" {
output "workspace_name" {
value = azurerm_log_analytics_workspace.workspace.name
}

output "alert_rule_id" {
value = azurerm_sentinel_alert_rule_scheduled.alert_rule_scheduled.name
}

output "alert_rule_name" {
value = azurerm_sentinel_alert_rule_scheduled.alert_rule_scheduled.name
}

output "alert_rule_display_name" {
value = azurerm_sentinel_alert_rule_scheduled.alert_rule_scheduled.display_name
}
}

output "storage_account_blob_service_id" {
value = azurerm_storage_blob.functioncode.id
}

output "storage_account_blob_service_name" {
value = azurerm_storage_blob.functioncode.name
}

output "storage_account_blob_type" {
value = azurerm_storage_blob.functioncode.type
}
41 changes: 41 additions & 0 deletions test/integration/verify/controls/azure_blob_service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
resource_group = input('resource_group', value: '', description: '')
storage_account_blob_service_id = input('storage_account_blob_service_id', value: '', description: '')
storage_account_blob_service_name = input('storage_account_blob_service_name', value: '', description: '')
storage_account_blob_type = input('storage_account_blob_type', value: '', description: '')
storage_account = input('storage_account', value: '', description: '')

control 'azure_blob_service' do
impact 1.0
title 'Testing the singular resource of azure_blob_service.'
desc 'Testing the singular resource of azure_blob_service.'

describe azure_blob_service(resource_group: resource_group, storage_account_name: storage_account) do
it { should exist }
end

describe azure_blob_service(resource_group: resource_group, storage_account_name: storage_account) do
its('sku.name') { should eq 'Standard_RAGRS' }
its('sku.tier') { should eq 'Standard' }

its('id') { should eq storage_account_blob_service_id }
its('name') { should eq storage_account_blob_service_name }
its('type') { should eq storage_account_blob_type }

its('properties.changeFeed.enabled') { should eq true }

its('properties.restorePolicy.enabled') { should eq true }
its('properties.restorePolicy.days') { should eq 6 }
# its('properties.restorePolicy.minRestoreTime') { should eq Time.parse('2022-09-13T09:34:18.5206216Z') }

its('properties.containerDeleteRetentionPolicy.enabled') { should eq true }
its('properties.containerDeleteRetentionPolicy.days') { should eq 7 }

its('properties.corsRules') { should be_empty }

its('properties.deleteRetentionPolicy.allowPermanentDelete') { should eq false }
its('properties.deleteRetentionPolicy.enabled') { should eq true }
its('properties.deleteRetentionPolicy.days') { should eq 7 }

its('properties.isVersioningEnabled') { should eq true }
end
end
Loading