Skip to content
Open
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
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ LCAF_ENV_FILE = .lcafenv
# Source repository for repo manifests
REPO_MANIFESTS_URL ?= https://github.com/launchbynttdata/launch-common-automation-framework.git
# Branch of source repository for repo manifests. Other tags not currently supported.
REPO_BRANCH ?= refs/tags/1.0.0
REPO_BRANCH ?= refs/tags/1.7.1
# Path to seed manifest in repository referenced in REPO_MANIFESTS_URL
REPO_MANIFEST ?= manifests/terraform_modules/seed/manifest.xml

Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ No providers.
| <a name="module_signalr"></a> [signalr](#module\_signalr) | terraform.registry.launch.nttdata.com/module_primitive/signalr/azurerm | ~> 1.0 |
| <a name="module_log_analytics_workspace"></a> [log\_analytics\_workspace](#module\_log\_analytics\_workspace) | terraform.registry.launch.nttdata.com/module_primitive/log_analytics_workspace/azurerm | ~> 1.0 |
| <a name="module_diagnostic_setting"></a> [diagnostic\_setting](#module\_diagnostic\_setting) | terraform.registry.launch.nttdata.com/module_primitive/monitor_diagnostic_setting/azurerm | ~> 1.0 |
| <a name="module_action_group"></a> [action\_group](#module\_action\_group) | terraform.registry.launch.nttdata.com/module_primitive/monitor_action_group/azurerm | ~> 1.0.0 |
| <a name="module_metric_alert"></a> [metric\_alert](#module\_metric\_alert) | terraform.registry.launch.nttdata.com/module_primitive/monitor_metric_alert/azurerm | ~> 2.0.0 |

## Resources

Expand Down Expand Up @@ -163,6 +165,8 @@ No resources.
| <a name="input_enabled_log"></a> [enabled\_log](#input\_enabled\_log) | n/a | <pre>list(object({<br> category_group = optional(string, "allLogs")<br> category = optional(string, null)<br> }))</pre> | `null` | no |
| <a name="input_metric"></a> [metric](#input\_metric) | n/a | <pre>object({<br> category = optional(string)<br> enabled = optional(bool)<br> })</pre> | `null` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | A mapping of tags to assign to the resource. | `map(string)` | `{}` | no |
| <a name="input_metric_alerts"></a> [metric\_alerts](#input\_metric\_alerts) | n/a | <pre>map(object({<br> description = string<br> action_groups = optional(set(string), [])<br> enabled = optional(bool, true)<br> severity = optional(number, 3)<br> frequency = optional(string, "PT1M")<br> webhook_properties = optional(map(string))<br><br> criterias = optional(list(object({<br> threshold = number<br> metric_namespace = string<br> metric_name = string<br> aggregation = string<br> operator = string<br> dimensions = optional(list(object({<br> name = string<br> operator = string<br> values = list(string)<br> })))<br> })), [])<br><br> dynamic_criteria = optional(object({<br> alert_sensitivity = string<br> metric_name = string<br> metric_namespace = string<br> aggregation = string<br> operator = string<br> dimensions = optional(list(object({<br> name = string<br> operator = string<br> values = list(string)<br> })))<br> }))<br> }))</pre> | `{}` | no |
| <a name="input_action_groups"></a> [action\_groups](#input\_action\_groups) | n/a | <pre>map(object({<br> action_group_name = string<br> short_name = string<br> arm_role_receivers = optional(set(string))<br> email_receivers = optional(set(string))<br> }))</pre> | `{}` | no |

## Outputs

Expand All @@ -172,4 +176,6 @@ No resources.
| <a name="output_signalr_name"></a> [signalr\_name](#output\_signalr\_name) | n/a |
| <a name="output_location"></a> [location](#output\_location) | n/a |
| <a name="output_resource_group_name"></a> [resource\_group\_name](#output\_resource\_group\_name) | n/a |
| <a name="output_metric_alerts"></a> [metric\_alerts](#output\_metric\_alerts) | n/a |
| <a name="output_action_groups"></a> [action\_groups](#output\_action\_groups) | n/a |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
9 changes: 9 additions & 0 deletions examples/complete/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,20 @@ No resources.

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_logical_product_family"></a> [logical\_product\_family](#input\_logical\_product\_family) | Name of the product family for which the resource is created | `string` | `"launch"` | no |
| <a name="input_logical_product_service"></a> [logical\_product\_service](#input\_logical\_product\_service) | Name of the product service for which the resource is created | `string` | `"signalr"` | no |
| <a name="input_environment"></a> [environment](#input\_environment) | Environment in which the resource should be provisioned like dev, qa, prod etc. | `string` | `"dev"` | no |
| <a name="input_environment_number"></a> [environment\_number](#input\_environment\_number) | The environment count for the respective environment. Defaults to 000. Increments in value of 1 | `string` | `"000"` | no |
| <a name="input_resource_number"></a> [resource\_number](#input\_resource\_number) | The resource count for the respective resource. Defaults to 000. Increments in value of 1 | `string` | `"000"` | no |
| <a name="input_use_azure_region_abbr"></a> [use\_azure\_region\_abbr](#input\_use\_azure\_region\_abbr) | Abbreviate the region in the resource names | `bool` | `true` | no |
| <a name="input_region"></a> [region](#input\_region) | Azure Region in which the infra needs to be provisioned | `string` | `"eastus"` | no |
| <a name="input_log_analytics_workspace_sku"></a> [log\_analytics\_workspace\_sku](#input\_log\_analytics\_workspace\_sku) | Specifies the SKU of the Log Analytics Workspace. Possible values are Free, PerNode, Premium, Standard, Standalone, Unlimited, CapacityReservation, and PerGB2018 (new SKU as of 2018-04-03). Defaults to PerGB2018. | `string` | `"PerGB2018"` | no |
| <a name="input_log_analytics_workspace_retention_in_days"></a> [log\_analytics\_workspace\_retention\_in\_days](#input\_log\_analytics\_workspace\_retention\_in\_days) | The workspace data retention in days. Possible values are either 7 (Free Tier only) or range between 30 and 730. | `number` | `"30"` | no |
| <a name="input_log_analytics_workspace_identity"></a> [log\_analytics\_workspace\_identity](#input\_log\_analytics\_workspace\_identity) | A identity block as defined below. | <pre>object({<br> type = string<br> identity_ids = optional(list(string))<br> })</pre> | `null` | no |
| <a name="input_log_analytics_destination_type"></a> [log\_analytics\_destination\_type](#input\_log\_analytics\_destination\_type) | (Optional) Specifies the type of destination for the logs. Possible values are 'Dedicated' or 'AzureDiagnostics'. | `string` | `"AzureDiagnostics"` | no |
| <a name="input_enabled_log"></a> [enabled\_log](#input\_enabled\_log) | n/a | <pre>list(object({<br> category_group = optional(string, "allLogs")<br> category = optional(string, null)<br> }))</pre> | <pre>[<br> {<br> "category_group": "allLogs"<br> }<br>]</pre> | no |
| <a name="input_metric"></a> [metric](#input\_metric) | n/a | <pre>object({<br> category = optional(string, "AllMetrics")<br> enabled = optional(bool, false)<br> })</pre> | <pre>{<br> "category": "AllMetrics"<br>}</pre> | no |
| <a name="input_metric_alerts"></a> [metric\_alerts](#input\_metric\_alerts) | n/a | <pre>map(object({<br> description = string<br> action_groups = optional(set(string), [])<br> enabled = optional(bool, true)<br> severity = optional(number, 3)<br> frequency = optional(string)<br> webhook_properties = optional(map(string))<br><br> criterias = optional(list(object({<br> threshold = number<br> metric_namespace = string<br> metric_name = string<br> aggregation = string<br> operator = string<br> dimensions = optional(list(object({<br> name = string<br> operator = string<br> values = list(string)<br> })))<br> })), [])<br><br> dynamic_criteria = optional(object({<br> alert_sensitivity = string<br> metric_name = string<br> metric_namespace = string<br> aggregation = string<br> operator = string<br> dimensions = optional(list(object({<br> name = string<br> operator = string<br> values = list(string)<br> })))<br> }))<br> }))</pre> | `{}` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | A mapping of tags to assign to the resource. | `map(string)` | `{}` | no |

## Outputs
Expand All @@ -43,4 +50,6 @@ No resources.
| <a name="output_signalr_name"></a> [signalr\_name](#output\_signalr\_name) | n/a |
| <a name="output_location"></a> [location](#output\_location) | n/a |
| <a name="output_resource_group_name"></a> [resource\_group\_name](#output\_resource\_group\_name) | n/a |
| <a name="output_metric_alerts"></a> [metric\_alerts](#output\_metric\_alerts) | n/a |
| <a name="output_action_groups"></a> [action\_groups](#output\_action\_groups) | n/a |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
9 changes: 9 additions & 0 deletions examples/complete/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@
module "signalr" {
source = "../.."

logical_product_family = var.logical_product_family
logical_product_service = var.logical_product_service
environment = var.environment
environment_number = var.environment_number
resource_number = var.resource_number
use_azure_region_abbr = var.use_azure_region_abbr

signalr_location = var.region
cors_allowed_origins = ["*"]

Expand All @@ -26,5 +33,7 @@ module "signalr" {
enabled_log = var.enabled_log
metric = var.metric

metric_alerts = var.metric_alerts

tags = local.tags
}
8 changes: 8 additions & 0 deletions examples/complete/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,11 @@ output "location" {
output "resource_group_name" {
value = module.signalr.resource_group_name
}

output "metric_alerts" {
value = module.signalr.metric_alerts
}

output "action_groups" {
value = module.signalr.action_groups
}
20 changes: 20 additions & 0 deletions examples/complete/test.tfvars
Original file line number Diff line number Diff line change
@@ -1 +1,21 @@
// empty.

logical_product_family = "launch"
logical_product_service = "signalr"
environment = "test"
environment_number = "001"
resource_number = "001"
use_azure_region_abbr = true

metric_alerts = {
"SystemErrorsHigh" = {
description = "Perecentage of system errors are higher than usual"
dynamic_criteria = {
alert_sensitivity = "Low"
metric_name = "SystemErrors"
metric_namespace = "Microsoft.SignalRService/SignalR"
aggregation = "Maximum"
operator = "GreaterThan"
}
}
}
84 changes: 84 additions & 0 deletions examples/complete/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,46 @@
// See the License for the specific language governing permissions and
// limitations under the License.

# naming variables

variable "logical_product_family" {
description = "Name of the product family for which the resource is created"
type = string
default = "launch"
}

variable "logical_product_service" {
description = "Name of the product service for which the resource is created"
type = string
default = "signalr"
}

variable "environment" {
description = "Environment in which the resource should be provisioned like dev, qa, prod etc."
type = string
default = "dev"
}

variable "environment_number" {
description = "The environment count for the respective environment. Defaults to 000. Increments in value of 1"
type = string
default = "000"
}

variable "resource_number" {
description = "The resource count for the respective resource. Defaults to 000. Increments in value of 1"
type = string
default = "000"
}

variable "use_azure_region_abbr" {
description = "Abbreviate the region in the resource names"
type = bool
default = true
}

# signalr variables

variable "region" {
description = "Azure Region in which the infra needs to be provisioned"
type = string
Expand Down Expand Up @@ -63,6 +103,50 @@ variable "metric" {
}
}

variable "metric_alerts" {
type = map(object({
description = string
action_groups = optional(set(string), [])
enabled = optional(bool, true)
severity = optional(number, 3)
frequency = optional(string)
webhook_properties = optional(map(string))

criterias = optional(list(object({
threshold = number
metric_namespace = string
metric_name = string
aggregation = string
operator = string
dimensions = optional(list(object({
name = string
operator = string
values = list(string)
})))
})), [])

dynamic_criteria = optional(object({
alert_sensitivity = string
metric_name = string
metric_namespace = string
aggregation = string
operator = string
dimensions = optional(list(object({
name = string
operator = string
values = list(string)
})))
}))
}))
default = {}

validation {
condition = alltrue(
[for alert in var.metric_alerts : !(alert.criterias == null && alert.dynamic_criteria == null)],
)
error_message = "At least one of 'criteria', 'dynamic_criteria' must be defined for all metric alerts"
}
}
variable "tags" {
description = "A mapping of tags to assign to the resource."
type = map(string)
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.21
require (
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.16.0
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/monitor/armmonitor v0.11.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/signalr/armsignalr v1.2.0
github.com/gruntwork-io/terratest v0.43.12
github.com/launchbynttdata/lcaf-component-terratest v1.0.3
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,8 @@ github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xP
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v2 v2.0.0 h1:PTFGRSlMKCQelWwxUyYVEUqseBJVemLyqWJjvMyt0do=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v2 v2.0.0/go.mod h1:LRr2FzBTQlONPPa5HREE5+RjSCTXl7BwOvYOaWTqCaI=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/monitor/armmonitor v0.11.0 h1:Ds0KRF8ggpEGg4Vo42oX1cIt/IfOhHWJBikksZbVxeg=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/monitor/armmonitor v0.11.0/go.mod h1:jj6P8ybImR+5topJ+eH6fgcemSFBmU6/6bFF8KkwuDI=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.1.1 h1:7CBQ+Ei8SP2c6ydQTGCCrS35bDxgTMfoP2miAwK++OU=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.1.1/go.mod h1:c/wcGeGx5FUPbM/JltUYHZcKmigwyVLJlDq+4HdtXaw=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/signalr/armsignalr v1.2.0 h1:Y8CF7FyuVVDyX5W6Azwjj3PpwUZVbXBOCyQytv/0QEA=
Expand Down
36 changes: 36 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,39 @@ module "diagnostic_setting" {
enabled_log = var.enabled_log
metric = var.metric
}

# This module is used to create an Azure Monitor Action Group.
module "action_group" {
for_each = var.action_groups
source = "terraform.registry.launch.nttdata.com/module_primitive/monitor_action_group/azurerm"
version = "~> 1.0.0"

action_group_name = each.key
resource_group_name = module.resource_group.name
short_name = each.value.short_name
tags = var.tags
arm_role_receivers = each.value.arm_role_receivers
email_receivers = each.value.email_receivers
depends_on = [module.resource_group]
}

module "metric_alert" {
for_each = var.metric_alerts
source = "terraform.registry.launch.nttdata.com/module_primitive/monitor_metric_alert/azurerm"
version = "~> 2.0.0"

name = each.key
resource_group_name = module.resource_group.name
scopes = [module.signalr.signalr_id]
description = each.value.description
frequency = each.value.frequency
severity = each.value.severity
enabled = each.value.enabled
action_group_ids = [for key in each.value.action_groups : module.action_group[key].action_group_id]
webhook_properties = each.value.webhook_properties

criteria = each.value.criterias

dynamic_criteria = each.value.dynamic_criteria
depends_on = [module.resource_group, module.action_group]
}
18 changes: 18 additions & 0 deletions outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,21 @@ output "location" {
output "resource_group_name" {
value = module.signalr.resource_group_name
}

output "metric_alerts" {
value = {
for key, value in module.metric_alert : key => {
id = value.metric_alert_id
name = value.name
}
}
}

output "action_groups" {
value = {
for key, value in module.action_group : key => {
id = value.action_group_id
name = value.name
}
}
}
26 changes: 24 additions & 2 deletions tests/testimpl/test_impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/Azure/azure-sdk-for-go/sdk/azcore/arm"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud"
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
armMetric "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/monitor/armmonitor"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/signalr/armsignalr"
"github.com/gruntwork-io/terratest/modules/terraform"
"github.com/launchbynttdata/lcaf-component-terratest/types"
Expand All @@ -33,21 +34,42 @@ func TestSignalRExists(t *testing.T, ctx types.TestContext) {
},
}

clientFactory, err := armsignalr.NewClientFactory(subscriptionId, credential, &options)
signalrClient, err := armsignalr.NewClient(subscriptionId, credential, &options)
if err != nil {
t.Fatalf("failed to create SignalR client: %v", err)
}

armMetricAlertsClient, err := armMetric.NewMetricAlertsClient(subscriptionId, credential, &options)
if err != nil {
t.Fatalf("Error getting Metric Alerts client: %v", err)
}

t.Run("doesSignalRExist", func(t *testing.T) {
resourceGroupName := terraform.Output(t, ctx.TerratestTerraformOptions(), "resource_group_name")
signalrName := terraform.Output(t, ctx.TerratestTerraformOptions(), "signalr_name")

res, err := clientFactory.NewClient().Get(context.Background(), resourceGroupName, signalrName, nil)
res, err := signalrClient.Get(context.Background(), resourceGroupName, signalrName, nil)
if err != nil {
t.Fatalf("failed to finish the request: %v", err)
}

assert.Equal(t, *res.Name, signalrName)
})

t.Run("doesMetricAlertsExist", func(t *testing.T) {
resourceGroupName := terraform.Output(t, ctx.TerratestTerraformOptions(), "resource_group_name")
metricAlertsMap := terraform.OutputMapOfObjects(t, ctx.TerratestTerraformOptions(), "metric_alerts")
var metricAlertsName string
for _, v := range metricAlertsMap {
metricAlertsName = v.(map[string]interface{})["name"].(string)
break // Access the first metric alert and break
}

metricAlerts, err := armMetricAlertsClient.Get(context.Background(), resourceGroupName, metricAlertsName, nil)
if err != nil {
t.Fatalf("Error getting MetricAlerts: %v", err)
}

assert.Equal(t, metricAlertsName, *metricAlerts.Name)
})
}
Loading