Skip to content
All projects

PF-03 · Tencent · IaC

Tencent Cloud audit-ready Terraform

Tencent Cloud modules that define CloudAudit tracks per service, so risky changes land in a COS bucket.

Role
Design and implementation
Period
Personal project · released Nov 2026
Cloud
Tencent
Scale
18 modules · 3 examples
Key tech
Terraform · Tencent Cloud · CloudAudit · COS · CAM · CLB
GitHub
18
Terraform modules
4
Audit tracks by service
19
Audit events tracked in code

At a glance

CloudAudit tracks into a COS bucketCOS bucketCAMCVMCBSVPCcam/cvm/disk/vpc/AddUserCreateApiKeyAttachUserPolicyRunInstancesTerminateInstancesResizeDiskCreateSecurityGroupPolicies4 audit tracks · one COS prefix per serviceRed border: risky event
Who changed what piles up in COS by service, ready to be read one kind at a time.

Problem

Changes on Tencent Cloud needed a per-service record of who did what. The provider also ships on an irregular cycle, so a new version could change a plan without any code change.

Approach

CloudAudit tracks are defined per service in code for CAM, CVM, CBS, and VPC, and each stores to its own COS prefix. Every module pins the provider to = 1.81.163.

Result

Permission, server, disk, and security group changes reach COS through the tracks defined in code, including risky events such as CreateApiKey and AttachUserPolicy.

Up close

ClientCLBL7 HTTPS 443Rule-based forwardingL4 TCP_SSL 9443Game trafficCVM backendHTTP redirects to HTTPS:8080:9000provider = 1.81.163 (exact version pinned)
These modules pin the provider to = 1.81.163, because Tencent releases do not follow a regular cycle.

Audit tracks per service

What this code does: Defines the CAM and CVM tracks as lists of event names.

  audit_tracks = [
    {
      name          = "iam_trackingset"
      resource_type = "CAM"
      event_names   = ["AddUser", "DeleteUser", "CreateApiKey", "DeleteApiKey", "AttachUserPolicy", "DetachUserPolicy"]
      action_type   = "*"
      storage = {
        storage_prefix = "cam"
        storage_type   = "cos"
      }
    },
    {
      name          = "vm_trackingset"
      resource_type = "CVM"
      event_names   = ["RunInstances", "TerminateInstances", "StopInstances", "StartInstances", "ResetInstancesType", "AttachDisks", "DetachDisks"]
      action_type   = "*"
      storage = {
        storage_prefix = "cvm"
        storage_type   = "cos"
      }
    },

Pinning the provider version

What this code does: Pins the provider to one exact version.

terraform {
  required_version = ">= 1.9, < 2.0"

  required_providers {
    tencentcloud = {
      source  = "tencentcloudstack/tencentcloud"
      version = "= 1.81.163"
    }
  }
}

What I learned

Keeping one track per service instead of one mixed stream lets a reviewer read one kind of event at a time and expire each kind on its own.

What I would improve

The scanner has few Tencent Cloud rules, so a pass covers less than it does on AWS. CI validates the examples but does not apply them.

Open to work · Cloud infrastructure and security