Skip to content

Commit

Permalink
new resource: azurerm_sentinel_data_connector_azure_security_center
Browse files Browse the repository at this point in the history
  • Loading branch information
magodo committed Feb 20, 2021
1 parent aa82f73 commit 402c061
Show file tree
Hide file tree
Showing 5 changed files with 382 additions and 3 deletions.
7 changes: 4 additions & 3 deletions azurerm/internal/services/sentinel/registration.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ func (r Registration) SupportedDataSources() map[string]*schema.Resource {
// SupportedResources returns the supported Resources supported by this Service
func (r Registration) SupportedResources() map[string]*schema.Resource {
return map[string]*schema.Resource{
"azurerm_sentinel_alert_rule_fusion": resourceSentinelAlertRuleFusion(),
"azurerm_sentinel_alert_rule_ms_security_incident": resourceSentinelAlertRuleMsSecurityIncident(),
"azurerm_sentinel_alert_rule_scheduled": resourceSentinelAlertRuleScheduled(),
"azurerm_sentinel_alert_rule_fusion": resourceSentinelAlertRuleFusion(),
"azurerm_sentinel_alert_rule_ms_security_incident": resourceSentinelAlertRuleMsSecurityIncident(),
"azurerm_sentinel_alert_rule_scheduled": resourceSentinelAlertRuleScheduled(),
"azurerm_sentinel_data_connector_azure_security_center": resourceSentinelDataConnectorAzureSecurityCenter(),
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
package sentinel

import (
"fmt"
"log"
"time"

"github.com/Azure/azure-sdk-for-go/services/preview/securityinsight/mgmt/2019-01-01-preview/securityinsight"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients"
loganalyticsParse "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/loganalytics/parse"
loganalyticsValidate "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/loganalytics/validate"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/sentinel/parse"
azSchema "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tf/schema"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func resourceSentinelDataConnectorAzureSecurityCenter() *schema.Resource {
return &schema.Resource{
Create: resourceSentinelDataConnectorAzureSecurityCenterCreate,
Read: resourceSentinelDataConnectorAzureSecurityCenterRead,
Delete: resourceSentinelDataConnectorAzureSecurityCenterDelete,

Importer: azSchema.ValidateResourceIDPriorToImportThen(func(id string) error {
_, err := parse.DataConnectorID(id)
return err
}, importSentinelDataConnector(securityinsight.DataConnectorKindAzureSecurityCenter)),

Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(30 * time.Minute),
Read: schema.DefaultTimeout(5 * time.Minute),
Delete: schema.DefaultTimeout(30 * time.Minute),
},

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringIsNotEmpty,
},

"log_analytics_workspace_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: loganalyticsValidate.LogAnalyticsWorkspaceID,
},

"subscription_id": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
ValidateFunc: validation.IsUUID,
},
},
}
}

func resourceSentinelDataConnectorAzureSecurityCenterCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).Sentinel.DataConnectorsClient
ctx, cancel := timeouts.ForCreateUpdate(meta.(*clients.Client).StopContext, d)
defer cancel()

workspaceId, err := loganalyticsParse.LogAnalyticsWorkspaceID(d.Get("log_analytics_workspace_id").(string))
if err != nil {
return err
}
name := d.Get("name").(string)
id := parse.NewDataConnectorID(workspaceId.SubscriptionId, workspaceId.ResourceGroup, workspaceId.WorkspaceName, name)

if d.IsNewResource() {
resp, err := client.Get(ctx, id.ResourceGroup, operationalInsightsResourceProvider, id.WorkspaceName, name)
if err != nil {
if !utils.ResponseWasNotFound(resp.Response) {
return fmt.Errorf("checking for existing Sentinel Data Connector Azure Security Center %q: %+v", id, err)
}
}

id := dataConnectorID(resp.Value)
if id != nil && *id != "" {
return tf.ImportAsExistsError("azurerm_sentinel_data_connector_azure_security_center", *id)
}
}

subscriptionId := d.Get("subscription_id").(string)
if subscriptionId == "" {
subscriptionId = id.SubscriptionId
}

param := securityinsight.ASCDataConnector{
Name: &name,
ASCDataConnectorProperties: &securityinsight.ASCDataConnectorProperties{
SubscriptionID: &subscriptionId,
DataTypes: &securityinsight.AlertsDataTypeOfDataConnector{
Alerts: &securityinsight.AlertsDataTypeOfDataConnectorAlerts{
State: securityinsight.Enabled,
},
},
},
Kind: securityinsight.KindAzureSecurityCenter,
}

_, err = client.CreateOrUpdate(ctx, id.ResourceGroup, operationalInsightsResourceProvider, id.WorkspaceName, id.Name, param)
if err != nil {
return fmt.Errorf("creating Sentinel Data Connector Azure Security Center %q: %+v", id, err)
}

d.SetId(id.ID())

return resourceSentinelDataConnectorAzureSecurityCenterRead(d, meta)
}

func resourceSentinelDataConnectorAzureSecurityCenterRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).Sentinel.DataConnectorsClient
ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d)
defer cancel()

id, err := parse.DataConnectorID(d.Id())
if err != nil {
return err
}
workspaceId := loganalyticsParse.NewLogAnalyticsWorkspaceID(id.SubscriptionId, id.ResourceGroup, id.WorkspaceName)

resp, err := client.Get(ctx, id.ResourceGroup, operationalInsightsResourceProvider, id.WorkspaceName, id.Name)
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
log.Printf("[DEBUG] Sentinel Data Connector Azure Security Center %q was not found - removing from state!", id)
d.SetId("")
return nil
}

