16 min read
On this page

Tencent Cloud EdgeOne + COS Deployment Guide

This document consolidates two common deployment patterns:

  1. API Acceleration: The client terminates TLS at the EdgeOne edge node, and EdgeOne fetches from the origin via HTTPS to the load balancer or origin server.
  2. Static Site: Build artifacts are uploaded to COS, and EdgeOne provides custom domains, HTTPS, caching, and cache purging capabilities.

All examples use placeholders and do not include real account IDs, domains, buckets, zones, load balancers, or credentials. In production, SecretId, SecretKey, and temporary tokens should be sourced from environment variables, Key Management Services (KMS), or CI Secret Stores, and must not be written to repositories or public documentation.

1. Variables and Security Boundaries

Subsequent commands uniformly use environment variables:

export TENCENTCLOUD_SECRET_ID='<secret-id>'
export TENCENTCLOUD_SECRET_KEY='<secret-key>'

export EO_ZONE_ID='<edgeone-zone-id>'
export API_DOMAIN='api.example.com'
export STATIC_DOMAIN='www.example.com'
export ORIGIN_DOMAIN='origin.example.internal'

export COS_BUCKET='example-web-<appid>'
export COS_REGION='ap-guangzhou'

Security Principles:

  • Management accounts are used only for creating infrastructure; deployment pipelines use independent sub-accounts or short-lived credentials.
  • IAM/CAM policies are authorized based on specific buckets and necessary actions, avoiding account-level cos:* permissions.
  • SecretKey or full signed request headers must not be printed in logs, shell history, or CI outputs.
  • Public documentation displays only placeholders; real resource lists are stored in private operations systems.

2. Pattern A: EdgeOne HTTPS Origin Fetch for API

flowchart LR
    C[Client] -->|HTTPS| EO[EdgeOne Edge]
    EO -->|HTTPS origin fetch| LB[Load Balancer / Reverse Proxy]
    LB --> APP[Application]

The recommended order is "origin fetch first, then certificate, then DNS". This allows verification before switching production traffic, avoiding 5xx errors caused by undeployed certificates or origin Host mismatches.

2.1 Create Acceleration Domain

tccli teo CreateAccelerationDomain \
  --region ap-guangzhou \
  --endpoint teo.tencentcloudapi.com \
  --ZoneId "$EO_ZONE_ID" \
  --DomainName "$API_DOMAIN" \
  --OriginInfo '{"OriginType":"IP_DOMAIN","Origin":"'"$ORIGIN_DOMAIN"'","PrivateAccess":"off"}' \
  --OriginProtocol HTTPS \
  --HttpsOriginPort 443

Verify the following configurations:

  • The origin certificate covers ORIGIN_DOMAIN, with a complete certificate chain and no expiration.
  • The origin Host matches the Layer 7 routing rules of the load balancer.
  • Origin port 443 allows EdgeOne origin fetches, and management ports are not inadvertently exposed.
  • HTTP to HTTPS redirects are handled at the expected layer to avoid origin redirect loops.

2.2 Deploy Edge Certificate

tccli teo ModifyHostsCertificate \
  --region ap-guangzhou \
  --endpoint teo.tencentcloudapi.com \
  --ZoneId "$EO_ZONE_ID" \
  --Hosts '["'"$API_DOMAIN"'"]' \
  --Mode eofreecert

Poll the domain and certificate status. Confirm that both are ready before changing DNS:

tccli teo DescribeAccelerationDomains \
  --region ap-guangzhou \
  --endpoint teo.tencentcloudapi.com \
  --ZoneId "$EO_ZONE_ID"

2.3 Pre-cutover Verification

First, resolve the access domain assigned by EdgeOne. Use curl --resolve to direct requests to the edge node while preserving the correct SNI and Host:

EO_CNAME="${API_DOMAIN}.eo.dnse1.com"
EO_IP=$(dig +short "$EO_CNAME" A | awk '/^[0-9.]+$/ {print; exit}')

curl --fail --show-error --silent \
  --resolve "${API_DOMAIN}:443:${EO_IP}" \
  -o /dev/null \
  -w 'HTTP %{http_code} TLS %{ssl_verify_result}\n' \
  "https://${API_DOMAIN}/health"

Only when the TLS verification result is 0, the health check returns the expected status, and there are no anomalies in the origin fetch logs, should you CNAME the business domain to EdgeOne.

2.4 DNS Cutover

tccli dnspod ModifyRecord \
  --endpoint dnspod.tencentcloudapi.com \
  --Domain example.com \
  --RecordId '<record-id>' \
  --SubDomain api \
  --RecordType CNAME \
  --RecordLine Default \
  --Value "${API_DOMAIN}.eo.dnse1.com" \
  --TTL 600

Reduce the TTL before cutover; restore the standard TTL after stable operation. Retain the original record value to ensure a quick rollback in case of anomalies.

3. Pattern B: COS Static Site + EdgeOne

