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

Add Log Analytics support for ACI #2763

Merged
merged 9 commits into from
Mar 7, 2019
150 changes: 147 additions & 3 deletions azurerm/resource_arm_container_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,60 @@ func resourceArmContainerGroup() *schema.Resource {
},
},

"diagnostics": {
Type: schema.TypeList,
Optional: true,
ForceNew: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"log_analytics": {
Type: schema.TypeList,
Required: true,
ForceNew: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"workspace_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validate.UUID,
},

"workspace_key": {
Type: schema.TypeString,
Required: true,
Sensitive: true,
ForceNew: true,
ValidateFunc: validate.NoEmptyStrings,
},

"log_type": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringInSlice([]string{
string(containerinstance.ContainerInsights),
string(containerinstance.ContainerInstanceLogs),
}, false),
},

"metadata": {
Type: schema.TypeMap,
Optional: true,
ForceNew: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
},
},
},
},
},
},

"ip_address": {
Type: schema.TypeString,
Computed: true,
Expand Down Expand Up @@ -318,13 +372,17 @@ func resourceArmContainerGroupCreate(d *schema.ResourceData, meta interface{}) e
tags := d.Get("tags").(map[string]interface{})
restartPolicy := d.Get("restart_policy").(string)

diagnosticsRaw := d.Get("diagnostics").([]interface{})
diagnostics := expandContainerGroupDiagnostics(diagnosticsRaw)

containers, containerGroupPorts, containerGroupVolumes := expandContainerGroupContainers(d)
containerGroup := containerinstance.ContainerGroup{
Name: &name,
Location: &location,
Tags: expandTags(tags),
ContainerGroupProperties: &containerinstance.ContainerGroupProperties{
Containers: containers,
Diagnostics: diagnostics,
RestartPolicy: containerinstance.ContainerGroupRestartPolicy(restartPolicy),
IPAddress: &containerinstance.IPAddress{
Type: containerinstance.ContainerGroupIPAddressType(IPAddressType),
Expand All @@ -340,8 +398,13 @@ func resourceArmContainerGroupCreate(d *schema.ResourceData, meta interface{}) e
containerGroup.ContainerGroupProperties.IPAddress.DNSNameLabel = &dnsNameLabel
}

if _, err := client.CreateOrUpdate(ctx, resGroup, name, containerGroup); err != nil {
return err
future, err := client.CreateOrUpdate(ctx, resGroup, name, containerGroup)
if err != nil {
return fmt.Errorf("Error creating/updating container group %q (Resource Group %q): %+v", name, resGroup, err)
}

if err = future.WaitForCompletionRef(ctx, client.Client); err != nil {
return fmt.Errorf("Error waiting for completion of container group %q (Resource Group %q): %+v", name, resGroup, err)
}

read, err := client.Get(ctx, resGroup, name)
Expand Down Expand Up @@ -394,7 +457,7 @@ func resourceArmContainerGroupRead(d *schema.ResourceData, meta interface{}) err
}

if err := d.Set("image_registry_credential", flattenContainerImageRegistryCredentials(d, props.ImageRegistryCredentials)); err != nil {
return fmt.Errorf("Error setting `capabilities`: %+v", err)
return fmt.Errorf("Error setting `image_registry_credential`: %+v", err)
}

if address := props.IPAddress; address != nil {
Expand All @@ -406,7 +469,12 @@ func resourceArmContainerGroupRead(d *schema.ResourceData, meta interface{}) err

d.Set("restart_policy", string(props.RestartPolicy))
d.Set("os_type", string(props.OsType))

if err := d.Set("diagnostics", flattenContainerGroupDiagnostics(d, props.Diagnostics)); err != nil {
return fmt.Errorf("Error setting `diagnostics`: %+v", err)
}
}

flattenAndSetTags(d, resp.Tags)

return nil
Expand Down Expand Up @@ -876,6 +944,82 @@ func flattenContainerVolumes(volumeMounts *[]containerinstance.VolumeMount, cont
return volumeConfigs
}

func expandContainerGroupDiagnostics(input []interface{}) *containerinstance.ContainerGroupDiagnostics {
if len(input) == 0 {
return nil
}

vs := input[0].(map[string]interface{})

analyticsVs := vs["log_analytics"].([]interface{})
analyticsV := analyticsVs[0].(map[string]interface{})

workspaceId := analyticsV["workspace_id"].(string)
workspaceKey := analyticsV["workspace_key"].(string)
logType := containerinstance.LogAnalyticsLogType(analyticsV["log_type"].(string))

metadataMap := analyticsV["metadata"].(map[string]interface{})
metadata := make(map[string]*string)
for k, v := range metadataMap {
strValue := v.(string)
metadata[k] = &strValue
}

return &containerinstance.ContainerGroupDiagnostics{
LogAnalytics: &containerinstance.LogAnalytics{
WorkspaceID: utils.String(workspaceId),
WorkspaceKey: utils.String(workspaceKey),
LogType: logType,
Metadata: metadata,
},
}
}

func flattenContainerGroupDiagnostics(d *schema.ResourceData, input *containerinstance.ContainerGroupDiagnostics) []interface{} {
if input == nil {
return []interface{}{}
}

logAnalytics := make([]interface{}, 0)

if la := input.LogAnalytics; la != nil {
output := make(map[string]interface{})

output["log_type"] = string(la.LogType)

metadata := make(map[string]interface{})
for k, v := range la.Metadata {
metadata[k] = *v
}
output["metadata"] = metadata

if la.WorkspaceID != nil {
output["workspace_id"] = *la.WorkspaceID
}

// the existing config may not exist at Import time, protect against it.
workspaceKey := ""
if existingDiags := d.Get("diagnostics").([]interface{}); len(existingDiags) > 0 {
existingDiag := existingDiags[0].(map[string]interface{})
if existingLA := existingDiag["log_analytics"].([]interface{}); len(existingLA) > 0 {
vs := existingLA[0].(map[string]interface{})
if key := vs["workspace_key"]; key != nil && key.(string) != "" {
workspaceKey = key.(string)
}
}
}
output["workspace_key"] = workspaceKey

logAnalytics = append(logAnalytics, output)
}

return []interface{}{
map[string]interface{}{
"log_analytics": logAnalytics,
},
}
}

func resourceArmContainerGroupPortsHash(v interface{}) int {
var buf bytes.Buffer

Expand Down
78 changes: 76 additions & 2 deletions azurerm/resource_arm_container_group_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,11 @@ func TestAccAzureRMContainerGroup_linuxComplete(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "container.0.volume.0.read_only", "false"),
resource.TestCheckResourceAttr(resourceName, "os_type", "Linux"),
resource.TestCheckResourceAttr(resourceName, "restart_policy", "OnFailure"),
resource.TestCheckResourceAttr(resourceName, "diagnostics.0.log_analytics.#", "1"),
resource.TestCheckResourceAttr(resourceName, "diagnostics.0.log_analytics.0.log_type", "ContainerInsights"),
resource.TestCheckResourceAttr(resourceName, "diagnostics.0.log_analytics.0.metadata.%", "1"),
resource.TestCheckResourceAttrSet(resourceName, "diagnostics.0.log_analytics.0.workspace_id"),
resource.TestCheckResourceAttrSet(resourceName, "diagnostics.0.log_analytics.0.workspace_key"),
),
metacpp marked this conversation as resolved.
Show resolved Hide resolved
},
{
Expand All @@ -228,6 +233,7 @@ func TestAccAzureRMContainerGroup_linuxComplete(t *testing.T) {
"container.0.secure_environment_variables.%",
"container.0.secure_environment_variables.secureFoo",
"container.0.secure_environment_variables.secureFoo1",
"diagnostics.0.log_analytics.0.workspace_key",
},
},
},
Expand Down Expand Up @@ -293,6 +299,11 @@ func TestAccAzureRMContainerGroup_windowsComplete(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "container.0.secure_environment_variables.secureFoo1", "secureBar1"),
resource.TestCheckResourceAttr(resourceName, "os_type", "Windows"),
resource.TestCheckResourceAttr(resourceName, "restart_policy", "Never"),
resource.TestCheckResourceAttr(resourceName, "diagnostics.0.log_analytics.#", "1"),
resource.TestCheckResourceAttr(resourceName, "diagnostics.0.log_analytics.0.log_type", "ContainerInsights"),
resource.TestCheckResourceAttr(resourceName, "diagnostics.0.log_analytics.0.metadata.%", "1"),
resource.TestCheckResourceAttrSet(resourceName, "diagnostics.0.log_analytics.0.workspace_id"),
resource.TestCheckResourceAttrSet(resourceName, "diagnostics.0.log_analytics.0.workspace_key"),
),
},
{
Expand All @@ -303,6 +314,7 @@ func TestAccAzureRMContainerGroup_windowsComplete(t *testing.T) {
"container.0.secure_environment_variables.%",
"container.0.secure_environment_variables.secureFoo",
"container.0.secure_environment_variables.secureFoo1",
"diagnostics.0.log_analytics.0.workspace_key",
},
},
},
Expand Down Expand Up @@ -543,6 +555,26 @@ resource "azurerm_resource_group" "test" {
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"
}