return fmt.Errorf("retrieving Sentinel Data Connector Azure Security Center %q: %+v", id, err)
}

if err := assertDataConnectorKind(resp.Value, securityinsight.DataConnectorKindAzureSecurityCenter); err != nil {
return fmt.Errorf("asserting Sentinel Data Connector Azure Security Center of %q: %+v", id, err)
}
dc := resp.Value.(securityinsight.ASCDataConnector)

d.Set("name", id.Name)
d.Set("log_analytics_workspace_id", workspaceId.ID())
d.Set("subscription_id", dc.SubscriptionID)

return nil
}

func resourceSentinelDataConnectorAzureSecurityCenterDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).Sentinel.DataConnectorsClient
ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d)
defer cancel()

id, err := parse.DataConnectorID(d.Id())
if err != nil {
return err
}

_, err = client.Delete(ctx, id.ResourceGroup, operationalInsightsResourceProvider, id.WorkspaceName, id.Name)
if err != nil {
return fmt.Errorf("deleting Sentinel Data Connector Azure Security Center %q: %+v", id, err)
}

return nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
package sentinel_test

import (
"context"
"fmt"
"testing"

"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/sentinel/parse"

"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/terraform"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/acceptance"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/acceptance/check"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

type SentinelDataConnectorAzureSecurityCenterResource struct{}

func TestAccAzureRMSentinelDataConnectorAzureSecurityCenter_basic(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_sentinel_data_connector_azure_security_center", "test")
r := SentinelDataConnectorAzureSecurityCenterResource{}

data.ResourceTest(t, r, []resource.TestStep{
{
Config: r.basic(data),
Check: resource.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep(),
})
}

func TestAccAzureRMSentinelDataConnectorAzureSecurityCenter_complete(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_sentinel_data_connector_azure_security_center", "test")
r := SentinelDataConnectorAzureSecurityCenterResource{}

data.ResourceTest(t, r, []resource.TestStep{
{
Config: r.complete(data),
Check: resource.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep(),
})
}

func TestAccAzureRMSentinelDataConnectorAzureSecurityCenter_requiresImport(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_sentinel_data_connector_azure_security_center", "test")
r := SentinelDataConnectorAzureSecurityCenterResource{}

data.ResourceTest(t, r, []resource.TestStep{
{
Config: r.basic(data),
Check: resource.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.RequiresImportErrorStep(r.requiresImport),
})
}

func (r SentinelDataConnectorAzureSecurityCenterResource) Exists(ctx context.Context, clients *clients.Client, state *terraform.InstanceState) (*bool, error) {
client := clients.Sentinel.DataConnectorsClient

id, err := parse.DataConnectorID(state.ID)
if err != nil {
return nil, err
}

if resp, err := client.Get(ctx, id.ResourceGroup, "Microsoft.OperationalInsights", id.WorkspaceName, id.Name); err != nil {
if utils.ResponseWasNotFound(resp.Response) {
return utils.Bool(false), nil
}
return nil, fmt.Errorf("retrieving Sentinel Data Connector Azure Security Center %q: %+v", id, err)
}

return utils.Bool(true), nil
}

func (r SentinelDataConnectorAzureSecurityCenterResource) basic(data acceptance.TestData) string {
template := r.template(data)
return fmt.Sprintf(`
%s
resource "azurerm_sentinel_data_connector_azure_security_center" "test" {
name = "accTestDC-%d"
log_analytics_workspace_id = azurerm_log_analytics_workspace.test.id
}
`, template, data.RandomInteger)
}

func (r SentinelDataConnectorAzureSecurityCenterResource) complete(data acceptance.TestData) string {
template := r.template(data)
return fmt.Sprintf(`
%s
data "azurerm_client_config" "test" {}
resource "azurerm_sentinel_data_connector_azure_security_center" "test" {
name = "accTestDC-%d"
log_analytics_workspace_id = azurerm_log_analytics_workspace.test.id
subscription_id = data.azurerm_client_config.test.subscription_id
}
`, template, data.RandomInteger)
}

func (r SentinelDataConnectorAzureSecurityCenterResource) requiresImport(data acceptance.TestData) string {
template := r.basic(data)
return fmt.Sprintf(`
%s
resource "azurerm_sentinel_data_connector_azure_security_center" "import" {
name = azurerm_sentinel_data_connector_azure_security_center.test.name
log_analytics_workspace_id = azurerm_sentinel_data_connector_azure_security_center.test.log_analytics_workspace_id
}
`, template)
}

func (r SentinelDataConnectorAzureSecurityCenterResource) template(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "test" {
name = "acctestRG-sentinel-%d"
location = "%s"
}
resource "azurerm_log_analytics_workspace" "test" {
name = "acctestLAW-%d"
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name
sku = "PerGB2018"
}
`, data.RandomInteger, data.Locations.Primary, data.RandomInteger)
}
4 changes: 4 additions & 0 deletions website/azurerm.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2839,6 +2839,10 @@
<li>
<a href="/docs/providers/azurerm/r/sentinel_alert_rule_scheduled.html">azurerm_sentinel_alert_rule_scheduled</a>
</li>

<li>
<a href="/docs/providers/azurerm/r/sentinel_data_connector_azure_security_center.html">azurerm_data_connector_azure_security_center</a>
</li>
</ul>
</li>

Expand Down
Loading

0 comments on commit 402c061

Please sign in to comment.