flowchart LR
    C[Browser] -->|HTTPS| EO[EdgeOne Edge]
    EO -->|Origin fetch| COS[COS static website endpoint]

3.1 Prepare Bucket

Static website hosting typically requires:

  • Creating a bucket in the specified region.
  • Uploading index.html and static resources.
  • Configuring the static website homepage and error pages.
  • Deciding between public read, private origin fetch, or signed access based on business needs. Do not mechanically grant write permissions to the entire bucket.

The COS static website endpoint usually looks like this:

<bucket>.cos-website.<region>.myqcloud.com

3.2 Create Static Site Acceleration Domain

COS_WEBSITE_ENDPOINT="${COS_BUCKET}.cos-website.${COS_REGION}.myqcloud.com"

tccli teo CreateAccelerationDomain \
  --region ap-guangzhou \
  --endpoint teo.tencentcloudapi.com \
  --ZoneId "$EO_ZONE_ID" \
  --DomainName "$STATIC_DOMAIN" \
  --OriginInfo '{"OriginType":"COS","Origin":"'"$COS_WEBSITE_ENDPOINT"'","PrivateAccess":"off"}' \
  --OriginProtocol FOLLOW \
  --HttpOriginPort 80 \
  --HttpsOriginPort 443

When OriginType=COS, do not additionally set the HostHeader; the platform handles this based on the COS origin type. Subsequently, deploy the edge certificate, perform pre-verification, and switch DNS following the order in Pattern A.

3.3 Upload and Cache Purging

coscli sync ./dist "cos://${COS_BUCKET}/" \
  --region "$COS_REGION" \
  --delete

tccli teo CreatePurgeTask \
  --region ap-guangzhou \
  --endpoint teo.tencentcloudapi.com \
  --ZoneId "$EO_ZONE_ID" \
  --Type purge_host \
  --Targets '["'"$STATIC_DOMAIN"'"]'

--delete will delete extra objects in the target endpoint. Use it only when the build directory and target bucket prefix have been confirmed. If the release process cannot guarantee this, use immutable filenames and upload only new resources.

4. Least Privilege

The deployment account should only have permissions necessary for the target bucket and cache purging. The following is a structural illustration, not a complete policy ready for direct use:

{
  "version": "2.0",
  "statement": [
    {
      "effect": "allow",
      "action": [
        "cos:PutObject",
        "cos:DeleteObject",
        "cos:GetObject",
        "cos:GetBucket"
      ],
      "resource": [
        "qcs::cos:<region>:uid/<appid>:<bucket>/*"
      ]
    },
    {
      "effect": "allow",
      "action": ["teo:CreatePurgeTask"],
      "resource": ["<edgeone-resource-scope>"]
    }
  ]
}

Actual action names and resource formats should be based on the current Tencent Cloud CAM documentation and API responses. Before going live, verify using an independent test account that it "can publish but cannot manage other buckets".

5. Go-Live Checklist

  • EdgeOne domain status is normal.
  • Edge certificate covers the business domain, with a normal certificate chain and validity period.
  • API origin fetch uses HTTPS, with correct origin certificates and Host routing.
  • curl --resolve pre-verification passed.
  • Original DNS values are recorded for rollback in case of failure.
  • Static resources use content hashing or explicit cache versioning strategies.
  • HTML cache duration is shorter than that of hashed JS/CSS/images.
  • Deployment account has only the minimum permissions for target resources.
  • No real keys or account-level resource lists appear in logs, scripts, or documentation.

6. Common Issues

SymptomCommon CauseTroubleshooting
teo.intl... timeoutCLI used the international site endpointExplicitly specify --endpoint teo.tencentcloudapi.com
TLS handshake failureEdge certificate is still deploying, or SNI/domain mismatchCheck certificate status and verify with openssl s_client -servername
EdgeOne returns 5xxOrigin unreachable, origin Host error, or origin certificate failureCheck origin fetch logs and directly verify origin HTTPS
COS origin fetch rejects HostHeaderCOS origin type does not allow custom HostHeaderRemove this configuration and let the platform handle it automatically
Upload returns 403 AccessDeniedSub-account lacks target bucket actions or resource scopeCheck CAM policy action and resource
Old page still visible after releaseHTML cache not refreshed or cache key mismatchQuery cache status and purge by domain/URL
Some regions still access old origin after DNS cutoverTTL not expired or recursive resolver cacheQuery using multiple public DNS servers and wait for propagation

7. Rollback

In case of certificate, origin fetch, or cache anomalies:

  1. Restore DNS to the pre-cutover record.
  2. Verify that direct origin access is available.
  3. Retain EdgeOne configuration for offline troubleshooting; do not continuously add modifications during the incident.
  4. After fixing the issue, perform pre-verification via curl --resolve again before the next cutover.

Explicitly separating certificate deployment, pre-verification, DNS cutover, and rollback is far more reliable than "changing DNS immediately after creating the domain".