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-132 Support managed applications #575

Merged
merged 8 commits into from
Mar 12, 2022
Merged
Show file tree
Hide file tree
Changes from 6 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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,8 @@ The following is a list of static resources.
- [azure_load_balancers](docs/resources/azure_load_balancers.md)
- [azure_lock](docs/resources/azure_lock.md)
- [azure_locks](docs/resources/azure_locks.md)
- [azure_managed_application](docs/resources/azure_managed_application.md)
- [azure_managed_applications](docs/resources/azure_managed_applications.md)
- [azure_management_group](docs/resources/azure_management_group.md)
- [azure_management_groups](docs/resources/azure_management_groups.md)
- [azure_mariadb_server](docs/resources/azure_mariadb_server.md)
Expand Down
101 changes: 101 additions & 0 deletions docs/resources/azure_managed_application.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
---
title: About the azure_managed_application Resource
platform: azure
---

# azure_managed_application

Use the `azure_managed_application` InSpec audit resource to test properties related to an Azure Managed Application.

## Azure REST API version, endpoint and http client parameters

This resource interacts with api versions supported by the resource provider.
The `api_version` can be defined as a resource parameter.
If not provided, the latest version will be used.
For more information, refer to [`azure_generic_resource`](azure_generic_resource.md).

Unless defined, `azure_cloud` global endpoint, and default values for the http client will be used.
For more information, refer to the resource pack [README](../../README.md).

## Availability

### Installation

