
Huawei Cloud Terraform Generator
- 124 installs
- 19 repo stars
- Updated July 31, 2026
- huaweicloud/huaweicloud-skills
Generate Huawei Cloud Terraform configurations for resources like VPC EIP, SMN topics/subscriptions, and Anti-DDoS using huaweicloud provider resource blocks.
About
Generates Terraform HCL for Huawei Cloud resources using the huaweicloud provider. A developer uses it to scaffold infrastructure-as-code for services such as VPC EIP, SMN, and Anti-DDoS.
- Emits huaweicloud provider resource blocks with variables
- Covers VPC EIP, SMN topic/subscription, and Anti-DDoS resources
Huawei Cloud Terraform Generator by the numbers
- 124 all-time installs (skills.sh)
- +16 installs in the week ending Aug 2, 2026 (Skillselion tracking)
- Ranked #531 of 1,042 Cloud & Infrastructure skills by installs in the Skillselion catalog
- Data as of Aug 2, 2026 (Skillselion catalog sync)
npx skills add https://github.com/huaweicloud/huaweicloud-skills --skill huawei-cloud-terraform-generatorAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 124 |
|---|---|
| repo stars | ★ 19 |
| Last updated | July 31, 2026 |
| Repository | huaweicloud/huaweicloud-skills ↗ |
What it does
Generate Huawei Cloud Terraform configurations for resources like VPC EIP, SMN topics/subscriptions, and Anti-DDoS using huaweicloud provider resource blocks.
Files
resource "huaweicloud_vpc_eip" "test" {
publicip {
type = var.vpc_eip_publicip_type
}
bandwidth {
share_type = var.vpc_eip_bandwidth_share_type
name = var.vpc_eip_bandwidth_name
size = var.vpc_eip_bandwidth_size
charge_mode = var.vpc_eip_bandwidth_charge_mode
}
}
resource "huaweicloud_smn_topic" "test" {
name = var.smn_topic_name
display_name = var.smn_topic_display_name
}
resource "huaweicloud_smn_subscription" "test" {
topic_urn = huaweicloud_smn_topic.test.id
endpoint = var.smn_subscription_endpoint
protocol = var.smn_subscription_protocol
remark = var.smn_subscription_remark
}
resource "huaweicloud_antiddos_basic" "test" {
traffic_threshold = var.antiddos_traffic_threshold
eip_id = huaweicloud_vpc_eip.test.id
topic_urn = huaweicloud_smn_topic.test.id
}
terraform {
required_version = ">= 1.9.0"
required_providers {
huaweicloud = {
source = "huaweicloud/huaweicloud"
version = ">= 1.50.0"
}
}
}
provider "huaweicloud" {
region = var.region_name
access_key = var.access_key
secret_key = var.secret_key
}
Create a basic configuration for Anti-DDoS
This example provides best practice code for using Terraform to create a basic configuration in HuaweiCloud Anti-DDoS service.
Prerequisites
- A HuaweiCloud account
- Terraform installed
- HuaweiCloud access key and secret key (AK/SK)
Variable Introduction
The following variables need to be configured:
Authentication Variables
region_name- The region where the Anti-DDoS basic configuration is locatedaccess_key- The access key of the IAM usersecret_key- The secret key of the IAM user
Resource Variables
Required Variables
vpc_eip_publicip_type- The EIP type. Possible values are 5_bgp (dynamic BGP) and 5_sbgp (static BGP)vpc_eip_bandwidth_share_type- The bandwidth share type. Possible values are PER (dedicated bandwidth) and
WHOLE (shared bandwidth)
smn_topic_name- The name of the topic to be createdsmn_subscription_endpoint- The message endpointsmn_subscription_protocol- The protocol of the message endpointantiddos_traffic_threshold- The traffic cleaning threshold in Mbps
Optional Variables
vpc_eip_bandwidth_name- The bandwidth name (required whenvpc_eip_bandwidth_share_typeis PER) (default: null)vpc_eip_bandwidth_size- The bandwidth size (required whenvpc_eip_bandwidth_share_typeis PER) (default: null)vpc_eip_bandwidth_charge_mode- The bandwidth charge mode (default: null)smn_topic_display_name- The topic display name (default: null)smn_subscription_remark- The remark information (default: null)
Usage
- Copy this example script to your
main.tf.
- Create a
terraform.tfvarsfile and fill in the required variables:
vpc_eip_publicip_type = "5_bgp"
vpc_eip_bandwidth_share_type = "PER"
vpc_eip_bandwidth_name = "test-antiddos-basic-name"
vpc_eip_bandwidth_size = 5
vpc_eip_bandwidth_charge_mode = "traffic"
smn_topic_name = "test-antiddos-basic-name"
smn_subscription_endpoint = "mailtest@gmail.com"
smn_subscription_protocol = "email"
antiddos_traffic_threshold = 200- Initialize Terraform:
$ terraform init- Review the Terraform plan:
$ terraform plan- Apply the configuration:
$ terraform apply- To clean up the resources:
$ terraform destroyNote
- Make sure to keep your credentials secure and never commit them to version control
- All resources will be created in the specified region
Requirements
| Name | Version |
|---|---|
| terraform | >= 0.14.0 |
| huaweicloud | >= 1.60.1 |
vpc_eip_publicip_type = "5_bgp"
vpc_eip_bandwidth_share_type = "PER"
vpc_eip_bandwidth_name = "test-antiddos-basic-name"
vpc_eip_bandwidth_size = 5
vpc_eip_bandwidth_charge_mode = "traffic"
smn_topic_name = "test-antiddos-basic-name"
smn_topic_display_name = "The display name of topic test-antiddos-basic-name"
smn_subscription_endpoint = "mailtest@gmail.com"
smn_subscription_protocol = "email"
smn_subscription_remark = "test remark"
antiddos_traffic_threshold = 200
# Variable definitions for authentication
variable "region_name" {
description = "The region where the Anti-DDoS cloud domain is located"
type = string
}
variable "access_key" {
description = "The access key of the IAM user"
type = string
sensitive = true
}
variable "secret_key" {
description = "The secret key of the IAM user"
type = string
sensitive = true
}
# Variable definitions for module
variable "vpc_eip_publicip_type" {
description = "The EIP type"
type = string
}
variable "vpc_eip_bandwidth_share_type" {
description = "The bandwidth share type"
type = string
}
variable "vpc_eip_bandwidth_name" {
description = "The bandwidth name"
type = string
default = null
}
variable "vpc_eip_bandwidth_size" {
description = "The bandwidth size"
type = number
default = null
}
variable "vpc_eip_bandwidth_charge_mode" {
description = "The bandwidth charge mode"
type = string
default = null
}
variable "smn_topic_name" {
description = "The name of the topic to be created"
type = string
}
variable "smn_topic_display_name" {
description = "The topic display name"
type = string
default = null
}
variable "smn_subscription_endpoint" {
description = "The message endpoint"
type = string
}
variable "smn_subscription_protocol" {
description = "The protocol of the message endpoint"
type = string
}
variable "smn_subscription_remark" {
description = "The remark information"
type = string
default = null
}
variable "antiddos_traffic_threshold" {
description = "The traffic cleaning threshold in Mbps"
type = number
}
resource "huaweicloud_antiddos_default_protection_policy" "test" {
traffic_threshold = var.antiddos_traffic_threshold
}
terraform {
required_version = ">= 1.9.0"
required_providers {
huaweicloud = {
source = "huaweicloud/huaweicloud"
version = ">= 1.50.0"
}
}
}
provider "huaweicloud" {
region = var.region_name
access_key = var.access_key
secret_key = var.secret_key
}
Create a default protection policy for Anti-DDoS
This example provides best practice code for using Terraform to create a default protection policy in HuaweiCloud Anti-DDoS service.
Prerequisites
- A HuaweiCloud account
- Terraform installed
- HuaweiCloud access key and secret key (AK/SK)
Variable Introduction
The following variables need to be configured:
Authentication Variables
region_name- The region where the Anti-DDoS default protection policy is locatedaccess_key- The access key of the IAM usersecret_key- The secret key of the IAM user
Resource Variables
Required Variables
antiddos_traffic_threshold- The traffic cleaning threshold in Mbps
Usage
- Copy this example script to your
main.tf.
- Create a
terraform.tfvarsfile and fill in the required variables:
antiddos_traffic_threshold = 200- Initialize Terraform:
$ terraform init- Review the Terraform plan:
$ terraform plan- Apply the configuration:
$ terraform apply- To clean up the resources:
$ terraform destroyNote
- Make sure to keep your credentials secure and never commit them to version control
- All resources will be created in the specified region
Requirements
| Name | Version |
|---|---|
| terraform | >= 0.14.0 |
| huaweicloud | >= 1.69.0 |
antiddos_traffic_threshold = 200
# Variable definitions for authentication
variable "region_name" {
description = "The region where the Anti-DDoS cloud domain is located"
type = string
}
variable "access_key" {
description = "The access key of the IAM user"
type = string
sensitive = true
}
variable "secret_key" {
description = "The secret key of the IAM user"
type = string
sensitive = true
}
# Variable definitions for module
variable "antiddos_traffic_threshold" {
description = "The traffic cleaning threshold in Mbps"
type = number
}
resource "huaweicloud_lts_group" "test" {
group_name = var.lts_group_name
ttl_in_days = var.lts_ttl_in_days
enterprise_project_id = var.enterprise_project_id
}
resource "huaweicloud_lts_stream" "test" {
group_id = huaweicloud_lts_group.test.id
stream_name = var.lts_stream_name
is_favorite = var.lts_is_favorite
enterprise_project_id = var.enterprise_project_id
}
resource "huaweicloud_antiddos_lts_config" "test" {
lts_group_id = huaweicloud_lts_group.test.id
lts_attack_stream_id = huaweicloud_lts_stream.test.id
enterprise_project_id = var.enterprise_project_id
}
terraform {
required_version = ">= 1.9.0"
required_providers {
huaweicloud = {
source = "huaweicloud/huaweicloud"
version = ">= 1.50.0"
}
}
}
provider "huaweicloud" {
region = var.region_name
access_key = var.access_key
secret_key = var.secret_key
}
Create a LTS configuration for Anti-DDoS
This example provides best practice code for using Terraform to create a LTS configuration in HuaweiCloud Anti-DDoS service.
Prerequisites
- A HuaweiCloud account
- Terraform installed
- HuaweiCloud access key and secret key (AK/SK)
Variable Introduction
The following variables need to be configured:
Authentication Variables
region_name- The region where the Anti-DDoS LTS configuration is locatedaccess_key- The access key of the IAM usersecret_key- The secret key of the IAM user
Resource Variables
Required Variables
lts_group_name- The name of the LTS grouplts_stream_name- The name of the LTS streamlts_ttl_in_days- The log expiration time(days)
Optional Variables
lts_is_favorite- Whether to favorite the log stream (default: false)enterprise_project_id- The enterprise project ID (default: null)
Usage
- Copy this example script to your
main.tf.
- Create a
terraform.tfvarsfile and fill in the required variables:
lts_group_name = "test-lts-group-name"
lts_stream_name = "test-lts-stream-name"
lts_ttl_in_days = 7- Initialize Terraform:
$ terraform init- Review the Terraform plan:
$ terraform plan- Apply the configuration:
$ terraform apply- To clean up the resources:
$ terraform destroyNote
- Make sure to keep your credentials secure and never commit them to version control
- All resources will be created in the specified region
Requirements
| Name | Version |
|---|---|
| terraform | >= 0.14.0 |
| huaweicloud | >= 1.77.6 |
lts_group_name = "test-lts-group-name"
lts_stream_name = "test-lts-stream-name"
lts_ttl_in_days = 7
lts_is_favorite = true
enterprise_project_id = "0"
# Variable definitions for authentication
variable "region_name" {
description = "The region where the Anti-DDoS cloud domain is located"
type = string
}
variable "access_key" {
description = "The access key of the IAM user"
type = string
sensitive = true
}
variable "secret_key" {
description = "The secret key of the IAM user"
type = string
sensitive = true
}
# Variable definitions for module
variable "lts_group_name" {
description = "The name of the LTS group"
type = string
}
variable "lts_ttl_in_days" {
description = "The log expiration time(days)"
type = number
}
variable "enterprise_project_id" {
description = "The enterprise project ID"
type = string
default = null
}
variable "lts_stream_name" {
description = "The name of the LTS stream"
type = string
}
variable "lts_is_favorite" {
description = "Whether to favorite the log stream"
type = bool
default = false
}
resource "huaweicloud_smn_topic" "test" {
name = var.smn_topic_name
enterprise_project_id = var.enterprise_project_id != "" ? var.enterprise_project_id : null
}
resource "huaweicloud_smn_subscription" "test" {
count = length(var.alarm_callback_urls) > 0 ? 1 : 0
topic_urn = huaweicloud_smn_topic.test.id
protocol = length(regexall("^https?://", var.alarm_callback_urls[count.index])) > 0 ? "https" : "http"
endpoint = var.alarm_callback_urls[count.index]
}
resource "huaweicloud_aom_message_template" "test" {
name = var.alarm_notification_template_name
locale = var.alarm_notification_template_locale
enterprise_project_id = var.enterprise_project_id != "" ? var.enterprise_project_id : null
description = var.alarm_notification_template_description
templates {
sub_type = var.alarm_notification_template_notification_type
topic = var.alarm_notification_template_notification_topic
content = var.alarm_notification_template_content
}
}
resource "huaweicloud_aom_alarm_action_rule" "test" {
depends_on = [huaweicloud_aom_message_template.test]
name = var.alarm_action_rule_name
user_name = var.alarm_action_rule_user_name
type = var.alarm_action_rule_type
notification_template = huaweicloud_aom_message_template.test.name
smn_topics {
topic_urn = huaweicloud_smn_topic.test.topic_urn
}
}
terraform {
required_version = ">= 1.9.0"
required_providers {
huaweicloud = {
source = "huaweicloud/huaweicloud"
version = ">= 1.50.0"
}
}
}
provider "huaweicloud" {
region = var.region_name
access_key = var.access_key
secret_key = var.secret_key
}
AOM Alarm Action Callback
This example provides best practice code for using Terraform to configure AOM alarm action callback through SMN (Simple Message Notification) on HuaweiCloud. The example demonstrates how to create a custom alarm notification template and configure alarm action rules with callback URLs to receive alarm notifications.
Prerequisites
- A HuaweiCloud account
- Terraform installed
- HuaweiCloud access key and secret key (AK/SK)
- AOM service enabled in the target region
- SMN service enabled in the target region
- A callback endpoint URL that can receive HTTP/HTTPS requests
Variable Introduction
The following variables need to be configured:
Authentication Variables
region_name- The region where resources will be createdaccess_key- The access key of the IAM usersecret_key- The secret key of the IAM user
Resource Variables
Required Variables
smn_topic_name- The name of the SMN topic used to send notificationsalarm_callback_urls- The list of callback URLs to receive alarm notifications (must start withhttp://or
https://, at least one URL is required)
alarm_notification_template_name- The name of the AOM alarm notification templatealarm_action_rule_name- The name of the AOM alarm action rulealarm_action_rule_user_name- The user name of the AOM alarm action rule
Optional Variables
enterprise_project_id- The ID of the enterprise project (default: "")alarm_notification_template_locale- The locale of the alarm notification template (default: "en-us", valid values:
"en-us" or "zh-cn")
alarm_notification_template_description- The description of the alarm notification template (default: "")alarm_notification_template_notification_type- The notification type of the template (default: "email")alarm_notification_template_notification_topic- The notification topic/title template (default: "An alert occurred
at time $${starts_at}[$${event_severity}_$${event_type}_$${clear_type}].")
alarm_notification_template_content- The content template of the alarm notification (default: includes alarm name,
ID, trigger time, severity, content, resource identifier, and remediation suggestion)
alarm_action_rule_type- The type of the AOM alarm action rule (default: "1" for notification)
Usage
- Copy this example script to your
main.tf.
- Create a
terraform.tfvarsfile and fill in the required variables:
smn_topic_name = "tf_test_alarm_action_callback"
alarm_callback_urls = ["https://www.example.com/alarm-callback"]
alarm_notification_template_name = "tf_test_alarm_action_callback"
alarm_notification_template_description = "This is a AOM alarm notification template created by Terraform"
alarm_action_rule_name = "tf_test_alarm_action_callback"
alarm_action_rule_user_name = "your_operation_user_name"- Initialize Terraform:
terraform init- Review the Terraform plan:
terraform plan- Apply the configuration:
terraform apply- To clean up the resources:
terraform destroyNotes
- Make sure to keep your credentials secure and never commit them to version control
- The alarm callback URLs must be valid HTTP or HTTPS URLs and must be accessible from the internet
- The alarm action rule depends on the alarm notification template
- The SMN subscription will be created automatically for each callback URL in the list
- The protocol (HTTP/HTTPS) for SMN subscription is automatically detected from the URL prefix
- The notification template supports variable substitution using
$${variable_name}syntax - Available template variables include:
$${event_name_alias}- Alarm name alias$${id}- Alarm ID$${action_rule}- Notification rule name$${starts_at}- Trigger time$${event_severity}- Alarm severity level$${event_type}- Event type$${clear_type}- Clear type$${alarm_info}- Alarm content$${resources_new}- Resource identifier$${alarm_fix_suggestion_zh}- Remediation suggestion (Chinese)- The template locale determines the language of built-in template variables
- All resources will be created in the specified region
- The callback endpoint should be able to handle POST requests with JSON payload
- When an alarm is triggered, SMN will send a notification to the configured callback URLs
Requirements
| Name | Version |
|---|---|
| terraform | >= 0.14.0 |
| huaweicloud | = 1.80.4 |
smn_topic_name = "tf_test_alarm_action_callback"
alarm_callback_urls = ["https://www.example.com"]
alarm_notification_template_name = "tf_test_alarm_action_callback"
alarm_notification_template_description = "This is a AOM alarm notification template created by Terraform"
alarm_action_rule_name = "tf_test_alarm_action_callback"
alarm_action_rule_user_name = "your_operation_user_name"
# Variable definitions for authentication
variable "region_name" {
description = "The region where resources will be created"
type = string
}
variable "access_key" {
description = "The access key of the IAM user"
type = string
sensitive = true
}
variable "secret_key" {
description = "The secret key of the IAM user"
type = string
sensitive = true
}
# Variable definitions for resources/data sources
variable "smn_topic_name" {
description = "The name of the SMN topic that used to send the SMN notification"
type = string
}
variable "enterprise_project_id" {
description = "The ID of the enterprise project"
type = string
default = ""
}
variable "alarm_callback_urls" {
description = "The URLs of the alarm callback"
type = list(string)
validation {
condition = length(var.alarm_callback_urls) > 0 && alltrue([for url in var.alarm_callback_urls : length(regexall("^http[s]?://", url)) > 0])
error_message = "The alarm callback URLs must be provided and must start with http:// or https://"
}
}
variable "alarm_notification_template_name" {
description = "The name of the AOM alarm notification template that used to send the SMN notification"
type = string
}
variable "alarm_notification_template_locale" {
description = "The locale of the AOM alarm notification template that used to send the SMN notification"
type = string
default = "en-us"
validation {
condition = contains(["en-us", "zh-cn"], var.alarm_notification_template_locale)
error_message = "The alarm notification template locale must be 'en-us' or 'zh-cn'"
}
}
variable "alarm_notification_template_description" {
description = "The description of the AOM alarm notification template that used to send the SMN notification"
type = string
default = ""
}
variable "alarm_notification_template_notification_type" {
description = "The notification type of the AOM alarm notification template that used to send the SMN notification"
type = string
default = "email"
}
variable "alarm_notification_template_notification_topic" {
description = "The notification topic of the AOM alarm notification template that used to send the SMN notification"
type = string
default = "An alert occurred at time $${starts_at}[$${event_severity}_$${event_type}_$${clear_type}]."
}
variable "alarm_notification_template_content" {
description = "The content of the AOM alarm notification template that used to send the SMN notification"
type = string
default = <<EOT
Alarm Name: $${event_name_alias};
Alarm ID: $${id};
Notification Rule: $${action_rule};
Trigger Time: $${starts_at};
Trigger Level: $${event_severity};
Alarm Content: $${alarm_info};
Resource Identifier: $${resources_new};
Remediation Suggestion: $${alarm_fix_suggestion_zh};
EOT
}
variable "alarm_action_rule_name" {
description = "The name of the AOM alarm action rule that used to send the SMN notification"
type = string
}
variable "alarm_action_rule_user_name" {
description = "The user name of the AOM alarm action rule that used to send the SMN notification"
type = string
}
variable "alarm_action_rule_type" {
description = "The type of the AOM alarm action rule that used to send the SMN notification"
type = string
default = "1" # notification
}
data "huaweicloud_dcs_instances" "test" {
name = var.dcs_instance_name
}
locals {
enterprise_project_id = try(data.huaweicloud_dcs_instances.test.instances[0].enterprise_project_id, null)
}
resource "huaweicloud_lts_group" "test" {
group_name = var.lts_group_name
ttl_in_days = 30
enterprise_project_id = local.enterprise_project_id
}
resource "huaweicloud_lts_stream" "test" {
group_id = huaweicloud_lts_group.test.id
stream_name = var.lts_stream_name
enterprise_project_id = local.enterprise_project_id
}
resource "huaweicloud_smn_topic" "test" {
name = var.smn_topic_name
enterprise_project_id = local.enterprise_project_id
}
resource "huaweicloud_smn_logtank" "test" {
topic_urn = huaweicloud_smn_topic.test.topic_urn
log_group_id = huaweicloud_lts_group.test.id
log_stream_id = huaweicloud_lts_stream.test.id
}
resource "huaweicloud_aom_alarm_action_rule" "test" {
name = var.alarm_action_rule_name
user_name = var.alarm_action_rule_user_name
type = var.alarm_action_rule_type
notification_template = "aom.built-in.template.zh"
smn_topics {
topic_urn = huaweicloud_smn_topic.test.topic_urn
}
}
data "huaweicloud_identity_projects" "test" {
# ST.002 Disable
name = var.region_name
# ST.002 Enable
}
locals {
exact_project_id = try([for v in data.huaweicloud_identity_projects.test.projects : v.id if v.name == var.region_name][0], null)
}
resource "huaweicloud_tms_resource_tags" "test" {
project_id = local.exact_project_id
resources {
resource_type = "dcs"
resource_id = try(data.huaweicloud_dcs_instances.test.instances[0].id, null)
}
tags = var.alarm_rule_matric_dimension_tags
}
resource "huaweicloud_aom_prom_instance" "test" {
depends_on = [huaweicloud_tms_resource_tags.test]
prom_name = var.prometheus_instance_name
prom_type = "CLOUD_SERVICE"
enterprise_project_id = local.enterprise_project_id
}
resource "huaweicloud_aom_cloud_service_access" "test" {
instance_id = huaweicloud_aom_prom_instance.test.id
service = "DCS"
tag_sync = "auto"
enterprise_project_id = local.enterprise_project_id
provisioner "local-exec" {
command = "sleep 240" # Waiting for the access center to complete the connection and generate indicators.
}
}
resource "huaweicloud_aomv4_alarm_rule" "test" {
depends_on = [huaweicloud_aom_cloud_service_access.test]
name = var.alarm_rule_name
type = "metric"
enable = true
prom_instance_id = huaweicloud_aom_prom_instance.test.id
enterprise_project_id = local.enterprise_project_id
alarm_notifications {
notification_enable = true
notification_type = "direct"
bind_notification_rule_id = huaweicloud_aom_alarm_action_rule.test.id
notify_resolved = true
notify_triggered = true
notify_frequency = "0"
}
metric_alarm_spec {
monitor_type = "all_metric"
recovery_conditions {
recovery_timeframe = 1
}
dynamic "trigger_conditions" {
for_each = var.alarm_rule_trigger_conditions
content {
metric_query_mode = "PROM"
metric_name = trigger_conditions.value.metric_name
promql = trigger_conditions.value.promql
promql_for = trigger_conditions.value.promql_for
aggregate_type = trigger_conditions.value.aggregate_type
aggregation_type = trigger_conditions.value.aggregation_type
aggregation_window = trigger_conditions.value.aggregation_window
metric_unit = trigger_conditions.value.metric_unit
metric_namespace = trigger_conditions.value.metric_namespace
operator = trigger_conditions.value.operator
metric_statistic_method = trigger_conditions.value.metric_statistic_method
thresholds = trigger_conditions.value.thresholds
trigger_type = trigger_conditions.value.trigger_type
trigger_interval = trigger_conditions.value.trigger_interval
trigger_times = trigger_conditions.value.trigger_times
query_param = trigger_conditions.value.query_param
query_match = trigger_conditions.value.query_match
}
}
}
lifecycle {
ignore_changes = [
metric_alarm_spec # If you want to update this configuration, please use a version higher than 1.82.3
]
}
}
terraform {
required_version = ">= 1.9.0"
required_providers {
huaweicloud = {
source = "huaweicloud/huaweicloud"
version = ">= 1.50.0"
}
}
}
provider "huaweicloud" {
region = var.region_name
access_key = var.access_key
secret_key = var.secret_key
}
Distribute Alarms by HuaweiCloud Tags
This example provides best practice code for using Terraform to distribute alarms by HuaweiCloud tags (Tag) through Prometheus monitoring and alarm management on HuaweiCloud. The example demonstrates how to monitor DCS instance CPU utilization metrics and distribute alarms based on tags.
Prerequisites
- A HuaweiCloud account
- Terraform installed
- HuaweiCloud access key and secret key (AK/SK)
- DCS service enabled in the target region
- AOM service enabled in the target region
- LTS service enabled in the target region
- SMN service enabled in the target region
- TMS service enabled in the target region
- At least one DCS instance exists in the target region
Variable Introduction
The following variables need to be configured:
Authentication Variables
region_name- The region where resources will be createdaccess_key- The access key of the IAM usersecret_key- The secret key of the IAM user
Resource Variables
Required Variables
lts_group_name- The name of the LTS group used to store SMN notification logslts_stream_name- The name of the LTS stream used to store SMN notification logssmn_topic_name- The name of the SMN topic used to send notificationsalarm_action_rule_name- The name of the AOM alarm action rule used to send SMN notificationsalarm_action_rule_user_name- The user name of the AOM alarm action rulealarm_rule_matric_dimension_tags- The custom tags to be added to the DCS instance for alarm distribution (map type,
e.g. { "Ihn" = "OPEN" })
prometheus_instance_name- The name of the Prometheus instance for cloud servicesalarm_rule_name- The name of the AOM alarm rulealarm_rule_trigger_conditions- The trigger conditions of the AOM alarm rulemetric_name- The name of the metric to monitor (e.g. "huaweicloud_sys_dcs_cpu_usage")promql- The PromQL query expression (must include tag conditions,
e.g. huaweicloud_sys_dcs_cpu_usage{Ihn="OPEN"})
aggregation_type- The aggregation method (e.g., "average", "max", "min", "sum")aggregation_window- The time window for aggregation (e.g., "1m")metric_unit- The unit of the metric (e.g., "%")metric_query_mode- The query mode (e.g., "PROM")metric_namespace- The namespace of the metric (e.g., "SYS.DCS")operator- The comparison operator (e.g., ">", "<", ">=", "<=", "=")metric_statistic_method- The statistic method (e.g., "single")thresholds- The alarm thresholds as a map (e.g.,{ "Critical" = 1 })trigger_type- The trigger type (e.g., "FIXED_RATE")trigger_interval- The interval between trigger checks (e.g., "1m")trigger_times- The number of consecutive times the condition must be met (e.g., "3")query_param- The query parameters in JSON formatquery_match- The query match conditions in JSON format (must include tag matching conditions)
Optional Variables
dcs_instance_name- The name of the existing DCS instance to be monitored (default: "", but required for the example
to work properly)
alarm_action_rule_type- The type of the AOM alarm action rule (default: "1" for notification)promql_for- The duration for which the condition must be true in trigger conditions (default: "")aggregate_type- The aggregation type in trigger conditions (default: "by")
Usage
- Copy this example script to your
main.tf.
- Create a
terraform.tfvarsfile and fill in the required variables:
dcs_instance_name = "your_dcs_instance_name"
lts_group_name = "tf_test_aom_alarm_rule_distribute_alarm"
lts_stream_name = "tf_test_aom_alarm_rule_distribute_alarm"
smn_topic_name = "tf_test_aom_alarm_rule_distribute_alarm"
alarm_action_rule_name = "tf_test_aom_alarm_rule_distribute_alarm_by_Ihn_tag"
alarm_action_rule_user_name = "your_iam_user_name"
alarm_rule_matric_dimension_tags = {
"Ihn" = "OPEN"
}
prometheus_instance_name = "tf_test_aom_alarm_rule_distribute_alarm"
alarm_rule_name = "tf_test_aom_alarm_rule_distribute_alarm_by_Ihn_tag"
alarm_rule_trigger_conditions = [
{
metric_name = "huaweicloud_sys_dcs_cpu_usage"
promql = "label_replace(avg_over_time(huaweicloud_sys_dcs_cpu_usage{Ihn=\"OPEN\"}[59999ms]),\"__name__\",\"huaweicloud_sys_dcs_cpu_usage\",\"\",\"\")"
promql_for = ""
aggregate_type = "by"
aggregation_type = "average"
aggregation_window = "1m"
metric_unit = "%"
metric_query_mode = "PROM"
metric_namespace = "SYS.DCS"
operator = ">"
metric_statistic_method = "single"
thresholds = {
"Critical" = 1
}
trigger_type = "FIXED_RATE"
trigger_interval = "1m"
trigger_times = "3"
query_param = "{\"code\": \"a\", \"apmMetricReg\": []}"
query_match = "[{\"id\":\"first\",\"dimension\":\"Ihn\",\"conditionValue\":[{\"name\":\"OPEN\"}],\"conditionList\":[{\"name\":\"OPEN\"}],\"addMode\": \"first\",\"conditionCompare\":\"=\",\"regExpress\":null,\"dimensionSelected\":{\"label\":\"Ihn\",\"id\":\"Ihn\"}}]"
}
]- Initialize Terraform:
terraform init- Review the Terraform plan:
terraform plan- Apply the configuration:
terraform apply- To clean up the resources:
terraform destroyNotes
- Make sure to keep your credentials secure and never commit them to version control
- The DCS instance must exist before running this example
- Tags will be automatically added to the DCS instance through TMS (Tag Management Service)
- The Prometheus instance type is set to "CLOUD_SERVICE" to support cloud service monitoring
- The cloud service access configuration includes automatic tag synchronization (
tag_sync = "auto") - After creating the cloud service access, the system waits 240 seconds for the access center to complete the connection
and generate indicators
- The alarm rule uses direct notification type and binds to the alarm action rule
- The PromQL query expression must include tag conditions to filter metrics by tags
- The
query_matchparameter must include tag matching conditions in JSON format - The
metric_alarm_specconfiguration is ignored in lifecycle to prevent unintended updates (requires provider version
>= 1.82.3 for updates)
- All resources will be created in the specified region
- The enterprise project ID is automatically retrieved from the DCS instance if available
- The alarm rule will only trigger for DCS instances that match the specified tags
Requirements
| Name | Version |
|---|---|
| terraform | >= 1.3.0 |
| huaweicloud | >= 1.80.4 |
dcs_instance_name = "tf_test_aom_alarm_rule_distribute_alarm"
lts_group_name = "tf_test_aom_alarm_rule_distribute_alarm"
lts_stream_name = "tf_test_aom_alarm_rule_distribute_alarm"
smn_topic_name = "tf_test_aom_alarm_rule_distribute_alarm"
alarm_action_rule_name = "tf_test_aom_alarm_rule_distribute_alarm_by_Ihn_tag"
alarm_action_rule_user_name = "servicestage"
alarm_rule_matric_dimension_tags = {
"Ihn" = "OPEN"
}
prometheus_instance_name = "tf_test_aom_alarm_rule_distribute_alarm"
alarm_rule_name = "tf_test_aom_alarm_rule_distribute_alarm_by_Ihn_tag"
alarm_rule_trigger_conditions = [
{
metric_name = "huaweicloud_sys_dcs_cpu_usage"
promql = "label_replace(avg_over_time(huaweicloud_sys_dcs_cpu_usage{Ihn=\"OPEN\"}[59999ms]),\"__name__\",\"huaweicloud_sys_dcs_cpu_usage\",\"\",\"\")"
promql_for = ""
aggregate_type = "by"
aggregation_type = "average"
aggregation_window = "1m"
metric_unit = "%"
metric_query_mode = "PROM"
metric_namespace = "SYS.DCS"
operator = ">"
metric_statistic_method = "single"
thresholds = {
"Critical" = 1
}
trigger_type = "FIXED_RATE"
trigger_interval = "1m"
trigger_times = "3"
query_param = "{\"code\": \"a\", \"apmMetricReg\": []}"
query_match = "[{\"id\":\"first\",\"dimension\":\"Ihn\",\"conditionValue\":[{\"name\":\"OPEN\"}],\"conditionList\":[{\"name\":\"OPEN\"}],\"addMode\": \"first\",\"conditionCompare\":\"=\",\"regExpress\":null,\"dimensionSelected\":{\"label\":\"Ihn\",\"id\":\"Ihn\"}}]"
}
]
# Variable definitions for authentication
variable "region_name" {
description = "The region where resources will be created"
type = string
}
variable "access_key" {
description = "The access key of the IAM user"
type = string
sensitive = true
}
variable "secret_key" {
description = "The secret key of the IAM user"
type = string
sensitive = true
}
# Variable definitions for resources/data sources
variable "dcs_instance_name" {
description = "The name of the DCS instance that used to store the alarm data"
type = string
default = ""
}
variable "lts_group_name" {
description = "The name of the LTS group that used to store the SMN notification logs"
type = string
}
variable "lts_stream_name" {
description = "The name of the LTS stream that used to store the SMN notification logs"
type = string
}
variable "smn_topic_name" {
description = "The name of the SMN topic that used to send the SMN notification"
type = string
}
variable "alarm_action_rule_name" {
description = "The name of the AOM alarm action rule that used to send the SMN notification"
type = string
}
variable "alarm_action_rule_user_name" {
description = "The user name of the AOM alarm action rule"
type = string
}
variable "alarm_action_rule_type" {
description = "The type of the AOM alarm action rule"
type = string
default = "1" # notification
}
variable "alarm_rule_matric_dimension_tags" {
description = "The custom tag of the DCS instance that used to distribute the alarm rule"
type = map(string)
}
variable "prometheus_instance_name" {
description = "The name of the Prometheus instance that used to store the alarm data"
type = string
}
variable "alarm_rule_name" {
description = "The name of the AOM alarm rule"
type = string
}
variable "alarm_rule_trigger_conditions" {
description = "The trigger conditions of the AOM alarm rule"
type = list(object({
metric_name = string
promql = string
promql_for = string
aggregate_type = optional(string, "by")
aggregation_type = string
aggregation_window = string
metric_unit = string
metric_query_mode = string
metric_namespace = string
operator = string
metric_statistic_method = string
thresholds = map(any) # key is the alarm level, value is the alarm threshold, e.g. "{\"Critical\": 1}"
trigger_type = string
trigger_interval = string
trigger_times = string
query_param = string # Query parameters in JSON format
query_match = string # Query match conditions in JSON format
}))
}
resource "huaweicloud_lts_group" "test" {
group_name = var.lts_group_name
ttl_in_days = 30
enterprise_project_id = var.enterprise_project_id != "" ? var.enterprise_project_id : null
}
resource "huaweicloud_lts_stream" "test" {
group_id = huaweicloud_lts_group.test.id
stream_name = var.lts_stream_name
enterprise_project_id = var.enterprise_project_id != "" ? var.enterprise_project_id : null
}
resource "huaweicloud_smn_topic" "test" {
name = var.smn_topic_name
enterprise_project_id = var.enterprise_project_id != "" ? var.enterprise_project_id : null
}
resource "huaweicloud_smn_logtank" "test" {
topic_urn = huaweicloud_smn_topic.test.topic_urn
log_group_id = huaweicloud_lts_group.test.id
log_stream_id = huaweicloud_lts_stream.test.id
}
resource "huaweicloud_aom_alarm_action_rule" "test" {
name = var.alarm_action_rule_name
user_name = var.alarm_action_rule_user_name
type = var.alarm_action_rule_type
notification_template = "aom.built-in.template.zh"
smn_topics {
topic_urn = huaweicloud_smn_topic.test.topic_urn
}
}
resource "huaweicloud_aom_alarm_group_rule" "test" {
depends_on = [huaweicloud_aom_alarm_action_rule.test]
name = var.alarm_group_rule_name
group_by = ["resource_provider"]
group_interval = var.alarm_group_rule_group_interval
group_repeat_waiting = var.alarm_group_rule_group_repeat_waiting
group_wait = var.alarm_group_rule_group_wait
description = var.alarm_group_rule_description != "" ? var.alarm_group_rule_description : null
enterprise_project_id = var.enterprise_project_id != "" ? var.enterprise_project_id : null
detail {
bind_notification_rule_ids = [huaweicloud_aom_alarm_action_rule.test.name]
dynamic "match" {
for_each = var.alarm_group_rule_condition_matching_rules
content {
key = match.value.key
operate = match.value.operate
value = match.value.value
}
}
}
}
resource "huaweicloud_aomv4_alarm_rule" "test" {
name = var.alarm_rule_name
type = "metric"
enable = true
prom_instance_id = var.prometheus_instance_id
alarm_notifications {
notification_enable = true
notification_type = "alarm_policy"
route_group_enable = true
route_group_rule = huaweicloud_aom_alarm_group_rule.test.name
notify_resolved = true
notify_triggered = true
notify_frequency = "-1"
}
metric_alarm_spec {
monitor_type = "all_metric"
recovery_conditions {
recovery_timeframe = 1
}
dynamic "trigger_conditions" {
for_each = var.alarm_rule_trigger_conditions
content {
metric_query_mode = "PROM"
metric_name = trigger_conditions.value.metric_name
promql = trigger_conditions.value.promql
promql_for = trigger_conditions.value.promql_for
aggregate_type = trigger_conditions.value.aggregate_type
aggregation_type = trigger_conditions.value.aggregation_type
aggregation_window = trigger_conditions.value.aggregation_window
metric_statistic_method = trigger_conditions.value.metric_statistic_method
thresholds = trigger_conditions.value.thresholds
trigger_type = trigger_conditions.value.trigger_type
trigger_interval = trigger_conditions.value.trigger_interval
trigger_times = trigger_conditions.value.trigger_times
query_param = trigger_conditions.value.query_param
query_match = trigger_conditions.value.query_match
}
}
}
lifecycle {
ignore_changes = [
metric_alarm_spec # If you want to update this configuration, please use a version higher than 1.82.3
]
}
}
terraform {
required_version = ">= 1.9.0"
required_providers {
huaweicloud = {
source = "huaweicloud/huaweicloud"
version = ">= 1.50.0"
}
}
}
provider "huaweicloud" {
region = var.region_name
access_key = var.access_key
secret_key = var.secret_key
}
Prevent ELB Alarm Storm with AOM Alarm Group Rule
This example provides best practice code for using Terraform to prevent ELB alarm storm by configuring AOM alarm group rules in HuaweiCloud. The example demonstrates how to use alarm grouping rules to reduce alarm noise and prevent alarm storms when monitoring ELB business layer metrics.
Prerequisites
- A HuaweiCloud account
- Terraform installed
- HuaweiCloud access key and secret key (AK/SK)
- AOM service enabled in the target region
- LTS service enabled in the target region
- SMN service enabled in the target region
Variable Introduction
The following variables need to be configured:
Authentication Variables
region_name- The region where the resources are locatedaccess_key- The access key of the IAM usersecret_key- The secret key of the IAM user
Resource Variables
Required Variables
lts_group_name- The name of the LTS group used to store SMN notification logslts_stream_name- The name of the LTS stream used to store SMN notification logssmn_topic_name- The name of the SMN topic used to send notificationsalarm_action_rule_user_name- The user name of the AOM alarm action rulealarm_group_rule_name- The name of the AOM alarm group rulealarm_rule_name- The name of the AOM alarm ruleprometheus_instance_id- The ID of the Prometheus instance (default: "0", which represents the default
Prometheus_AOM_Default instance)
alarm_rule_trigger_conditions- The trigger conditions of the AOM alarm rulemetric_name- The name of the metric to monitorpromql- The PromQL query expressionpromql_for- The duration for which the condition must be trueaggregate_type- The aggregation type (default: "by")aggregation_type- The aggregation method (e.g., "average", "max", "min", "sum")aggregation_window- The time window for aggregationmetric_statistic_method- The statistic method (e.g., "single")thresholds- The alarm thresholds as a map (e.g.,{ "Critical" = 1 })trigger_type- The trigger type (e.g., "FIXED_RATE")trigger_interval- The interval between trigger checkstrigger_times- The number of consecutive times the condition must be metquery_param- The query parameters in JSON formatquery_match- The query match conditions in JSON format
Optional Variables
alarm_action_rule_name- The name of the AOM alarm action rule (default: "apm")alarm_action_rule_type- The type of the AOM alarm action rule (default: "1")alarm_group_rule_group_interval- The group interval of the alarm group rule in seconds (default: 60)alarm_group_rule_group_repeat_waiting- The group repeat waiting time in seconds (default: 3600)alarm_group_rule_group_wait- The group wait time in seconds (default: 15)alarm_group_rule_description- The description of the alarm group rule (default: "")enterprise_project_id- The ID of the enterprise project (default: "")prometheus_instance_id- The ID of the Prometheus instance (default: "0")alarm_group_rule_condition_matching_rules- The condition matching rules for the alarm group rulekey- The key of the matching condition (e.g., "event_severity", "resource_provider")operate- The operation type (e.g., "EXIST", "EQUALS")value- The list of values to match- Default: Filters for Critical and Major severity alarms from AOM
Usage
- Copy this example script to your
main.tf.
- Create a
terraform.tfvarsfile and fill in the required variables:
lts_group_name = "tf_test_aom_prevent_elb_alarm_storm"
lts_stream_name = "tf_test_aom_prevent_elb_alarm_storm"
smn_topic_name = "tf_test_aom_prevent_elb_alarm_storm"
alarm_action_rule_user_name = "your_ima_user_name"
alarm_group_rule_name = "tf_test_aom_prevent_elb_alarm_storm"
alarm_rule_name = "tf_test_aom_prevent_elb_alarm_storm"
prometheus_instance_id = "0" # Optional, default is "0" (Prometheus_AOM_Default)
alarm_rule_trigger_conditions = [
{
metric_name = "aom_metrics_total_per_hour"
promql = "label_replace(avg_over_time(aom_metrics_total_per_hour{type=\"custom\"}[59999ms]),\"__name__\",\"aom_metrics_total_per_hour\",\"\",\"\")"
promql_for = "3m"
aggregate_type = "by"
aggregation_type = "average"
aggregation_window = "1m"
metric_statistic_method = "single"
thresholds = {
"Critical" = 1
}
trigger_type = "FIXED_RATE"
trigger_interval = "1m"
trigger_times = "3"
query_param = "{\"code\": \"a\", \"apmMetricReg\": []}"
query_match = "{\"id\": \"first\", \"dimension\": \"type\", \"conditionValue\": [{\"name\": \"custom\"}], \"conditionList\": [{\"name\": \"custom\"}, {\"name\": \"basic\"}], \"addMode\": \"first\", \"conditionCompare\": \"=\", \"dimensionSelected\": {\"label\": \"type\", \"id\": \"type\"}}"
}
]- Initialize Terraform:
$ terraform init- Review the Terraform plan:
$ terraform plan- Apply the configuration:
$ terraform apply- To clean up the resources:
$ terraform destroyNotes
- Make sure to keep your credentials secure and never commit them to version control
- The alarm group rule is dependent on the alarm action rule
- The alarm rule notification is automatically configured with alarm policy notification type and route group enabled
- The route group rule name in the alarm rule notification automatically matches the alarm group rule name
- The alarm group rule filters alarms by severity (Critical, Major) and source (AOM) by default
- Alarms are grouped by resource provider to merge similar alarms together
- The group wait time determines how long to wait before sending the first notification after creating a group
- The group interval determines how often to check for new alarms in a group
- The group repeat waiting time determines how long to wait before sending a repeat notification for the same group
- All resources will be created in the specified region
- The PromQL query must comply with Prometheus query syntax
- The thresholds is a map type with alarm levels as keys (Critical, Major, Minor, Info) and threshold values as values
- The default Prometheus instance ID is "0", which represents the Prometheus_AOM_Default instance
- The alarm rule uses
huaweicloud_aomv4_alarm_ruleresource with metric alarm type - The
metric_alarm_specconfiguration is ignored in lifecycle to prevent unintended updates (requires provider version
>= 1.82.3 for updates)
Requirements
| Name | Version |
|---|---|
| terraform | >= 1.3.0 |
| huaweicloud | >= 1.80.4 |
lts_group_name = "tf_test_aom_prevent_elb_alarm_storm"
lts_stream_name = "tf_test_aom_prevent_elb_alarm_storm"
smn_topic_name = "tf_test_aom_prevent_elb_alarm_storm"
alarm_action_rule_user_name = "servicestage"
alarm_group_rule_name = "tf_test_aom_prevent_elb_alarm_storm"
alarm_rule_name = "tf_test_aom_prevent_elb_alarm_storm"
alarm_rule_trigger_conditions = [
{
metric_name = "aom_metrics_total_per_hour"
promql = "label_replace(avg_over_time(aom_metrics_total_per_hour{type=\"custom\"}[59999ms]),\"__name__\",\"aom_metrics_total_per_hour\",\"\",\"\")"
promql_for = "3m"
aggregate_type = "by"
aggregation_type = "average"
aggregation_window = "1m"
metric_statistic_method = "single"
thresholds = {
"Critical" = 1
}
trigger_type = "FIXED_RATE"
trigger_interval = "1m"
trigger_times = "3"
query_param = "{\"code\": \"a\", \"apmMetricReg\": []}"
query_match = "{\"id\": \"first\", \"dimension\": \"type\", \"conditionValue\": [{\"name\": \"custom\"}], \"conditionList\": [{\"name\": \"custom\"}, {\"name\": \"basic\"}], \"addMode\": \"first\", \"conditionCompare\": \"=\", \"dimensionSelected\": {\"label\": \"type\", \"id\": \"type\"}}"
}
]
# Variable definitions for authentication
variable "region_name" {
description = "The region where resources will be created"
type = string
}
variable "access_key" {
description = "The access key of the IAM user"
type = string
sensitive = true
}
variable "secret_key" {
description = "The secret key of the IAM user"
type = string
sensitive = true
}
# Variable definitions for resources/data sources
variable "lts_group_name" {
description = "The name of the LTS group that used to store the SMN notification logs"
type = string
}
variable "enterprise_project_id" {
description = "The ID of the enterprise project"
type = string
default = ""
}
variable "lts_stream_name" {
description = "The name of the LTS stream that used to store the SMN notification logs"
type = string
}
variable "smn_topic_name" {
description = "The name of the SMN topic that used to send the SMN notification"
type = string
}
variable "alarm_action_rule_name" {
description = "The name of the AOM alarm action rule that used to send the SMN notification"
type = string
default = "apm"
}
variable "alarm_action_rule_user_name" {
description = "The user name of the AOM alarm action rule"
type = string
}
variable "alarm_action_rule_type" {
description = "The type of the AOM alarm action rule"
type = string
default = "1" # notification
}
variable "alarm_group_rule_name" {
description = "The name of the AOM alarm group rule"
type = string
}
variable "alarm_group_rule_group_interval" {
description = "The group interval of the AOM alarm group rule"
type = number
default = 60
}
variable "alarm_group_rule_group_repeat_waiting" {
description = "The group repeat waiting of the AOM alarm group rule"
type = number
default = 3600
}
variable "alarm_group_rule_group_wait" {
description = "The group wait of the AOM alarm group rule"
type = number
default = 15
}
variable "alarm_group_rule_description" {
description = "The description of the AOM alarm group rule"
type = string
default = ""
}
variable "alarm_group_rule_condition_matching_rules" {
description = "The condition matching rules of the AOM alarm group rule"
type = list(object({
key = string
operate = string
value = list(string)
}))
default = [
{
key = "event_severity"
operate = "EXIST"
value = ["Critical", "Major"]
},
{
key = "resource_provider"
operate = "EQUALS"
value = ["AOM"]
}
]
}
variable "alarm_rule_name" {
description = "The name of the AOM alarm rule"
type = string
}
variable "prometheus_instance_id" {
description = "The ID of the Prometheus instance"
type = string
default = "0" # The default prometheus instance is 'Prometheus_AOM_Default'.
}
variable "alarm_rule_trigger_conditions" {
description = "The trigger conditions of the AOM alarm rule"
type = list(object({
metric_name = string
promql = string
promql_for = string
aggregate_type = optional(string, "by")
aggregation_type = string
aggregation_window = string
metric_statistic_method = string
thresholds = map(any) # key is the alarm level, value is the alarm threshold, e.g. "{\"Critical\": 1}"
trigger_type = string
trigger_interval = string
trigger_times = string
query_param = string # Query parameters in JSON format
query_match = string # Query match conditions in JSON format
}))
}
resource "huaweicloud_vpc" "test" {
name = var.vpc_name
cidr = var.vpc_cidr
}
resource "huaweicloud_vpc_subnet" "test" {
vpc_id = huaweicloud_vpc.test.id
name = var.subnet_name
cidr = var.subnet_cidr == "" ? cidrsubnet(huaweicloud_vpc.test.cidr, 8, 0) : var.subnet_cidr
gateway_ip = var.subnet_gateway_ip == "" ? cidrhost(cidrsubnet(huaweicloud_vpc.test.cidr, 8, 0), 1) : var.subnet_gateway_ip
}
resource "huaweicloud_networking_secgroup" "test" {
name = var.security_group_name
}
resource "huaweicloud_fgs_function" "test" {
name = var.function_name
memory_size = var.function_memory_size
runtime = var.function_runtime
timeout = var.function_timeout
handler = var.function_handler
code_type = var.function_code_type
app = var.function_app
func_code = var.function_code
}
data "huaweicloud_availability_zones" "test" {
count = length(var.availability_zones) == 0 ? 1 : 0
}
resource "huaweicloud_apig_instance" "test" {
name = var.instance_name
edition = var.instance_edition
vpc_id = huaweicloud_vpc.test.id
subnet_id = huaweicloud_vpc_subnet.test.id
security_group_id = huaweicloud_networking_secgroup.test.id
enterprise_project_id = var.enterprise_project_id
availability_zones = length(var.availability_zones) == 0 ? try(slice(data.huaweicloud_availability_zones.test[0].names, 0, var.availability_zones_count), null) : var.availability_zones
}
resource "huaweicloud_apig_custom_authorizer" "test" {
instance_id = huaweicloud_apig_instance.test.id
name = var.custom_authorizer_name
function_urn = huaweicloud_fgs_function.test.urn
function_version = var.function_version
type = var.custom_authorizer_type
network_type = var.custom_authorizer_network_type
cache_age = var.custom_authorizer_cache_age
is_body_send = var.custom_authorizer_is_body_send
user_data = var.custom_authorizer_use_data
dynamic "identity" {
for_each = var.custom_authorizer_identity
content {
name = identity.value.name
location = identity.value.location
validation = identity.value.validation
}
}
}
resource "huaweicloud_apig_response" "test" {
name = var.response_name
instance_id = huaweicloud_apig_instance.test.id
group_id = huaweicloud_apig_group.test.id
dynamic "rule" {
for_each = var.response_rules
content {
error_type = rule.value["error_type"]
body = rule.value["body"]
status_code = rule.value["status_code"]
dynamic "headers" {
for_each = rule.value["headers"]
content {
key = headers.value["key"]
value = headers.value["value"]
}
}
}
}
}
resource "huaweicloud_apig_group" "test" {
name = var.group_name
instance_id = huaweicloud_apig_instance.test.id
}
resource "huaweicloud_apig_api" "test" {
instance_id = huaweicloud_apig_instance.test.id
group_id = huaweicloud_apig_group.test.id
type = var.api_type
name = var.api_name
request_protocol = var.api_request_protocol
request_method = var.api_request_method
request_path = var.api_request_path
security_authentication = "AUTHORIZER"
matching = var.api_matching
response_id = huaweicloud_apig_response.test.id
authorizer_id = huaweicloud_apig_custom_authorizer.test.id
dynamic "backend_params" {
for_each = var.api_backend_params
content {
type = backend_params.value["type"]
name = backend_params.value["name"]
location = backend_params.value["location"]
value = backend_params.value["value"]
system_param_type = backend_params.value["system_param_type"]
}
}
func_graph {
function_urn = huaweicloud_fgs_function.test.urn
version = var.function_version
network_type = var.api_func_graph_network_type
request_protocol = var.api_func_graph_request_protocol
}
}
terraform {
required_version = ">= 1.9.0"
required_providers {
huaweicloud = {
source = "huaweicloud/huaweicloud"
version = ">= 1.50.0"
}
}
}
provider "huaweicloud" {
region = var.region_name
access_key = var.access_key
secret_key = var.secret_key
}
Register an API with Custom Authorizer and FunctionGraph
This example provides best practice code for using Terraform to create an API Gateway instance with a custom authorizer and FunctionGraph backend on HuaweiCloud.
Prerequisites
- A HuaweiCloud account
- Terraform installed
- HuaweiCloud access key and secret key (AK/SK)
Variable Introduction
The following variables need to be configured:
Authentication Variables
region_name- The region where resources will be createdaccess_key- The access key of the IAM usersecret_key- The secret key of the IAM user
Resource Variables
Required Variables
vpc_name- The name of the VPCsubnet_name- The name of the subnetsecurity_group_name- The name of the security groupfunction_name- The name of the FunctionGraph functionfunction_code- The code content of the FunctionGraph functioninstance_name- The instance name of the dedicated APIGenterprise_project_id- The ID of the enterprise project to which the APIG instance belongs (required for
enterprise users, default: null)
custom_authorizer_name- The name of the custom authorizerresponse_name- The response name of the dedicated APIGresponse_rules- The response rules of the dedicated APIGerror_type- The error type of the API response rulebody- The body template of the API response rulestatus_code- The HTTP status code of the API response ruleheaders- The configuration of the custom response headers (default: [])key- The key name of the response headervalue- The value for the specified response header keygroup_name- The group name of the dedicated APIGapi_name- The name of the APIapi_request_path- The request path of the APIapi_backend_params- The backend parameters of the APItype- The type of the backend parametername- The name of the backend parameterlocation- The location of the backend parametervalue- The value of the backend parametersystem_param_type- The system parameter type of the backend parameter (required for system parameters)
Optional Variables
vpc_cidr- The CIDR block of the VPC (default: "192.168.0.0/16")subnet_cidr- The CIDR block of the subnet (default: "")subnet_gateway_ip- The gateway IP of the subnet (default: "")function_memory_size- The memory size (MB) for the function (default: 128)function_runtime- The runtime environment for the function (default: "Python3.9")function_timeout- The timeout (seconds) for the function (default: 3)function_handler- The handler of the function (default: "index.handler")function_code_type- The code type of the function (default: "inline")function_app- The name of the application to which the function belongs (default: "default")availability_zones- The availability zones to which the APIG instance belongs (default: [])
If not specified, will be automatically allocated based on the number of availability_zones_count
instance_edition- The edition of the APIG instance (default: "BASIC")availability_zones_count- The number of availability zones to which the instance belongs (default: 1)function_version- The version of the function (default: "latest")custom_authorizer_type- The type of the custom authorizer (default: "FRONTEND")custom_authorizer_network_type- The network type of the custom authorizer (default: "V1")custom_authorizer_cache_age- The cache age of the custom authorizer (default: 0)custom_authorizer_is_body_send- Whether to send body in the custom authorizer (default: false)custom_authorizer_use_data- The user data used to obtain backend access authorization (default: null)custom_authorizer_identity- The identity list of the custom authorizer (default: [])name- The name of the identitylocation- The location of the identityvalidation- The parameter verification expressionapi_type- The type of the API (default: "Public")api_request_protocol- The request protocol of the API (default: "BOTH")api_request_method- The request method of the API (default: "GET")api_matching- The matching rule of the API (default: "Exact")api_func_graph_network_type- The network type of the FunctionGraph function (default: "V1")api_func_graph_request_protocol- The request protocol of the FunctionGraph function (default: "HTTPS")
Usage
- Copy this example script to your
main.tf.
- Create a
terraform.tfvarsfile and fill in the required variables. Example:
vpc_name = "your_vpc_name"
subnet_name = "your_subnet_name"
security_group_name = "your_security_group_name"
function_name = "your_function_name"
function_code = "your_function_code"
instance_name = "your_apig_instance_name"
enterprise_project_id = "your_enterprise_project_id"
custom_authorizer_name = "your_custom_authorizer_name"
group_name = "your_group_name"
response_name = "your_response_name"
response_rules = "your_response_rules"
api_name = "your_api_name"
api_request_path = "your_api_request_path"
api_backend_params = "your_api_backend_params"- Initialize Terraform:
terraform init- Review the Terraform plan:
terraform plan- Apply the configuration:
terraform apply- To clean up the resources:
terraform destroyNote
- Make sure to keep your credentials secure and never commit them to version control.
- All resources will be created in the specified region.
- Please be aware of API Gateway and FunctionGraph service quotas in your HuaweiCloud account.
Requirements
| Name | Version |
|---|---|
| terraform | >= 1.3.0 |
| huaweicloud | >= 1.72.0 |
vpc_name = "tf_test_apig_api_auth"
subnet_name = "tf_test_apig_api_auth"
security_group_name = "tf_test_apig_api_auth"
function_name = "tf_test_function"
function_code = <<EOF
# -*- coding:utf-8 -*-
import json
def handler(event, context):
if event["headers"].get("x-user-auth")=='cXpsdzQyVW9Xa1NVTX==':
return {
'statusCode': 200,
'body': json.dumps({
"status":"allow",
"context":{
"user_name":"user1"
}
})
}
else:
return {
'statusCode': 200,
'body': json.dumps({
"status":"deny",
"context":{
"code":"1001",
"message":"incorrect username or password"
}
})
}
EOF
instance_name = "tf_test_apig_instance"
enterprise_project_id = "0"
custom_authorizer_name = "tf_test_custom_authorizer"
group_name = "tf_test_apig_group"
response_name = "tf_test_apig_response"
response_rules = [
{
error_type = "AUTHORIZER_FAILURE"
body = "{\"code\":\"$context.authorizer.frontend.code\",\"message\":\"$context.authorizer.frontend.message\"}"
status_code = 401
}
]
api_name = "tf_test_apig_api_auth"
api_request_path = "/backend/users"
api_backend_params = [
{
type = "SYSTEM"
name = "X-User-Auth"
location = "HEADER"
value = "user_name"
system_param_type = "frontend"
}
]
# Variable definitions for authentication
variable "region_name" {
description = "The region where resources will be created"
type = string
}
variable "access_key" {
description = "The access key of the IAM user"
type = string
sensitive = true
}
variable "secret_key" {
description = "The secret key of the IAM user"
type = string
sensitive = true
}
# Variable definitions for resources/data sources
variable "vpc_name" {
description = "The name of the VPC"
type = string
}
variable "vpc_cidr" {
description = "The CIDR block of the VPC"
type = string
default = "192.168.0.0/16"
}
variable "subnet_name" {
description = "The name of the subnet"
type = string
}
variable "subnet_cidr" {
description = "The CIDR block of the subnet"
type = string
default = ""
}
variable "subnet_gateway_ip" {
description = "The gateway IP of the subnet"
type = string
default = ""
}
variable "security_group_name" {
description = "The name of the security group"
type = string
}
variable "function_name" {
description = "The function name of the FunctionGraph"
type = string
}
variable "function_memory_size" {
description = "The memory size (MB) for the function"
type = number
default = 128
}
variable "function_runtime" {
description = "The runtime environment for the function"
type = string
default = "Python3.9"
}
variable "function_timeout" {
description = "The timeout (seconds) for the function"
type = number
default = 3
}
variable "function_handler" {
description = "The handler of the function"
type = string
default = "index.handler"
}
variable "function_code_type" {
description = "The code type of the function"
type = string
default = "inline"
}
variable "function_app" {
description = "The name of the application to which the function belongs"
type = string
default = "default"
}
variable "function_code" {
description = "The code content of the FunctionGraph function"
type = string
}
variable "availability_zones" {
description = "The availability zones to which the APIG instance belongs"
type = list(string)
default = []
nullable = false
}
variable "instance_name" {
description = "The instance name of the dedicated APIG"
type = string
}
variable "instance_edition" {
description = "The edition of the APIG instance"
type = string
default = "BASIC"
}
variable "enterprise_project_id" {
description = "The ID of the enterprise project to which the APIG instance belongs"
type = string
default = null
}
variable "availability_zones_count" {
description = "The number of availability zones to which the instance belongs"
type = number
default = 1
}
variable "custom_authorizer_name" {
description = "The name of the custom authorizer"
type = string
}
variable "function_version" {
description = "The version of the function"
type = string
default = "latest"
}
variable "custom_authorizer_type" {
description = "The type of the custom authorizer"
type = string
default = "FRONTEND"
}
variable "custom_authorizer_network_type" {
description = "The network type of the custom authorizer"
type = string
default = "V1"
}
variable "custom_authorizer_cache_age" {
description = "The cache age of the custom authorizer"
type = number
default = 0
}
variable "custom_authorizer_is_body_send" {
description = "Whether to send body in the custom authorizer"
type = bool
default = false
}
variable "custom_authorizer_use_data" {
description = "The user data used to obtain backend access authorization"
type = string
default = null
}
variable "custom_authorizer_identity" {
description = "The identity list of the custom authorizer"
type = list(object({
name = string
location = string
validation = optional(string, null)
}))
default = []
nullable = false
}
variable "response_name" {
description = "The response name of the dedicated APIG"
type = string
}
variable "response_rules" {
description = "The response rules of the dedicated APIG"
type = list(object({
error_type = string
body = string
status_code = optional(number, null)
headers = optional(list(object({
key = string
value = string
})), [])
}))
default = []
nullable = false
}
variable "group_name" {
description = "The group name of the dedicated APIG"
type = string
}
variable "api_type" {
description = "The type of the API"
type = string
default = "Public"
}
variable "api_name" {
description = "The name of the API"
type = string
}
variable "api_request_protocol" {
description = "The request protocol of the API"
type = string
default = "BOTH"
}
variable "api_request_method" {
description = "The request method of the API"
type = string
default = "GET"
}
variable "api_request_path" {
description = "The request path of the API"
type = string
}
variable "api_matching" {
description = "The matching rule of the API"
type = string
default = "Exact"
}
variable "api_backend_params" {
description = "The backend parameters of the API"
type = list(object({
type = string
name = string
location = string
value = string
system_param_type = optional(string, null)
}))
nullable = false
}
variable "api_func_graph_network_type" {
description = "The network type of the FunctionGraph function"
type = string
default = "V1"
}
variable "api_func_graph_request_protocol" {
description = "The request protocol of the FunctionGraph function"
type = string
default = "HTTPS"
}
resource "huaweicloud_vpc" "test" {
name = var.vpc_name
cidr = var.vpc_cidr
}
resource "huaweicloud_vpc_subnet" "test" {
vpc_id = huaweicloud_vpc.test.id
name = var.subnet_name
cidr = var.subnet_cidr != "" ? var.subnet_cidr : cidrsubnet(huaweicloud_vpc.test.cidr, 8, 0)
gateway_ip = var.subnet_gateway_ip != "" ? var.subnet_gateway_ip : cidrhost(cidrsubnet(huaweicloud_vpc.test.cidr, 8, 0), 1)
}
resource "huaweicloud_networking_secgroup" "test" {
name = var.security_group_name
delete_default_rules = true
}
data "huaweicloud_availability_zones" "test" {
count = length(var.availability_zones) > 0 ? 0 : 1
}
resource "huaweicloud_apig_instance" "test" {
name = var.instance_name
edition = var.instance_edition
vpc_id = huaweicloud_vpc.test.id
subnet_id = huaweicloud_vpc_subnet.test.id
security_group_id = huaweicloud_networking_secgroup.test.id
enterprise_project_id = var.enterprise_project_id
availability_zones = length(var.availability_zones) > 0 ? var.availability_zones : try(slice(data.huaweicloud_availability_zones.test[0].names, 0, var.availability_zones_count), null)
}
data "huaweicloud_dms_kafka_flavors" "test" {
count = var.kafka_instance_flavor_id != "" ? 0 : 1
type = var.kafka_instance_flavor_type
storage_spec_code = var.kafka_instance_storage_spec_code
availability_zones = length(var.availability_zones) > 0 ? var.availability_zones : try(slice(data.huaweicloud_availability_zones.test[0].names, 0, 3))
}
resource "huaweicloud_dms_kafka_instance" "test" {
name = var.kafka_instance_name
description = var.kafka_instance_description
availability_zones = length(var.availability_zones) > 0 ? var.availability_zones : try(slice(data.huaweicloud_availability_zones.test[0].names, 0, 3))
vpc_id = huaweicloud_vpc.test.id
network_id = huaweicloud_vpc_subnet.test.id
security_group_id = huaweicloud_networking_secgroup.test.id
ssl_enable = var.kafka_instance_ssl_enable
flavor_id = var.kafka_instance_flavor_id != "" ? var.kafka_instance_flavor_id : try(data.huaweicloud_dms_kafka_flavors.test[0].flavors[0].id, null)
engine_version = var.kafka_instance_engine_version
storage_spec_code = var.kafka_instance_storage_spec_code
storage_space = var.kafka_instance_storage_space
broker_num = var.kafka_instance_broker_num
charging_mode = var.kafka_charging_mode
period_unit = var.kafka_period_unit
period = var.kafka_period
auto_renew = var.kafka_auto_new
access_user = var.kafka_instance_user_name
password = var.kafka_instance_user_password
# If you want to change some of the following parameters, you need to remove the corresponding fields from "lifecycle.ignore_changes".
lifecycle {
ignore_changes = [
access_user,
availability_zones,
flavor_id,
]
}
}
resource "huaweicloud_dms_kafka_topic" "test" {
instance_id = huaweicloud_dms_kafka_instance.test.id
name = var.kafka_topic_name
partitions = var.kafka_topic_partitions
}
resource "huaweicloud_apig_plugin" "test" {
instance_id = huaweicloud_apig_instance.test.id
name = var.plugin_name
description = var.plugin_description
type = "kafka_log"
content = jsonencode({
broker_list = var.kafka_security_protocol == "PLAINTEXT" ? (split(",", huaweicloud_dms_kafka_instance.test.port_protocol[0].private_plain_address)) : var.kafka_security_protocol == "SASL_PLAINTEXT" ? (split(",", huaweicloud_dms_kafka_instance.test.port_protocol[0].private_sasl_plaintext_address)) : (split(",", huaweicloud_dms_kafka_instance.test.port_protocol[0].private_sasl_ssl_address))
topic = var.kafka_topic_name
key = var.kafka_message_key
max_retry_count = var.kafka_max_retry_count
retry_backoff = var.kafka_retry_backoff
sasl_config = {
security_protocol = var.kafka_security_protocol
sasl_mechanisms = var.kafka_sasl_mechanisms
sasl_username = var.kafka_sasl_username != "" ? nonsensitive(var.kafka_sasl_username) : (var.kafka_security_protocol == "PLAINTEXT" ? "" : nonsensitive(var.kafka_access_user))
sasl_password = var.kafka_sasl_password != "" ? nonsensitive(var.kafka_sasl_password) : (var.kafka_security_protocol == "PLAINTEXT" ? "" : nonsensitive(var.kafka_password))
ssl_ca_content = var.kafka_ssl_ca_content != "" ? nonsensitive(var.kafka_ssl_ca_content) : ""
}
})
lifecycle {
ignore_changes = [
content,
]
}
}
terraform {
required_version = ">= 1.9.0"
required_providers {
huaweicloud = {
source = "huaweicloud/huaweicloud"
version = ">= 1.50.0"
}
}
}
provider "huaweicloud" {
region = var.region_name
access_key = var.access_key
secret_key = var.secret_key
}
Create an APIG instance with Kafka forward plugin
This example provides best practice code for using Terraform to create an API Gateway (APIG) instance with a Kafka forward plugin in HuaweiCloud. This plugin enables asynchronous message processing by forwarding HTTP API requests to Kafka topics.
Prerequisites
- A HuaweiCloud account
- HuaweiCloud access key and secret key (AK/SK)
Variables Introduction
The following variables need to be configured:
Authentication Variables
region_name- The region where resources will be createdaccess_key- The access key of the IAM usersecret_key- The secret key of the IAM user
Resource Variables
Required Variables
vpc_name- The name of the VPCsubnet_name- The name of the subnetsecurity_group_name- The name of the security groupinstance_name- The name of the APIG instanceplugin_name- The name of the Kafka forward pluginkafka_instance_name- The name of the DMS Kafka instancekafka_topic_name- The name of the Kafka topic to receive messageskafka_broker_list- The broker list for the Kafka instance. Format: host1:port1,host2:port2kafka_instance_storage_spec_code- The storage spec code of the DMS Kafka instancekafka_instance_engine_version- The engine version of the DMS Kafka instancekafka_instance_storage_space- The storage space of the DMS Kafka instance in GBkafka_instance_broker_num- The number of brokers for the DMS Kafka instancekafka_instance_user_name- The access user name for the DMS Kafka instancekafka_instance_user_password- The access user password for the DMS Kafka instance
Optional Variables
vpc_cidr- The CIDR block of the VPC (default: "192.168.0.0/16")subnet_cidr- The CIDR block of the subnet (default: "", auto-calculated if empty)subnet_gateway_ip- The gateway IP address of the subnet (default: "", auto-calculated if empty)availability_zones- The availability zones to which the instance belongs (default: [])
If not specified, will be automatically allocated based on the number of availability_zones_count
availability_zones_count- The number of availability zones to which the instance belongs (default: 1)instance_edition- The edition of the APIG instance (default: "BASIC")enterprise_project_id- The ID of the enterprise project (default: null)plugin_description- The description of the Kafka forward plugin (default: null)kafka_instance_description- The description of the DMS Kafka instance (default: "")kafka_instance_flavor_id- The flavor ID of the DMS Kafka instance (default: "", auto-selected if empty)kafka_instance_flavor_type- The flavor type of the DMS Kafka instance (default: "cluster")kafka_instance_ssl_enable- Whether to enable SSL for the DMS Kafka instance (default: false)kafka_charging_mode- The charging mode. Options: prePaid, postPaid (default: "prePaid")kafka_period_unit- The period unit. Options: month, year (default: "month")kafka_period- The period (default: 1)kafka_auto_new- Whether to enable auto renewal (default: "false")kafka_topic_partitions- The number of partitions for the Kafka topic (default: 1)kafka_message_key- The message key extraction strategy (default: ""). Can be a static value or a variable
expression like "$context.requestId"
kafka_max_retry_count- The maximum number of retry attempts for failed message sends (default: 3)kafka_retry_backoff- The backoff time in seconds between retries (default: 10)kafka_security_protocol- The security protocol for Kafka connection (default: "PLAINTEXT"). Options: PLAINTEXT,
SASL_PLAINTEXT, SASL_SSL, SSL
kafka_sasl_mechanisms- The SASL mechanism for authentication (default: "PLAIN"). Options: PLAIN, SCRAM-SHA-256,
SCRAM-SHA-512
kafka_sasl_username- The SASL username for authentication (default: "", uses kafka_access_user if empty and
security_protocol is not PLAINTEXT)
kafka_sasl_password- The SASL password for authentication (default: "", uses kafka_password if empty and
security_protocol is not PLAINTEXT)
kafka_ssl_ca_content- The SSL CA certificate content (default: "", sensitive)kafka_access_user- The access user for Kafka authentication (default: "", used when kafka_sasl_username is empty,
sensitive)
kafka_password- The password for Kafka authentication (default: "", used when kafka_sasl_password is empty,
sensitive)
Usage
- Copy this example script to your
main.tf.
- Create a
terraform.tfvarsfile and fill in the required variables. Example:
vpc_name = "your_vpc_name"
subnet_name = "your_subnet_name"
security_group_name = "your_security_group_name"
instance_name = "your_apig_instance_name"
plugin_name = "your_plugin_name"
kafka_instance_name = "your_kafka_instance_name"
kafka_topic_name = "your_kafka_topic_name"
kafka_broker_list = "broker1:9092,broker2:9092,broker3:9092"
kafka_instance_storage_spec_code = "dms.physical.storage.high.v2"
kafka_instance_engine_version = "2.7"
kafka_instance_storage_space = 600
kafka_instance_broker_num = 3
kafka_instance_user_name = "user"
kafka_instance_user_password = "YourPassword123"- Initialize Terraform:
terraform init- Review the Terraform plan:
terraform plan- Apply the configuration:
terraform apply- To clean up the resources:
terraform destroyNote
- Make sure to keep your credentials secure and never commit them to version control.
- All resources will be created in the specified region.
- The APIG instance is created with BASIC edition by default.
- The APIG instance will be deployed in the first available zone if
availability_zonesis not specified. - The Kafka instance flavor will be automatically selected if
kafka_instance_flavor_idis not provided. - The plugin type should be "kafka_log". Please verify the correct plugin type name in the APIG documentation or by
querying available plugin types before using this example.
- The plugin converts HTTP requests to Kafka messages in JSON format, including request metadata, body, and context
information.
- For authenticated Kafka connections, you can use
kafka_sasl_usernameandkafka_sasl_password, or leave them empty
to use kafka_access_user and kafka_password when security_protocol is not PLAINTEXT.
- Please be aware of API Gateway and DMS Kafka service quotas in your HuaweiCloud account.
Requirements
| Name | Version |
|---|---|
| terraform | >= 1.1.0 |
| huaweicloud | >= 1.77.7 |
# Network configuration
vpc_name = "tf_test_vpc"
subnet_name = "tf_test_subnet"
# Security group
security_group_name = "tf_test_security_group"
# APIG instance configuration
instance_name = "tf_test_apig_instance"
instance_edition = "BASIC"
enterprise_project_id = "0"
# Plugin configuration
plugin_name = "tf_test_kafka_forward_plugin"
plugin_description = "Kafka forward plugin created by Terraform script"
# Kafka instance configuration
kafka_instance_name = "tf_test_kafka_instance"
kafka_instance_description = "Kafka instance for testing"
kafka_instance_flavor_type = "cluster"
kafka_instance_storage_spec_code = "dms.physical.storage.high.v2"
kafka_instance_engine_version = "2.7"
kafka_instance_storage_space = 600
kafka_instance_broker_num = 3
kafka_instance_ssl_enable = false
kafka_instance_user_name = "user"
kafka_instance_user_password = "Kafkatest@123"
# Kafka charging configuration
kafka_charging_mode = "prePaid"
kafka_period_unit = "month"
kafka_period = 1
kafka_auto_new = "false"
# Kafka topic configuration
kafka_topic_name = "tf_test_kafka_topic"
kafka_topic_partitions = 1
# Kafka plugin configuration
kafka_message_key = "terraform-test" # Use request ID as message key
kafka_max_retry_count = 3
kafka_retry_backoff = 10
# Kafka security configuration
kafka_security_protocol = "PLAINTEXT" # Options: PLAINTEXT, SASL_PLAINTEXT, SASL_SSL, SSL
kafka_sasl_mechanisms = "PLAIN" # Options: PLAIN, SCRAM-SHA-256, SCRAM-SHA-512
kafka_access_user = "user"
kafka_password = "Kafkatest@123"
# Variable definitions for authentication
variable "region_name" {
description = "The name of the region"
type = string
}
variable "access_key" {
description = "The access key for the Huawei Cloud"
type = string
sensitive = true
}
variable "secret_key" {
description = "The secret key for the Huawei Cloud"
type = string
sensitive = true
}
# Variable definitions for resources/data sources
variable "vpc_name" {
description = "The name of the VPC"
type = string
}
variable "vpc_cidr" {
description = "The CIDR block of the VPC"
type = string
default = "192.168.0.0/16"
}
variable "subnet_name" {
description = "The name of the subnet"
type = string
}
variable "subnet_cidr" {
description = "The CIDR block of the subnet"
type = string
default = ""
nullable = false
}
variable "subnet_gateway_ip" {
description = "The gateway IP address of the subnet"
type = string
default = ""
nullable = false
}
variable "security_group_name" {
description = "The name of the security group"
type = string
}
variable "availability_zones" {
description = "The availability zones to which the instance belongs"
type = list(string)
default = []
nullable = false
}
variable "instance_name" {
description = "The name of the APIG instance"
type = string
}
variable "instance_edition" {
description = "The edition of the APIG instance"
type = string
default = "BASIC"
}
variable "enterprise_project_id" {
description = "The ID of the enterprise project"
type = string
default = null
}
variable "availability_zones_count" {
description = "The number of availability zones to which the instance belongs"
type = number
default = 1
}
variable "kafka_instance_flavor_id" {
description = "The flavor ID of the DMS Kafka instance"
type = string
default = ""
nullable = false
}
variable "kafka_instance_flavor_type" {
description = "The flavor type of the DMS Kafka instance"
type = string
default = "cluster"
}
variable "kafka_instance_storage_spec_code" {
description = "The storage spec code of the DMS Kafka instance"
type = string
default = "dms.physical.storage.high.v2"
}
variable "kafka_instance_name" {
description = "The name of the DMS Kafka instance"
type = string
}
variable "kafka_instance_description" {
description = "The description of the DMS Kafka instance"
type = string
default = ""
}
variable "kafka_instance_ssl_enable" {
description = "Whether to enable SSL for the DMS Kafka instance"
type = bool
default = false
}
variable "kafka_instance_engine_version" {
description = "The engine version of the DMS Kafka instance"
type = string
}
variable "kafka_instance_storage_space" {
description = "The storage space of the DMS Kafka instance in GB"
type = number
}
variable "kafka_instance_broker_num" {
description = "The number of brokers for the DMS Kafka instance"
type = number
}
variable "kafka_charging_mode" {
description = "The charging mode of the DMS Kafka instance. Options: prePaid, postPaid"
type = string
default = "prePaid"
}
variable "kafka_period_unit" {
description = "The period unit of the DMS Kafka instance. Options: month, year"
type = string
default = "month"
}
variable "kafka_period" {
description = "The period of the DMS Kafka instance"
type = number
default = 1
}
variable "kafka_auto_new" {
description = "Whether to enable auto renewal for the DMS Kafka instance"
type = string
default = "false"
}
variable "kafka_instance_user_name" {
description = "The access user name for the DMS Kafka instance"
type = string
sensitive = true
}
variable "kafka_instance_user_password" {
description = "The access user password for the DMS Kafka instance"
type = string
sensitive = true
}
variable "kafka_topic_name" {
description = "The name of the Kafka topic to receive messages"
type = string
}
variable "kafka_topic_partitions" {
description = "The number of partitions for the Kafka topic"
type = number
default = 1
}
variable "plugin_name" {
description = "The name of the Kafka forward plugin"
type = string
}
variable "plugin_description" {
description = "The description of the Kafka forward plugin"
type = string
default = null
}
variable "kafka_security_protocol" {
description = "The security protocol for Kafka connection. Options: PLAINTEXT, SASL_PLAINTEXT, SASL_SSL, SSL"
type = string
default = "PLAINTEXT"
nullable = false
validation {
condition = contains(["PLAINTEXT", "SASL_PLAINTEXT", "SASL_SSL", "SSL"], var.kafka_security_protocol)
error_message = "kafka_security_protocol must be one of: PLAINTEXT, SASL_PLAINTEXT, SASL_SSL, SSL."
}
}
variable "kafka_message_key" {
description = "The message key extraction strategy. Can be a static value or a variable expression like $context.requestId"
type = string
default = ""
}
variable "kafka_max_retry_count" {
description = "The maximum number of retry attempts for failed message sends"
type = number
default = 3
}
variable "kafka_retry_backoff" {
description = "The backoff time in seconds between retries"
type = number
default = 10
}
variable "kafka_sasl_mechanisms" {
description = "The SASL mechanism for authentication. Options: PLAIN, SCRAM-SHA-256, SCRAM-SHA-512"
type = string
default = "PLAIN"
validation {
condition = contains(["PLAIN", "SCRAM-SHA-256", "SCRAM-SHA-512"], var.kafka_sasl_mechanisms)
error_message = "kafka_sasl_mechanisms must be one of: PLAIN, SCRAM-SHA-256, SCRAM-SHA-512."
}
}
variable "kafka_sasl_username" {
description = "The SASL username for authentication (leave empty to use kafka_access_user)"
type = string
default = ""
sensitive = true
nullable = false
}
variable "kafka_access_user" {
description = "The access user for Kafka authentication (used when kafka_sasl_username is empty and security_protocol is not PLAINTEXT)"
type = string
default = ""
sensitive = true
nullable = false
}
variable "kafka_sasl_password" {
description = "The SASL password for authentication (leave empty to use kafka_password)"
type = string
default = ""
sensitive = true
nullable = false
}
variable "kafka_password" {
description = "The password for Kafka authentication (used when kafka_sasl_password is empty and security_protocol is not PLAINTEXT)"
type = string
default = ""
sensitive = true
nullable = false
}
variable "kafka_ssl_ca_content" {
description = "The SSL CA certificate content for SSL/TLS encrypted connections"
type = string
default = ""
sensitive = true
nullable = false
}
data "huaweicloud_availability_zones" "test" {
count = length(var.availability_zones) < var.availability_zones_count ? 1 : 0
}
resource "huaweicloud_vpc" "test" {
count = var.vpc_id == "" && var.subnet_id == "" ? 1 : 0
name = var.vpc_name
cidr = var.vpc_cidr
}
resource "huaweicloud_vpc_subnet" "test" {
count = var.subnet_id == "" ? 1 : 0
vpc_id = var.vpc_id != "" ? var.vpc_id : huaweicloud_vpc.test[0].id
name = var.subnet_name
cidr = var.subnet_cidr != "" ? var.subnet_cidr : cidrsubnet(huaweicloud_vpc.test[0].cidr, 4, 0)
gateway_ip = var.subnet_gateway_ip != "" ? var.subnet_gateway_ip : var.subnet_cidr != "" ? cidrhost(var.subnet_cidr, 1) : cidrhost(cidrsubnet(huaweicloud_vpc.test[0].cidr, 4, 0), 1)
availability_zone = length(var.availability_zones) > 0 ? try(var.availability_zones[0], null) : try(data.huaweicloud_availability_zones.test[0].names[0], null)
}
resource "huaweicloud_networking_secgroup" "test" {
name = var.security_group_name
delete_default_rules = true
}
resource "huaweicloud_apig_instance" "test" {
name = var.instance_name
edition = var.instance_edition
vpc_id = var.vpc_id != "" ? var.vpc_id : huaweicloud_vpc.test[0].id
subnet_id = var.subnet_id != "" ? var.subnet_id : huaweicloud_vpc_subnet.test[0].id
security_group_id = huaweicloud_networking_secgroup.test.id
availability_zones = length(var.availability_zones) < var.availability_zones_count ? concat(var.availability_zones, try(slice([for v in try(data.huaweicloud_availability_zones.test[0].names, []) : v if !contains(var.availability_zones, v)], 0, var.availability_zones_count - length(var.availability_zones)), [])) : var.availability_zones
enterprise_project_id = var.enterprise_project_id
lifecycle {
ignore_changes = [
availability_zones
]
}
}
resource "huaweicloud_apig_plugin" "test" {
instance_id = huaweicloud_apig_instance.test.id
name = var.plugin_name
type = "proxy_cache"
description = var.plugin_description
content = jsonencode({
cache_key = {
system_params = [],
parameters = [
"custom_param"
],
headers = []
},
cache_http_status_and_ttl = [
{
http_status = [
202,
203
],
ttl = 5
}
],
client_cache_control = {
mode = "off",
datas = []
},
cacheable_headers = [
"X-Custom-Header"
]
})
}
terraform {
required_version = ">= 1.9.0"
required_providers {
huaweicloud = {
source = "huaweicloud/huaweicloud"
version = ">= 1.50.0"
}
}
}
provider "huaweicloud" {
region = var.region_name
access_key = var.access_key
secret_key = var.secret_key
}
Create an APIG instance with proxy cache plugin
This example provides best practice code for using Terraform to create an API Gateway (APIG) instance with a proxy cache plugin in HuaweiCloud.
Prerequisites
- A HuaweiCloud account
- Terraform installed
- HuaweiCloud access key and secret key (AK/SK)
Variable Introduction
The following variables need to be configured:
Authentication Variables
region_name- The region where resources will be createdaccess_key- The access key of the IAM usersecret_key- The secret key of the IAM user
Resource Variables
Required Variables
security_group_name- The name of the security groupinstance_name- The name of the APIG instanceplugin_name- The name of the proxy cache plugin
Optional Variables
availability_zones- The availability zones to which the instance belongs (default: [])
If not specified, will be automatically allocated based on the number of availability_zones_count
availability_zones_count- The number of availability zones to which the instance belongs (default: 1)vpc_id- The ID of the VPC (required ifvpc_nameis not provided)subnet_id- The ID of the subnet (required ifsubnet_nameis not provided)vpc_name- The name of the VPC (required ifvpc_idis not provided)vpc_cidr- The CIDR block of the VPC (default: "192.168.0.0/16")subnet_name- The name of the subnet (required ifsubnet_idis not provided)subnet_cidr- The CIDR block of the subnet (default: "")subnet_gateway_ip- The gateway IP address of the subnet (default: "")instance_edition- The edition of the APIG instance (default: "BASIC")enterprise_project_id- The ID of the enterprise project, required for enterprise users (default: null)plugin_description- The description of the proxy cache plugin (default: null)
Notes
- Either
vpc_idorvpc_namemust be provided, but not both - Either
subnet_idorsubnet_namemust be provided, but not both
Usage
- Copy this example script to your
main.tf.
- Create a
terraform.tfvarsfile and fill in the required variables:
vpc_name = "your_vpc_name"
subnet_name = "your_subnet_name"
security_group_name = "your_security_group_name"
instance_name = "your_apig_instance_name"
plugin_name = "your_plugin_name"Or use existing VPC and subnet by providing their IDs:
vpc_id = "your_existing_vpc_id"
subnet_id = "your_existing_subnet_id"
security_group_name = "your_security_group_name"
instance_name = "your_apig_instance_name"
plugin_name = "your_plugin_name"- Initialize Terraform:
$ terraform init- Review the Terraform plan:
$ terraform plan- Apply the configuration:
$ terraform apply- To clean up the resources:
$ terraform destroyProxy Cache Plugin Configuration
The proxy cache plugin is configured with the following settings:
- Cache Key Configuration
- Custom parameter:
custom_param - No system parameters or headers used in cache key
- Cache HTTP Status and TTL
- HTTP status codes 202 and 203 are cached for 5 seconds
- Client Cache Control
- Mode: off
- Cacheable Headers
X-Custom-Header
Note
- Make sure to keep your credentials secure and never commit them to version control
- All resources will be created in the specified region
- The APIG instance is created with BASIC edition by default
- The APIG instance will be deployed in the first available zone if
availability_zonesis not specified - You can use existing VPC and subnet by providing
vpc_idandsubnet_idinstead of creating new ones - When using existing VPC/subnet, make sure they exist before running this example
Requirements
| Name | Version |
|---|---|
| terraform | >= 1.9.0 |
| huaweicloud | >= 1.49.0 |
vpc_name = "tf_test_vpc"
subnet_name = "tf_test_subnet"
security_group_name = "tf_test_security_group"
instance_name = "tf_test_instance"
enterprise_project_id = "0"
plugin_name = "tf_test_plugin"
plugin_description = "Created by Terraform script"
# Variable definitions for authentication
variable "region_name" {
description = "The region where resources will be created"
type = string
}
variable "access_key" {
description = "The access key of the IAM user"
type = string
sensitive = true
}
variable "secret_key" {
description = "The secret key of the IAM user"
type = string
sensitive = true
}
# Variable definitions for resources/data sources
variable "availability_zones" {
description = "The availability zones to which the instance belongs"
type = list(string)
default = []
nullable = false
}
variable "availability_zones_count" {
description = "The number of availability zones to which the instance belongs"
type = number
default = 1
}
variable "vpc_id" {
description = "The ID of the VPC"
type = string
default = ""
}
variable "subnet_id" {
description = "The ID of the subnet"
type = string
default = ""
}
variable "vpc_name" {
description = "The name of the VPC"
type = string
default = ""
validation {
condition = var.vpc_id != "" || var.vpc_name != ""
error_message = "vpc_name must be provided if vpc_id is not provided."
}
}
variable "vpc_cidr" {
description = "The CIDR block of the VPC"
type = string
default = "192.168.0.0/16"
}
variable "subnet_name" {
description = "The name of the subnet"
type = string
default = ""
validation {
condition = var.subnet_id == "" || var.subnet_name == ""
error_message = "subnet_name must be provided if subnet_id is not provided."
}
}
variable "subnet_cidr" {
description = "The CIDR block of the subnet"
type = string
default = ""
}
variable "subnet_gateway_ip" {
description = "The gateway IP address of the subnet"
type = string
default = ""
}
variable "security_group_name" {
description = "The name of the security group"
type = string
}
variable "instance_name" {
description = "The name of the APIG instance"
type = string
}
variable "instance_edition" {
description = "The edition of the APIG instance"
type = string
default = "BASIC"
}
variable "enterprise_project_id" {
description = "The ID of the enterprise project"
type = string
default = null
}
variable "plugin_name" {
description = "The name of the APIG plugin"
type = string
}
variable "plugin_description" {
description = "The description of the APIG plugin"
type = string
default = null
}
data "huaweicloud_availability_zones" "test" {}
data "huaweicloud_compute_flavors" "test" {
count = var.instance_flavor_id == "" ? 1 : 0
availability_zone = try(data.huaweicloud_availability_zones.test.names[0], null)
performance_type = var.instance_flavor_performance_type
cpu_core_count = var.instance_flavor_cpu_core_count
memory_size = var.instance_flavor_memory_size
}
data "huaweicloud_images_images" "test" {
count = var.instance_image_id == "" ? 1 : 0
flavor_id = var.instance_flavor_id != "" ? var.instance_flavor_id : try(data.huaweicloud_compute_flavors.test[0].ids[0], null)
visibility = "public"
os = "Ubuntu"
}
resource "huaweicloud_vpc" "test" {
name = var.vpc_name
cidr = var.vpc_cidr
}
resource "huaweicloud_vpc_subnet" "test" {
vpc_id = huaweicloud_vpc.test.id
name = var.subnet_name
cidr = var.subnet_cidr != "" ? var.subnet_cidr : cidrsubnet(huaweicloud_vpc.test.cidr, 8, 0)
gateway_ip = var.subnet_gateway_ip != "" ? var.subnet_gateway_ip : cidrhost(cidrsubnet(huaweicloud_vpc.test.cidr, 8, 0), 1)
}
resource "huaweicloud_networking_secgroup" "test" {
name = var.security_group_name
delete_default_rules = true
}
resource "huaweicloud_kps_keypair" "test" {
name = var.keypair_name
public_key = var.keypair_public_key != "" ? var.keypair_public_key : null
}
resource "huaweicloud_as_configuration" "test" {
scaling_configuration_name = var.configuration_name
instance_config {
image = var.instance_image_id != "" ? var.instance_image_id : try(data.huaweicloud_images_images.test[0].images[0].id, null)
flavor = var.instance_flavor_id != "" ? var.instance_flavor_id : try(data.huaweicloud_compute_flavors.test[0].flavors[0].id, null)
key_name = huaweicloud_kps_keypair.test.id
dynamic "disk" {
for_each = var.disk_configurations
content {
disk_type = disk.value.disk_type
volume_type = disk.value.volume_type
size = disk.value.volume_size
}
}
}
}
resource "huaweicloud_as_group" "test" {
scaling_configuration_id = huaweicloud_as_configuration.test.id
vpc_id = huaweicloud_vpc.test.id
scaling_group_name = var.group_name
desire_instance_number = var.desire_instance_number
min_instance_number = var.min_instance_number
max_instance_number = var.max_instance_number
delete_publicip = var.is_delete_publicip
delete_instances = var.is_delete_instances ? "yes" : "no"
networks {
id = huaweicloud_vpc_subnet.test.id
}
security_groups {
id = huaweicloud_networking_secgroup.test.id
}
}
resource "huaweicloud_smn_topic" "test" {
name = var.topic_name
}
resource "huaweicloud_ces_alarmrule" "test" {
alarm_name = var.alarm_rule_name
metric {
namespace = "SYS.AS"
}
resources {
dimensions {
name = "AutoScalingGroup"
value = huaweicloud_as_group.test.id
}
}
dynamic "condition" {
for_each = var.rule_conditions
content {
alarm_level = condition.value.alarm_level
metric_name = condition.value.metric_name
period = condition.value.period
filter = condition.value.filter
comparison_operator = condition.value.comparison_operator
suppress_duration = condition.value.suppress_duration
value = condition.value.value
count = condition.value.count
}
}
alarm_actions {
type = "autoscaling"
notification_list = [huaweicloud_smn_topic.test.id]
}
}
# ST.001 Disable
resource "huaweicloud_as_policy" "scaling_up" {
scaling_policy_name = var.scaling_up_policy_name
scaling_policy_type = "ALARM"
scaling_group_id = huaweicloud_as_group.test.id
alarm_id = huaweicloud_ces_alarmrule.test.id
cool_down_time = var.scaling_up_cool_down_time
scaling_policy_action {
operation = "ADD"
instance_number = var.scaling_up_instance_number
}
}
resource "huaweicloud_as_policy" "scaling_down" {
scaling_policy_name = var.scaling_down_policy_name
scaling_policy_type = "ALARM"
scaling_group_id = huaweicloud_as_group.test.id
alarm_id = huaweicloud_ces_alarmrule.test.id
cool_down_time = var.scaling_down_cool_down_time
scaling_policy_action {
operation = "REMOVE"
instance_number = var.scaling_down_instance_number
}
}
# ST.001 Enable
terraform {
required_version = ">= 1.9.0"
required_providers {
huaweicloud = {
source = "huaweicloud/huaweicloud"
version = ">= 1.50.0"
}
}
}
provider "huaweicloud" {
region = var.region_name
access_key = var.access_key
secret_key = var.secret_key
}
Create an AS Alarm Policy
This example provides best practice code for using Terraform to create an Auto Scaling (AS) alarm policy in HuaweiCloud. The example demonstrates how to set up a complete AS environment with alarm-based scaling policies.
Prerequisites
- A HuaweiCloud account
- Terraform installed
- HuaweiCloud access key and secret key (AK/SK)
- AS service enabled in the target region
- CES service enabled in the target region
- SMN service enabled in the target region
- VPC service enabled in the target region
- ECS service enabled in the target region
Variable Introduction
The following variables need to be configured:
Authentication Variables
region_name- The region where the resources are locatedaccess_key- The access key of the IAM usersecret_key- The secret key of the IAM user
Resource Variables
Required Variables
vpc_name- The name of the VPCsubnet_name- The name of the subnetsecurity_group_name- The name of the security groupkeypair_name- The name of the key pair that is used to access the AS instanceconfiguration_name- The name of the AS configurationdisk_configurations- The disk configurations for the AS instance (must include exactly one system disk)disk_type- The type of the disk (SYS for system disk, DATA for data disk)volume_type- The type of the volume (SSD, SATA, SAS)volume_size- The size of the volume in GBgroup_name- The name of the AS grouptopic_name- The name of the SMN topicalarm_rule_name- The name of the CES alarm rulerule_conditions- The conditions of the alarm rulealarm_level- The alarm level (1-4, default: 2)metric_name- The name of the metric to monitorperiod- The period for collecting the metric data in secondsfilter- The data aggregation method (average, max, min, sum)comparison_operator- The comparison operator (>, <, >=, <=, =)suppress_duration- The suppression duration in seconds (default: 0)value- The threshold value for the alarmcount- The number of consecutive periods that the condition must be metscaling_up_policy_name- The name of the scaling up policyscaling_down_policy_name- The name of the scaling down policy
Optional Variables
instance_flavor_id- The flavor ID of the AS instance (default: "")instance_flavor_performance_type- The performance type of the AS instance flavor (default: "normal")instance_flavor_cpu_core_count- The CPU core count of the AS instance flavor (default: 2)instance_flavor_memory_size- The memory size of the AS instance flavor (default: 4)instance_image_id- The image ID of the AS instance (default: "")vpc_cidr- The CIDR block of the VPC (default: "192.168.0.0/16")subnet_cidr- The CIDR block of the subnet (default: "")subnet_gateway_ip- The gateway IP of the subnet (default: "")keypair_public_key- The public key of the key pair (default: "")desire_instance_number- The desired number of scaling instances in the AS group (default: 2)min_instance_number- The minimum number of scaling instances in the AS group (default: 0)max_instance_number- The maximum number of scaling instances in the AS group (default: 10)is_delete_publicip- Whether to delete the public IP address when the AS group is deleted (default: true)is_delete_instances- Whether to delete the scaling instances when the AS group is deleted (default: true)scaling_up_cool_down_time- The cool down time of the scaling up policy (default: 300)scaling_up_instance_number- The number of instances to add when scaling up (default: 1)scaling_down_cool_down_time- The cool down time of the scaling down policy (default: 300)scaling_down_instance_number- The number of instances to remove when scaling down (default: 1)
Usage
- Copy this example script to your
main.tf.
- Create a
terraform.tfvarsfile and fill in the required variables:
vpc_name = "tf_test_vpc"
subnet_name = "tf_test_subnet"
security_group_name = "tf_test_security_group"
keypair_name = "tf_test_keypair"
configuration_name = "tf_test_configuration"
disk_configurations = [
{
disk_type = "SYS"
volume_type = "SSD"
volume_size = 40
}
]
group_name = "tf_test_group"
topic_name = "tf_test_topic"
alarm_rule_name = "tf_test_alarm_rule"
rule_conditions = [
{
metric_name = "cpu_util"
period = 300
filter = "average"
comparison_operator = ">"
value = 80
count = 1
}
]
scaling_up_policy_name = "tf_test_scaling_up_policy"
scaling_down_policy_name = "tf_test_scaling_down_policy"- Initialize Terraform:
$ terraform init- Review the Terraform plan:
$ terraform plan- Apply the configuration:
$ terraform apply- To clean up the resources:
$ terraform destroyArchitecture
This example creates the following resources:
1. VPC and Subnet - Network infrastructure for the AS group 2. Security Group - Security rules for the instances 3. Key Pair - SSH key for instance access 4. AS Configuration - Instance configuration template 5. AS Group - Auto Scaling group with desired, min, and max instance counts 6. SMN Topic - Notification topic for alarm actions 7. CES Alarm Rule - Cloud monitoring alarm rule based on CPU utilization 8. AS Policies - Scaling up and scaling down policies triggered by alarms
Notes
- Make sure to keep your credentials secure and never commit them to version control
- The AS group is dependent on the VPC, subnet, security group, and AS configuration
- The alarm rule monitors CPU utilization and triggers scaling policies
- Scaling policies are configured to add/remove instances based on alarm conditions
- The example uses Ubuntu public images by default, but you can specify custom images
- Disk configurations must include exactly one system disk (disk_type = "SYS")
Requirements
| Name | Version |
|---|---|
| terraform | >= 1.9.0 |
| huaweicloud | >= 1.57.0 |
vpc_name = "tf_test_vpc"
subnet_name = "tf_test_subnet"
security_group_name = "tf_test_security_group"
keypair_name = "tf_test_keypair"
configuration_name = "tf_test_configuration"
disk_configurations = [
{
disk_type = "SYS"
volume_type = "SSD"
volume_size = 40
}
]
group_name = "tf_test_group"
topic_name = "tf_test_topic"
alarm_rule_name = "tf_test_alarm_rule"
rule_conditions = [
{
metric_name = "cpu_util"
period = 300
filter = "average"
comparison_operator = ">"
value = 80
count = 1
}
]
scaling_up_policy_name = "tf_test_scaling_up_policy"
scaling_down_policy_name = "tf_test_scaling_down_policy"
# Variables definitions for authorization
variable "region_name" {
description = "The region where the resources are located"
type = string
}
variable "access_key" {
description = "The access key of the IAM user"
type = string
sensitive = true
}
variable "secret_key" {
description = "The secret key of the IAM user"
type = string
sensitive = true
}
# Variables definitions for resource/data source
variable "instance_flavor_id" {
description = "The flavor ID of the AS instance"
type = string
default = ""
}
variable "instance_flavor_performance_type" {
description = "The performance type of the AS instance flavor"
type = string
default = "normal"
}
variable "instance_flavor_cpu_core_count" {
description = "The CPU core count of the AS instance flavor"
type = number
default = 2
}
variable "instance_flavor_memory_size" {
description = "The memory size of the AS instance flavor"
type = number
default = 4
}
variable "instance_image_id" {
description = "The image ID of the AS instance"
type = string
default = ""
}
variable "vpc_name" {
description = "The name of the VPC"
type = string
}
variable "vpc_cidr" {
description = "The CIDR block of the VPC"
type = string
default = "192.168.0.0/16"
}
variable "subnet_name" {
description = "The name of the subnet"
type = string
}
variable "subnet_cidr" {
description = "The CIDR block of the subnet"
type = string
default = ""
}
variable "subnet_gateway_ip" {
description = "The gateway IP of the subnet"
type = string
default = ""
validation {
condition = (var.subnet_cidr != "" && var.subnet_gateway_ip != "") || (var.subnet_cidr == "" && var.subnet_gateway_ip == "")
error_message = "The 'subnet_cidr' and 'subnet_gateway_ip' is not allowed for only one of them to be empty"
}
}
variable "security_group_name" {
description = "The name of the security group"
type = string
}
variable "keypair_name" {
description = "The name of the key pair that is used to access the AS instance"
type = string
}
variable "keypair_public_key" {
description = "The public key of the key pair that is used to access the AS instance"
type = string
default = ""
}
variable "configuration_name" {
description = "The name of the AS configuration"
type = string
}
variable "disk_configurations" {
description = "The disk configurations for the AS instance"
type = list(object({
disk_type = string
volume_type = string
volume_size = number
}))
nullable = false
validation {
condition = length(var.disk_configurations) > 0 && length([for v in var.disk_configurations : v if v.disk_type == "SYS"]) == 1
error_message = "The 'disk_configurations' is not allowed to be empty and only one system disk is allowed"
}
}
variable "group_name" {
description = "The name of the AS group"
type = string
}
variable "desire_instance_number" {
description = "The desired number of scaling instances in the AS group"
type = number
default = 2
}
variable "min_instance_number" {
description = "The minimum number of scaling instances in the AS group"
type = number
default = 0
}
variable "max_instance_number" {
description = "The maximum number of scaling instances in the AS group"
type = number
default = 10
}
variable "is_delete_publicip" {
description = "Whether to delete the public IP address of the scaling instances when the AS group is deleted"
type = bool
default = true
}
variable "is_delete_instances" {
description = "Whether to delete the scaling instances when the AS group is deleted"
type = bool
default = true
}
variable "topic_name" {
description = "The name of the SMN topic"
type = string
}
variable "alarm_rule_name" {
description = "The name of the CES alarm rule"
type = string
}
variable "rule_conditions" {
description = "The conditions of the alarm rule"
type = list(object({
alarm_level = optional(number, 2)
metric_name = string
period = number
filter = string
comparison_operator = string
suppress_duration = optional(number, 0)
value = number
count = number
}))
nullable = false
validation {
condition = length(var.rule_conditions) > 0
error_message = "The 'rule_conditions' is not allowed to be empty"
}
}
variable "scaling_up_policy_name" {
description = "The name of the scaling up policy"
type = string
}
variable "scaling_up_cool_down_time" {
description = "The cool down time of the scaling up policy"
type = number
default = 300
}
variable "scaling_up_instance_number" {
description = "The number of instances to add when the scaling up policy is triggered"
type = number
default = 1
}
variable "scaling_down_policy_name" {
description = "The name of the scaling down policy"
type = string
}
variable "scaling_down_cool_down_time" {
description = "The cool down time of the scaling down policy"
type = number
default = 300
}
variable "scaling_down_instance_number" {
description = "The number of instances to remove when the scaling down policy is triggered"
type = number
default = 1
}
data "huaweicloud_availability_zones" "test" {
count = var.availability_zone == "" ? 1 : 0
}
data "huaweicloud_compute_flavors" "test" {
count = var.configuration_flavor_id == "" ? 1 : 0
availability_zone = var.availability_zone == "" ? try(data.huaweicloud_availability_zones.test[0].names[0], null) : var.availability_zone
performance_type = var.configuration_flavor_performance_type
cpu_core_count = var.configuration_flavor_cpu_core_count
memory_size = var.configuration_flavor_memory_size
}
data "huaweicloud_images_images" "test" {
count = var.configuration_image_id == "" ? 1 : 0
flavor_id = var.configuration_flavor_id == "" ? try(data.huaweicloud_compute_flavors.test[0].flavors[0].id, null) : var.configuration_flavor_id
visibility = var.configuration_image_visibility
os = var.configuration_image_os
}
resource "huaweicloud_networking_secgroup" "test" {
name = var.security_group_name
delete_default_rules = true
}
resource "huaweicloud_kps_keypair" "test" {
name = var.keypair_name
public_key = var.keypair_public_key != "" ? var.keypair_public_key : null
}
resource "huaweicloud_as_configuration" "test" {
scaling_configuration_name = var.configuration_name
instance_config {
image = var.configuration_image_id == "" ? try(data.huaweicloud_images_images.test[0].images[0].id, null) : var.configuration_image_id
flavor = var.configuration_flavor_id == "" ? try(data.huaweicloud_compute_flavors.test[0].flavors[0].id, null) : var.configuration_flavor_id
key_name = huaweicloud_kps_keypair.test.id
security_group_ids = [huaweicloud_networking_secgroup.test.id]
metadata = var.configuration_metadata
user_data = var.configuration_user_data
dynamic "disk" {
for_each = var.configuration_disks
content {
size = disk.value["size"]
volume_type = disk.value["volume_type"]
disk_type = disk.value["disk_type"]
}
}
dynamic "public_ip" {
for_each = var.configuration_public_eip_settings
content {
eip {
ip_type = public_ip.value.ip_type
bandwidth {
size = public_ip.value.bandwidth.size
share_type = public_ip.value.bandwidth.share_type
charging_mode = public_ip.value.bandwidth.charging_mode
}
}
}
}
}
}
terraform {
required_version = ">= 1.9.0"
required_providers {
huaweicloud = {
source = "huaweicloud/huaweicloud"
version = ">= 1.50.0"
}
}
}
provider "huaweicloud" {
region = var.region_name
access_key = var.access_key
secret_key = var.secret_key
}
security_group_name = "tf_test_secgroup_demo"
keypair_name = "tf_test_keypair_demo"
configuration_name = "tf_test_as_configuration"
configuration_metadata = {
some_key = "some_value"
}
configuration_user_data = <<EOT
# !/bin/sh
echo "Hello World! The time is now $(date -R)!" | tee /root/output.txt
EOT
configuration_disks = [
{
size = 40
volume_type = "SSD"
disk_type = "SYS"
}
]
configuration_public_eip_settings = [
{
ip_type = "5_bgp"
bandwidth = {
size = 10
share_type = "PER"
charging_mode = "traffic"
}
}
]
terraform {
required_version = ">= 1.9.0"
required_providers {
huaweicloud = {
source = "huaweicloud/huaweicloud"
version = ">= 1.50.0"
}
}
}
provider "huaweicloud" {
region = var.region_name
access_key = var.access_key
secret_key = var.secret_key
}
security_group_name = "tf_test_secgroup_demo"
keypair_name = "tf_test_keypair_demo"
configuration_name = "tf_test_as_configuration"
configuration_metadata = {
some_key = "some_value"
}
configuration_user_data = <<EOT
# !/bin/sh
echo "Hello World! The time is now $(date -R)!" | tee /root/output.txt
EOT
configuration_disks = [
{
size = 40
volume_type = "SSD"
disk_type = "SYS"
}
]
configuration_public_eip_settings = [
{
ip_type = "5_bgp"
bandwidth = {
size = 10
share_type = "PER"
charging_mode = "traffic"
}
}
]
scaling_group_vpc_name = "tf_test_vpc_demo"
scaling_group_subnet_name = "tf_test_subnet_demo"
scaling_group_name = "tf_test_scaling_group_demo"
terraform {
required_version = ">= 1.9.0"
required_providers {
huaweicloud = {
source = "huaweicloud/huaweicloud"
version = ">= 1.50.0"
}
}
}
provider "huaweicloud" {
region = var.region_name
access_key = var.access_key
secret_key = var.secret_key
}
vpc_name = "tf_test_bms_vpc"
subnet_name = "tf_test_bms_subnet"
security_group_name = "tf_test_bms_security_group"
keypair_name = "tf_test_kps_keypair"
instance_name = "tf_test_bms_instance"
instance_user_id = "your_user_id"
enterprise_project_id = "0"
instance_tags = {
owner = "terraform"
}
resource "huaweicloud_bms_instance_password_reset" "test" {
server_id = var.bms_instance_id
new_password = var.bms_instance_new_password
}
terraform {
required_version = ">= 1.9.0"
required_providers {
huaweicloud = {
source = "huaweicloud/huaweicloud"
# SC.004 Disable
version = ">=1.82.5"
# SC.004 Enable
}
}
}
provider "huaweicloud" {
region = var.region_name
access_key = var.access_key
secret_key = var.secret_key
}
bms_instance_id = "your_bms_instance_id"
bms_instance_new_password = "your_new_password"
resource "huaweicloud_bms_volume_attach" "test" {
server_id = var.server_id
volume_id = var.volume_id
device = var.device
}
terraform {
required_version = ">= 1.9.0"
required_providers {
huaweicloud = {
source = "huaweicloud/huaweicloud"
version = ">= 1.50.0"
}
}
}
provider "huaweicloud" {
region = var.region_name
access_key = var.access_key
secret_key = var.secret_key
}
server_id = "your_bms_server_id"
volume_id = "your_evs_volume_id"
device = "/dev/sdb"