resource "azurerm_log_analytics_solution" "test" {
solution_name = "ContainerInsights"
location = "${azurerm_resource_group.test.location}"
resource_group_name = "${azurerm_resource_group.test.name}"
workspace_resource_id = "${azurerm_log_analytics_workspace.test.id}"
workspace_name = "${azurerm_log_analytics_workspace.test.name}"

plan {
publisher = "Microsoft"
product = "OMSGallery/ContainerInsights"
}
}

resource "azurerm_container_group" "test" {
name = "acctestcontainergroup-%d"
location = "${azurerm_resource_group.test.location}"
Expand Down Expand Up @@ -575,11 +607,22 @@ resource "azurerm_container_group" "test" {
commands = ["cmd.exe", "echo", "hi"]
}

diagnostics {
log_analytics {
workspace_id = "${azurerm_log_analytics_workspace.test.workspace_id}"
workspace_key = "${azurerm_log_analytics_workspace.test.primary_shared_key}"
log_type = "ContainerInsights"
metadata {
"node-name" = "acctestContainerGroup"
}
}
}

tags = {
environment = "Testing"
}
}
`, ri, location, ri, ri)
`, ri, location, ri, ri, ri)
}

func testAccAzureRMContainerGroup_linuxComplete(ri int, location string) string {
Expand All @@ -589,6 +632,26 @@ resource "azurerm_resource_group" "test" {
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"
}

resource "azurerm_log_analytics_solution" "test" {
solution_name = "ContainerInsights"
location = "${azurerm_resource_group.test.location}"
resource_group_name = "${azurerm_resource_group.test.name}"
workspace_resource_id = "${azurerm_log_analytics_workspace.test.id}"
workspace_name = "${azurerm_log_analytics_workspace.test.name}"

plan {
publisher = "Microsoft"
product = "OMSGallery/ContainerInsights"
}
}

resource "azurerm_storage_account" "test" {
name = "accsa%d"
resource_group_name = "${azurerm_resource_group.test.name}"
Expand Down Expand Up @@ -649,11 +712,22 @@ resource "azurerm_container_group" "test" {
commands = ["/bin/bash", "-c", "ls"]
}

diagnostics {
log_analytics {
workspace_id = "${azurerm_log_analytics_workspace.test.workspace_id}"
workspace_key = "${azurerm_log_analytics_workspace.test.primary_shared_key}"
log_type = "ContainerInsights"
metadata {
"node-name" = "acctestContainerGroup"
}
}
}

tags = {
environment = "Testing"
}
}
`, ri, location, ri, ri, ri, ri)
`, ri, location, ri, ri, ri, ri, ri)
}

func testCheckAzureRMContainerGroupExists(resourceName string) resource.TestCheckFunc {
Expand Down
Loading