This resource is available in the [InSpec Azure resource pack](https://github.com/inspec/inspec-azure).
For an example `inspec.yml` file and how to set up your Azure credentials, refer to resource pack [README](../../README.md#Service-Principal).

## Syntax

`name`, `resource_group` is a required parameter.

```ruby
describe azure_managed_application(resource_group: 'RESOURCE_GROUP', name: 'MANAGED_APPLICATION_NAME') do
it { should exist }
its('type') { should eq 'Microsoft.ServiceBus/Namespaces' }
its('location') { should eq 'East US' }
end
```

```ruby
describe azure_managed_application(resource_group: 'RESOURCE_GROUP', name: 'MANAGED_APPLICATION_NAME') do
it { should exist }
end
```
## Parameters

| Name | Description |
|----------------|----------------------------------------------------------------------------------|
| name | Name of the Azure Managed Applications to test. |
| resource_group | Azure resource group that the targeted resource resides in. `MyResourceGroup` |

The parameter set should be provided for a valid query:
- `resource_group` and `name`

## Properties

| Property | Description |
|--------------------------|------------------------------------------------------------------|
| id | Resource Id. |
| name | Resource name. |
| type | Resource type. `Microsoft.Solutions/applications` |
| location | Resource location. |
| properties | The properties of the Managed Application. |
| properties.plan | The plan information. |
| properties.identity | The identity of the resource. |
| properties.provisioningState | Provisioning state of the namespace. |


For properties applicable to all resources, such as `type`, `name`, `id`, `properties`, refer to [`azure_generic_resource`](azure_generic_resource.md#properties).

Also, refer to [Azure documentation](https://docs.microsoft.com/en-us/rest/api/managedapplications/applications/get) for other properties available.

## Examples

### Test that the Managed Applications is provisioned successfully.

```ruby
describe azure_managed_application(resource_group: 'RESOURCE_GROUP', name: 'MANAGED_APPLICATION_NAME') do
its('properties.provisioningState') { should eq 'Succeeded' }
end
```

## Matchers

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

### exists

```ruby
# If a Managed Application is found it will exist
describe azure_managed_application(resource_group: 'RESOURCE_GROUP', name: 'MANAGED_APPLICATION_NAME') do
it { should exist }
end
# if Managed Application is not found it will not exist
describe azure_managed_application(resource_group: 'RESOURCE_GROUP', name: 'MANAGED_APPLICATION_NAME') do
it { should_not exist }
end
```

## Azure Permissions

Your [Service Principal](https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-create-service-principal-portal) must be setup with a `reader` role on the subscription you wish to test.
98 changes: 98 additions & 0 deletions docs/resources/azure_managed_applications.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
---
title: About the azure_managed_applications Resource
platform: azure
---

# azure_managed_applications

Use the `azure_managed_applications` InSpec audit resource to test properties related to all Azure Managed Applications.

## Azure REST API version, endpoint and http client parameters

This resource interacts with api versions supported by the resource provider.
The `api_version` can be defined as a resource parameter.
If not provided, the latest version will be used.
For more information, refer to [`azure_generic_resource`](azure_generic_resource.md).

Unless defined, `azure_cloud` global endpoint, and default values for the http client will be used.
For more information, refer to the resource pack [README](../../README.md).

## Availability

### Installation

This resource is available in the [InSpec Azure resource pack](https://github.com/inspec/inspec-azure).
For an example `inspec.yml` file and how to set up your Azure credentials, refer to resource pack [README](../../README.md#Service-Principal).

## Syntax

An `azure_managed_applications` resource block returns all Azure Managed Applications.

```ruby
describe azure_managed_applications do
#...
end
```

## Parameters
| Name | Description |
|----------------|----------------------------------------------------------------------------------|
| resource_group | Azure resource group that the targeted resource resides in. `MyResourceGroup` (Optional) |

The parameter set optionally be provided for a valid query:
- `resource_group`

## Properties

|Property | Description | Filter Criteria<superscript>*</superscript> |
|--------------------------------|------------------------------------------------------------------------|------------------|
| ids | A list of resource IDs. | `id` |
| names | A list of resource Names. | `name` |
| types | A list of the resource types. | `type` |
| properties | A list of Properties for all the Managed Applications. | `properties` |
| locations | A list of the resource locations. | `location` |
| identities | A list of the identity of the resources. | `identity` |
| plans | A list of the plan informations. | `plan` |
| provisioningStates | A list of provisioning states of the app. | `provisioningState`|
| publisherTenantIds | A list of the publisher tenant Id. | `publisherTenantId`|

<superscript>*</superscript> For information on how to use filter criteria on plural resources refer to [FilterTable usage](https://github.com/inspec/inspec/blob/master/dev-docs/filtertable-usage.md).

## Examples

### Loop through Managed Applications by their names.

```ruby
azure_managed_applications(resource_group: 'RESOURCE_GROUP').names.each do |name|
describe azure_managed_application(resource_group: 'RESOURCE_GROUP', name: name) do
it { should exist }
end
end
```
### Test that there are Managed Applications that are successfully provisioned.

```ruby
describe azure_managed_applications(resource_group: 'RESOURCE_GROUP').where(provisioningState: 'Succeeded') do
it { should exist }
end
```

## Matchers

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

### exists

```ruby
# Should not exist if no Managed Applications are present
describe azure_managed_applications(resource_group: 'RESOURCE_GROUP') do
it { should_not exist }
end
# Should exist if the filter returns at least one Managed Applications
describe azure_managed_applications(resource_group: 'RESOURCE_GROUP') do
it { should exist }
end
```
## Azure Permissions

Your [Service Principal](https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-create-service-principal-portal) must be setup with a `reader` role on the subscription you wish to test.
22 changes: 22 additions & 0 deletions libraries/azure_managed_application.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
require 'azure_generic_resource'

class AzureManagedApplication < AzureGenericResource
name 'azure_managed_application'
desc 'Retrieves and verifies the settings of an Azure Managed Application.'
example <<-EXAMPLE
describe azure_managed_application(resource_group: 'inspec-rg', name: 'app_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.Solutions/applications', opts)
super(opts, true)
end

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

class AzureManagedApplications < AzureGenericResources
name 'azure_managed_applications'
desc 'Verifies settings for a collection of Azure Managed Applications.'
example <<-EXAMPLE
describe azure_managed_applications 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.Solutions/applications', opts)
super(opts, true)
return if failed_resource?

populate_filter_table_from_response
end

def to_s
super(AzureManagedApplications)
end

private

def populate_table
@resources.each do |resource|
@table << resource.merge(resource[:properties])
end
end
end
30 changes: 30 additions & 0 deletions terraform/azure.tf
Original file line number Diff line number Diff line change
Expand Up @@ -1556,4 +1556,34 @@ resource "azurerm_sql_managed_instance" "sql_instance_for_inspec" {
azurerm_subnet_network_security_group_association.subnet_nsg,
azurerm_subnet_route_table_association.route_table_assoc_inspec,
]
}

resource "azurerm_managed_application_definition" "mng_app_def" {
name = "inspecmngappdef"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
lock_level = "ReadOnly"
package_file_uri = "https://github.com/Azure/azure-managedapp-samples/raw/master/Managed Application Sample Packages/201-managed-storage-account/managedstorage.zip"
display_name = "InspecManagedAppDefinition"
description = "Test Managed App Definition for Inspec"

authorization {
service_principal_id = data.azurerm_client_config.current.object_id
role_definition_id = split("/", data.azurerm_role_definition.contributor.id)[length(split("/", data.azurerm_role_definition.contributor.id)) - 1]
}
}

resource "azurerm_managed_application" "mng_app" {
name = "inspectestmngapp"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
kind = "ServiceCatalog"
managed_resource_group_name = "InspecGroup"
application_definition_id = azurerm_managed_application_definition.mng_app_def.id

parameters = {
location = azurerm_resource_group.rg.location
storageAccountNamePrefix = "storeNamePrefix"
storageAccountType = "Standard_LRS"
}
}
5 changes: 5 additions & 0 deletions terraform/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -527,4 +527,9 @@ output "inspec_adls_dns_suffix" {
output "inspec_sql_managed_instance_name" {
description = "The SQL managed instance name"
value = azurerm_sql_managed_instance.sql_instance_for_inspec.name
}

output "inspec_managed_app" {
description = "The Managed Application Name"
value = azurerm_managed_application.mng_app.name
}
11 changes: 11 additions & 0 deletions test/integration/verify/controls/azure_managed_application.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
resource_group = input(:resource_group, value: '')
inspec_managed_app = input(:inspec_managed_app, value: '')

control 'test the properties of an Azure Managed APP' do
describe azure_managed_application(resource_group: resource_group, name: inspec_managed_app) do
it { should exist }
its('kind') { should eq 'ServiceCatalog' }
its('location') { should eq location }
its('properties.provisioningState') { should eq 'Created' }
end
end
14 changes: 14 additions & 0 deletions test/integration/verify/controls/azure_managed_applications.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
resource_group = input(:resource_group, value: '')
inspec_managed_app = input(:inspec_managed_app, value: '')
location = input(:location, value: '')

control 'test the properties of all Azure Service Bus Namespaces' do
describe azure_managed_applications(resource_group: resource_group) do
it { should exist }
its('names') { should include inspec_managed_app }
its('managementModes') { should include 'Managed' }
its('locations') { should include location }
its('types') { should include 'Microsoft.Solutions/applications' }
its('provisioningStates') { should include 'Created' }
end
end
17 changes: 17 additions & 0 deletions test/unit/resources/azure_managed_application_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
require_relative 'helper'
require 'azure_managed_application'

class AzureManagedApplicationConstructorTest < Minitest::Test
def test_empty_param_not_ok
assert_raises(ArgumentError) { AzureManagedApplication.new }
end

# resource_provider should not be allowed.
def test_resource_provider_not_ok
assert_raises(ArgumentError) { AzureManagedApplication.new(resource_provider: 'some_type') }
end

def test_resource_group_name_alone_not_ok
assert_raises(ArgumentError) { AzureManagedApplication.new(resource_group: 'test') }
end
end
21 changes: 21 additions & 0 deletions test/unit/resources/azure_managed_applications_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
require_relative 'helper'
require 'azure_managed_applications'

class AzureManagedApplicationsConstructorTest < Minitest::Test
# resource_type should not be allowed.
def test_resource_type_not_ok
assert_raises(ArgumentError) { AzureManagedApplications.new(resource_provider: 'some_type') }
end

def tag_value_not_ok
assert_raises(ArgumentError) { AzureManagedApplications.new(tag_value: 'some_tag_value') }
end

def tag_name_not_ok
assert_raises(ArgumentError) { AzureManagedApplications.new(tag_name: 'some_tag_name') }
end

def test_name_not_ok
assert_raises(ArgumentError) { AzureManagedApplications.new(name: 'some_name') }
end
end