# Deploy Event Subscription (OBS Event Source, Kafka Event Target)

## Application Scenario

Huawei Cloud EventGrid (EG) event subscription functionality supports automatically routing events generated by OBS (Object Storage Service) to Kafka message queues, implementing event-driven architectures between cloud services. Through this integration approach, you can build real-time data processing pipelines, pushing OBS storage operation events (such as object creation, deletion, modification, etc.) to Kafka clusters in real-time for downstream consumers to process and analyze in real-time.

This best practice is particularly suitable for scenarios requiring real-time monitoring of OBS storage operations, building data lake event-driven architectures, implementing storage event and message queue integration, such as data backup monitoring, file processing workflows, real-time data analysis, etc. This best practice will introduce how to use Terraform to automatically deploy a complete event subscription configuration from OBS event source to Kafka event target, including VPC network, OBS storage bucket, Kafka instance, EG connection, and event subscription creation.

## Related Resources/Data Sources

This best practice involves the following main resources and data sources:

### Data Sources

- [Availability Zones Query Data Source (data.huaweicloud\_availability\_zones)](https://registry.terraform.io/providers/huaweicloud/huaweicloud/latest/docs/data-sources/availability_zones)
- [DMS Kafka Flavors Query Data Source (data.huaweicloud\_dms\_kafka\_flavors)](https://registry.terraform.io/providers/huaweicloud/huaweicloud/latest/docs/data-sources/dms_kafka_flavors)
- [EventGrid Event Channels Query Data Source (data.huaweicloud\_eg\_event\_channels)](https://registry.terraform.io/providers/huaweicloud/huaweicloud/latest/docs/data-sources/eg_event_channels)

### Resources

- [VPC Resource (huaweicloud\_vpc)](https://registry.terraform.io/providers/huaweicloud/huaweicloud/latest/docs/resources/vpc)
- [VPC Subnet Resource (huaweicloud\_vpc\_subnet)](https://registry.terraform.io/providers/huaweicloud/huaweicloud/latest/docs/resources/vpc_subnet)
- [Security Group Resource (huaweicloud\_networking\_secgroup)](https://registry.terraform.io/providers/huaweicloud/huaweicloud/latest/docs/resources/networking_secgroup)
- [OBS Bucket Resource (huaweicloud\_obs\_bucket)](https://registry.terraform.io/providers/huaweicloud/huaweicloud/latest/docs/resources/obs_bucket)
- [DMS Kafka Instance Resource (huaweicloud\_dms\_kafka\_instance)](https://registry.terraform.io/providers/huaweicloud/huaweicloud/latest/docs/resources/dms_kafka_instance)
- [DMS Kafka Topic Resource (huaweicloud\_dms\_kafka\_topic)](https://registry.terraform.io/providers/huaweicloud/huaweicloud/latest/docs/resources/dms_kafka_topic)
- [EventGrid Connection Resource (huaweicloud\_eg\_connection)](https://registry.terraform.io/providers/huaweicloud/huaweicloud/latest/docs/resources/eg_connection)
- [Event Subscription Resource (huaweicloud\_eg\_event\_subscription)](https://registry.terraform.io/providers/huaweicloud/huaweicloud/latest/docs/resources/eg_event_subscription)
- [OBS Object Resource (huaweicloud\_obs\_bucket\_object)](https://registry.terraform.io/providers/huaweicloud/huaweicloud/latest/docs/resources/obs_bucket_object)
- [Time Sleep Resource (time\_sleep)](https://registry.terraform.io/providers/hashicorp/time/latest/docs/resources/sleep)

### Resource/Data Source Dependencies

```
data.huaweicloud_availability_zones
    └── huaweicloud_dms_kafka_instance

data.huaweicloud_dms_kafka_flavors
    └── huaweicloud_dms_kafka_instance

huaweicloud_vpc
    ├── huaweicloud_vpc_subnet
    ├── huaweicloud_dms_kafka_instance
    └── huaweicloud_eg_connection

huaweicloud_vpc_subnet
    ├── huaweicloud_dms_kafka_instance
    └── huaweicloud_eg_connection

huaweicloud_networking_secgroup
    └── huaweicloud_dms_kafka_instance

huaweicloud_dms_kafka_instance
    ├── huaweicloud_dms_kafka_topic
    └── huaweicloud_eg_connection

huaweicloud_dms_kafka_topic
    └── huaweicloud_eg_connection

huaweicloud_eg_connection
    └── time_sleep
        └── huaweicloud_eg_event_subscription

data.huaweicloud_eg_event_channels
    └── huaweicloud_eg_event_subscription

huaweicloud_obs_bucket
    └── huaweicloud_obs_bucket_object
```

## Operation Steps

### 1. Script Preparation

Prepare the TF file (e.g., main.tf) in the specified workspace for writing the current best practice script, ensuring that it (or other TF files in the same directory) contains the provider version declaration and Huawei Cloud authentication information required for deploying resources. Refer to the "Preparation Before Deploying Huawei Cloud Resources" document for configuration introduction.

### 2. Create VPC Network

Add the following script to the TF file (e.g., main.tf) to instruct Terraform to create a VPC resource:

```hcl
# Variable definitions for VPC
variable "vpc_name" {
  description = "The name of the VPC"
  type        = string
}

variable "vpc_cidr" {
  description = "The CIDR block of the VPC"
  type        = string
  default     = "172.16.0.0/16"
}

# Create a VPC resource under the specified region (if the region parameter is omitted, it defaults to the region specified in the current provider block)
resource "huaweicloud_vpc" "test" {
  name = var.vpc_name
  cidr = var.vpc_cidr
}
```

**Parameter Description**:

- **name**: VPC name, assigned by referencing the input variable vpc\_name
- **cidr**: VPC CIDR block, assigned by referencing the input variable vpc\_cidr, default value is "172.16.0.0/16"

### 3. Create VPC Subnet

Add the following script to the TF file to instruct Terraform to create a VPC subnet resource:

```hcl
# Variable definitions for subnet
variable "subnet_name" {
  description = "The name of the subnet"
  type        = string
}

variable "subnet_cidr" {
  description = "The CIDR block of the subnet"
  type        = string
  default     = "172.16.10.0/24"
}

variable "subnet_gateway" {
  description = "The gateway IP address of the subnet"
  type        = string
  default     = "172.16.10.1"
}

# Create a VPC subnet resource under the specified region (if the region parameter is omitted, it defaults to the region specified in the current provider block)
resource "huaweicloud_vpc_subnet" "test" {
  vpc_id     = huaweicloud_vpc.test.id
  name       = var.subnet_name
  cidr       = var.subnet_cidr
  gateway_ip = var.subnet_gateway
}
```

**Parameter Description**:

- **vpc\_id**: VPC ID that the subnet belongs to, referencing the ID of the VPC resource created earlier
- **name**: Subnet name, assigned by referencing the input variable subnet\_name
- **cidr**: Subnet CIDR block, assigned by referencing the input variable subnet\_cidr, default value is "172.16.10.0/24"
- **gateway\_ip**: Subnet gateway IP address, assigned by referencing the input variable subnet\_gateway, default value is "172.16.10.1"

### 4. Create Security Group

Add the following script to the TF file to instruct Terraform to create a security group resource:

```hcl
# Variable definitions for security group
variable "security_group_name" {
  description = "The name of the security group"
  type        = string
}

# Create a security group resource under the specified region (if the region parameter is omitted, it defaults to the region specified in the current provider block)
resource "huaweicloud_networking_secgroup" "test" {
  name = var.security_group_name
}
```

**Parameter Description**:

- **name**: Security group name, assigned by referencing the input variable security\_group\_name

### 5. Create OBS Bucket

Add the following script to the TF file to instruct Terraform to create an OBS bucket resource:

```hcl
# Variable definitions for OBS bucket
variable "bucket_name" {
  description = "The name of the OBS bucket"
  type        = string
}

variable "bucket_acl" {
  description = "The ACL policy for a bucket"
  type        = string
  default     = "private"
}

# Create an OBS bucket resource under the specified region (if the region parameter is omitted, it defaults to the region specified in the current provider block)
resource "huaweicloud_obs_bucket" "test" {
  bucket        = var.bucket_name
  acl           = var.bucket_acl
  force_destroy = true
}
```

**Parameter Description**:

- **bucket**: OBS bucket name, assigned by referencing the input variable bucket\_name
- **acl**: Bucket ACL policy, assigned by referencing the input variable bucket\_acl, default value is "private"
- **force\_destroy**: Whether to force delete the bucket, set to true to allow deletion of non-empty buckets

### 6. Query Availability Zone Information

Add the following script to the TF file to instruct Terraform to query availability zone information:

```hcl
# Variable definitions for availability zones
variable "availability_zones" {
  description = "The availability zones to which the Kafka instance belongs"
  type        = list(string)
  default     = []
}

# Get all available availability zone information under the specified region (if the region parameter is omitted, it defaults to the region specified in the current provider block), used to create Kafka instances
data "huaweicloud_availability_zones" "test" {
  count = length(var.availability_zones) == 0 ? 1 : 0
}
```

**Parameter Description**:

- **count**: Conditional creation, creates this data source when availability\_zones variable is an empty list

### 7. Query DMS Kafka Flavor Information

Add the following script to the TF file to instruct Terraform to query DMS Kafka flavor information:

```hcl
# Variable definitions for Kafka flavors
variable "instance_flavor_id" {
  description = "The flavor ID of the Kafka instance"
  type        = string
  default     = "kafka.2u4g.cluster.small"
}

variable "instance_flavor_type" {
  description = "The flavor type of the Kafka instance"
  type        = string
  default     = "cluster"
}

variable "instance_storage_spec_code" {
  description = "The storage specification code of the Kafka instance"
  type        = string
  default     = "dms.physical.storage.high.v2"
}

# Get all DMS Kafka flavor information that meets specific conditions under the specified region (if the region parameter is omitted, it defaults to the region specified in the current provider block), used to create Kafka instances
data "huaweicloud_dms_kafka_flavors" "test" {
  count = var.instance_flavor_id == "" ? 1 : 0

  type               = var.instance_flavor_type
  availability_zones = length(var.availability_zones) == 0 ? try(slice(data.huaweicloud_availability_zones.test[0].names, 0, 3)) : var.availability_zones
  storage_spec_code  = var.instance_storage_spec_code
}
```

**Parameter Description**:

- **count**: Conditional creation, creates this data source when instance\_flavor\_id variable is an empty string
- **type**: Flavor type, assigned by referencing the input variable instance\_flavor\_type, default value is "cluster"
- **availability\_zones**: Availability zone list, prioritizes using availability\_zones variable, uses queried availability zones if empty
- **storage\_spec\_code**: Storage specification code, assigned by referencing the input variable instance\_storage\_spec\_code, default value is "dms.physical.storage.high.v2"

### 8. Create DMS Kafka Instance

Add the following script to the TF file to instruct Terraform to create a DMS Kafka instance resource:

```hcl
# Variable definitions for Kafka instance
variable "instance_name" {
  description = "The name of the Kafka instance"
  type        = string
}

variable "instance_engine_version" {
  description = "The engine version of the Kafka instance"
  type        = string
  default     = "3.x"
}

variable "instance_storage_space" {
  description = "The storage space of the Kafka instance"
  type        = number
  default     = 300
}

variable "instance_broker_num" {
  description = "The number of brokers of the Kafka instance"
  type        = number
  default     = 3
}

variable "instance_ssl_enable" {
  description = "The SSL enable of the Kafka instance"
  type        = bool
  default     = false
}

variable "instance_description" {
  description = "The description of the Kafka instance"
  type        = string
  default     = ""
}

variable "instance_security_protocol" {
  description = "The protocol to use after SASL is enabled"
  type        = string
  default     = "SASL_SSL"
}

variable "charging_mode" {
  description = "The charging mode of the Kafka instance"
  type        = string
  default     = "postPaid"
}

# Create a DMS Kafka instance resource under the specified region (if the region parameter is omitted, it defaults to the region specified in the current provider block)
resource "huaweicloud_dms_kafka_instance" "test" {
  name               = var.instance_name
  availability_zones = length(var.availability_zones) == 0 ? try(slice(data.huaweicloud_availability_zones.test[0].names, 0, 3)) : var.availability_zones
  engine_version     = var.instance_engine_version
  flavor_id          = var.instance_flavor_id == "" ? try(data.huaweicloud_dms_kafka_flavors.test[0].flavors[0].id, null) : var.instance_flavor_id
  storage_spec_code  = var.instance_storage_spec_code
  storage_space      = var.instance_storage_space
  broker_num         = var.instance_broker_num
  vpc_id             = huaweicloud_vpc.test.id
  network_id         = huaweicloud_vpc_subnet.test.id
  security_group_id  = huaweicloud_networking_secgroup.test.id
  ssl_enable         = var.instance_ssl_enable
  description        = var.instance_description
  security_protocol  = var.instance_security_protocol
  charging_mode      = var.charging_mode

  lifecycle {
    ignore_changes = [
      availability_zones,
      flavor_id,
    ]
  }
}
```

**Parameter Description**:

- **name**: Kafka instance name, assigned by referencing the input variable instance\_name
- **availability\_zones**: Availability zone list that the instance belongs to, prioritizes using availability\_zones variable, uses queried availability zones if empty
- **engine\_version**: Kafka engine version, assigned by referencing the input variable instance\_engine\_version, default value is "3.x"
- **flavor\_id**: Instance flavor ID, prioritizes using instance\_flavor\_id variable, uses queried flavor ID if empty
- **storage\_spec\_code**: Storage specification code, assigned by referencing the input variable instance\_storage\_spec\_code
- **storage\_space**: Storage space size, assigned by referencing the input variable instance\_storage\_space, default value is 300
- **broker\_num**: Broker node count, assigned by referencing the input variable instance\_broker\_num, default value is 3
- **vpc\_id**: VPC ID, referencing the ID of the VPC resource created earlier
- **network\_id**: Subnet ID, referencing the ID of the VPC subnet resource created earlier
- **security\_group\_id**: Security group ID, referencing the ID of the security group resource created earlier
- **ssl\_enable**: Whether to enable SSL, assigned by referencing the input variable instance\_ssl\_enable, default value is false
- **description**: Instance description, assigned by referencing the input variable instance\_description, default value is empty string
- **security\_protocol**: Security protocol, assigned by referencing the input variable instance\_security\_protocol, default value is "SASL\_SSL"
- **charging\_mode**: Charging mode, assigned by referencing the input variable charging\_mode, default value is "postPaid"
- **lifecycle.ignore\_changes**: Lifecycle management, ignoring changes to availability\_zones and flavor\_id

### 9. Create DMS Kafka Topic

Add the following script to the TF file to instruct Terraform to create a DMS Kafka topic resource:

```hcl
# Variable definitions for Kafka topic
variable "topic_name" {
  description = "The name of the topic"
  type        = string
}

variable "topic_partitions" {
  description = "The number of the topic partition"
  type        = number
  default     = 3
}

# Create a DMS Kafka topic resource under the specified region (if the region parameter is omitted, it defaults to the region specified in the current provider block)
resource "huaweicloud_dms_kafka_topic" "test" {
  instance_id = huaweicloud_dms_kafka_instance.test.id
  name        = var.topic_name
  partitions  = var.topic_partitions
}
```

**Parameter Description**:

- **instance\_id**: Kafka instance ID, referencing the ID of the DMS Kafka instance resource created earlier
- **name**: Topic name, assigned by referencing the input variable topic\_name
- **partitions**: Topic partition count, assigned by referencing the input variable topic\_partitions, default value is 3

### 10. Create Local Variables

Add the following script to the TF file to create local variables:

```hcl
# Create local variables for building Kafka connection address
locals {
  kafka_connect_with_port = join(
    ",",
    formatlist(
      "%s:${huaweicloud_dms_kafka_instance.test.port}",
      split(",", huaweicloud_dms_kafka_instance.test.connect_address)
    )
  )
}
```

**Parameter Description**:

- **kafka\_connect\_with\_port**: Kafka connection address list with ports, generated by formatting Kafka instance connection address and port

### 11. Create EventGrid Connection

Add the following script to the TF file to instruct Terraform to create an EventGrid connection resource:

```hcl
# Variable definitions for EG connection
variable "connection_name" {
  description = "The name of the connection"
  type        = string
}

variable "connection_acks" {
  description = "The number of confirmation signals the prouder needs to receive to consider the message sent successfully"
  type        = string
  default     = "1"
}

# Create an EventGrid connection resource under the specified region (if the region parameter is omitted, it defaults to the region specified in the current provider block)
resource "huaweicloud_eg_connection" "test" {
  name      = var.connection_name
  type      = "KAFKA"
  vpc_id    = huaweicloud_vpc.test.id
  subnet_id = huaweicloud_vpc_subnet.test.id

  kafka_detail {
    instance_id     = huaweicloud_dms_kafka_instance.test.id
    connect_address = local.kafka_connect_with_port
    acks            = var.connection_acks
  }

  lifecycle {
    ignore_changes = [
      kafka_detail[0].user_name,
      kafka_detail[0].password,
    ]
  }

  depends_on = [
    huaweicloud_dms_kafka_topic.test
  ]
}
```

**Parameter Description**:

- **name**: Connection name, assigned by referencing the input variable connection\_name
- **type**: Connection type, set to "KAFKA" for Kafka connection
- **vpc\_id**: VPC ID, referencing the ID of the VPC resource created earlier
- **subnet\_id**: Subnet ID, referencing the ID of the VPC subnet resource created earlier
- **kafka\_detail**: Kafka connection detailed configuration
  - **instance\_id**: Kafka instance ID, referencing the ID of the DMS Kafka instance resource created earlier
  - **connect\_address**: Connection address, using the value of local variable kafka\_connect\_with\_port
  - **acks**: Confirmation signal count, assigned by referencing the input variable connection\_acks, default value is "1"
- **lifecycle.ignore\_changes**: Lifecycle management, ignoring changes to username and password in kafka\_detail
- **depends\_on**: Explicit dependency relationship, ensuring Kafka topic exists before connection creation

### 12. Create Time Sleep Resource

Add the following script to the TF file to instruct Terraform to create a time sleep resource:

```hcl
# Create a time sleep resource under the specified region (if the region parameter is omitted, it defaults to the region specified in the current provider block), used to wait for Kafka topic and EG connection to be ready
resource "time_sleep" "test" {
  create_duration = "5s"

  depends_on = [
    huaweicloud_eg_connection.test
  ]
}
```

**Parameter Description**:

- **create\_duration**: Wait time, set to "5s" to wait for 5 seconds
- **depends\_on**: Explicit dependency relationship, ensuring EventGrid connection exists before time sleep resource creation

### 13. Query EventGrid Event Channel Information

Add the following script to the TF file to instruct Terraform to query EventGrid event channel information:

```hcl
# Get all EventGrid event channel information that meets specific conditions under the specified region (if the region parameter is omitted, it defaults to the region specified in the current provider block), used to create event subscriptions
data "huaweicloud_eg_event_channels" "test" {
  provider_type = "OFFICIAL"
  name          = "default"
}
```

**Parameter Description**:

- **provider\_type**: Provider type, set to "OFFICIAL" for official provider
- **name**: Channel name, set to "default" for default channel

### 14. Create Event Subscription Resource

Add the following script to the TF file to instruct Terraform to create an event subscription resource:

```hcl
# Variable definitions for event subscription
variable "subscription_source_values" {
  description = "The event types to be subscribed from OBS service"
  type        = list(string)
  default     = [
    "OBS:CloudTrace:ApiCall",
    "OBS:CloudTrace:ObsSDK",
    "OBS:CloudTrace:ConsoleAction",
    "OBS:CloudTrace:SystemAction",
    "OBS:CloudTrace:Others"
  ]
}

# Create an event subscription resource under the specified region (if the region parameter is omitted, it defaults to the region specified in the current provider block)
resource "huaweicloud_eg_event_subscription" "test" {
  channel_id = try(data.huaweicloud_eg_event_channels.test.channels[0].id, "")
  name       = try(data.huaweicloud_eg_event_channels.test.channels[0].name, "")

  sources {
    name          = "HC.OBS"
    provider_type = "OFFICIAL"

    filter_rule = jsonencode({
      "source" : [
        {
          "op" : "StringIn",
          "values" : ["HC.OBS"]
        }
      ],
      "type" : [
        {
          "op" : "StringIn",
          "values" : var.subscription_source_values
        }
      ],
    })
  }

  targets {
    name          = "HC.Kafka"
    provider_type = "OFFICIAL"
    connection_id = huaweicloud_eg_connection.test.id

    transform = jsonencode({
      "type" : "ORIGINAL",
    })

    detail_name = "kafka_detail"
    detail      = jsonencode({
      "topic" : huaweicloud_dms_kafka_topic.test.name
      "key_transform" : {
        "type" : "ORIGINAL",
      }
    })
  }

  lifecycle {
    ignore_changes = [
      sources
    ]
  }

  depends_on = [
    time_sleep.test
  ]
}
```

**Parameter Description**:

- **channel\_id**: Event channel ID, using the queried default event channel ID
- **name**: Event subscription name, using the queried default event channel name
- **sources**: Event source configuration block
  - **name**: Event source name, set to "HC.OBS" for OBS service
  - **provider\_type**: Event source provider type, set to "OFFICIAL" for official provider
  - **filter\_rule**: Filter rule, configuring event source filter conditions in JSON format, including source and type filtering
- **targets**: Event target configuration block
  - **name**: Event target name, set to "HC.Kafka" for Kafka service
  - **provider\_type**: Event target provider type, set to "OFFICIAL" for official provider
  - **connection\_id**: Connection ID, referencing the ID of the EventGrid connection resource created earlier
  - **transform**: Transform configuration, configuring event transformation rules in JSON format, set to "ORIGINAL" to maintain original format
  - **detail\_name**: Target detail configuration name, set to "kafka\_detail"
  - **detail**: Target detail configuration, configuring Kafka topic and key transformation rules in JSON format
- **lifecycle.ignore\_changes**: Lifecycle management, ignoring changes to sources to avoid rebuilding subscriptions
- **depends\_on**: Explicit dependency relationship, ensuring time sleep resource is completed before event subscription creation

### 15. Create OBS Object

Add the following script to the TF file to instruct Terraform to create an OBS object resource:

```hcl
# Variable definitions for OBS object
variable "object_extension_name" {
  description = "The extension name of the OBS object to be uploaded"
  type        = string
  default     = ".txt"
  nullable    = false
}

variable "object_name" {
  description = "The name of the OBS object to be uploaded"
  type        = string
}

variable "object_upload_content" {
  description = "The content of the OBS object to be uploaded"
  type        = string
}

# Create an OBS object resource under the specified region (if the region parameter is omitted, it defaults to the region specified in the current provider block)
resource "huaweicloud_obs_bucket_object" "test" {
  bucket       = huaweicloud_obs_bucket.test.id
  key          = var.object_extension_name != "" ? format("%s%s", var.object_name, var.object_extension_name) : var.object_name
  content_type = "application/xml"
  content      = var.object_upload_content
}
```

**Parameter Description**:

- **bucket**: Bucket ID, referencing the ID of the OBS bucket resource created earlier
- **key**: Object key name, deciding whether to add extension name based on whether object\_extension\_name is empty
- **content\_type**: Object content type, set to "application/xml"
- **content**: Object content, assigned by referencing the input variable object\_upload\_content

### 16. Preset Input Parameters Required for Resource Deployment (Optional)

In this practice, some resources and data sources use input variables to assign values to configuration content. These input parameters need to be manually entered during subsequent deployments. At the same time, Terraform provides a method to preset these configurations through `.tfvars` files, which can avoid repeated input during each execution.

Create a `terraform.tfvars` file in the working directory with the following example content:

```hcl
# Huawei Cloud authentication information
region_name = "cn-north-4"
access_key  = "your-access-key"
secret_key  = "your-secret-key"

# VPC network configuration
vpc_name    = "tf_test_vpc"
subnet_name = "tf_test_subnet"

# Security group configuration
security_group_name = "tf_test_security_group"

# OBS bucket configuration
bucket_name = "tf-test-bucket"

# Kafka instance configuration
instance_name = "tf_test_kafka"

# Kafka topic configuration
topic_name = "tf-test-topic"

# EventGrid connection configuration
connection_name = "tf-test-connect"

# OBS object configuration
object_name           = "tf-test-obs-object"
object_upload_content = <<EOT
def main():
    print("Hello, World!")

if __name__ == "__main__":
    main()
EOT
```

**Usage**:

1. Save the above content as `terraform.tfvars` file in the working directory (this file name allows users to automatically import the content of this `tfvars` file when executing terraform commands; for other names, `.auto` needs to be added before tfvars, such as `variables.auto.tfvars`)
2. Modify parameter values as needed
3. When executing `terraform plan` or `terraform apply`, Terraform will automatically read the variable values from this file

In addition to using `terraform.tfvars` file, variable values can also be set in the following ways:

1. Command line parameters: `terraform apply -var="vpc_name=my-vpc" -var="bucket_name=my-bucket"`
2. Environment variables: `export TF_VAR_vpc_name=my-vpc`
3. Custom named variable files: `terraform apply -var-file="custom.tfvars"`

> Note: If the same variable is set in multiple ways, Terraform will use the variable value according to the following priority: command line parameters > variable files > environment variables > default values.

### 17. Initialize and Apply Terraform Configuration

After completing the above script configuration, execute the following steps to create resources:

1. Run `terraform init` to initialize the environment
2. Run `terraform plan` to view the resource creation plan
3. After confirming the resource plan is correct, run `terraform apply` to start creating event subscription (OBS event source, Kafka event target)
4. Run `terraform show` to view the details of the created event subscription (OBS event source, Kafka event target)

## Reference Information

- [Huawei Cloud EventGrid Product Documentation](https://support.huaweicloud.com/eg/index.html)
- [Huawei Cloud Provider Documentation](https://registry.terraform.io/providers/huaweicloud/huaweicloud/latest/docs)
- [Best Practice Source Code Reference For EventGrid Event Subscription (OBS Event Source, Kafka Event Target)](https://github.com/huaweicloud/terraform-provider-huaweicloud/tree/master/examples/eg/event-subscriptions/obs-to-kafka)