Skip to main content
Every WAAP policy, rule, and response page in Terraform references a domain resource by ID, so the domain is the first thing a configuration must declare before anything else can attach to it. The Gcore Terraform provider v0 manages this entire chain as code, replacing the manual click-through setup in the Portal. The following resources are supported: WAAP domains, security policies, custom rules, advanced rules, firewall rules, API paths, custom response pages, and security insight silence rules. Provider installation and authentication are covered in the Terraform overview. WAAP resources require provider v0 with permanent_api_token authentication.

Workflow

Add resource configuration to main.tf, then run:
Review the output, then apply:
Enter yes when prompted. The getting started guide covers the full workflow.

Domains

A WAAP domain is the root resource that all other WAAP resources depend on. It is linked to a CDN resource and controls the operating mode and protection settings for a domain.

Create a WAAP domain

The following configuration creates a CDN resource with WAAP enabled and attaches a WAAP domain to it.
1

Open the main.tf file

2

Copy and customize the code

3

Configure the CDN resource

  • Specify cname — the domain name to protect.
  • Specify origin — the origin server hostname or IP address.
  • Keep waap { value = true } to enable WAAP on this CDN resource.
4

Configure the WAAP domain

  • name — must match the CDN resource cname.
  • status — set to "monitor" to inspect traffic without blocking, or "active" to enforce protection. Start with "monitor" to validate the configuration before going live.
  • (optional) Add settings.ddos to configure DDoS protection thresholds:
    • global_threshold — maximum number of requests per second across all IPs before rate limiting applies.
    • burst_threshold — maximum number of requests per second from a single IP before it is rate limited.
  • (optional) Add settings.api to define API endpoints:
    • api_urls — list of URL patterns treated as API endpoints. JavaScript injection and CAPTCHA are disabled for these paths.
    • is_api — set to true to treat the entire domain as an API domain. If set, api_urls is ignored.
  • (optional) Add api_discovery_settings to enable automated API Discovery:
    • description_file_location — URL of the OpenAPI specification file (YAML or JSON, versions 2, 3, or 3.1).
    • description_file_scan_enabled — enable periodic scanning of the specification file.
    • description_file_scan_interval_hours — scan interval in hours.
    • traffic_scan_enabled — enable traffic-based API discovery.
    • traffic_scan_interval_hours — traffic scan interval in hours.
After creation, switch status from "monitor" to "active" only after reviewing traffic in the Events page and confirming that legitimate requests are not blocked.
After a WAAP domain is created, it takes a few seconds to propagate before rules can be attached to it. When the domain and its rules are defined in the same configuration, the first terraform apply may fail rule creation with a 429 error (“domain is still being propagated”). Running terraform apply a second time resolves this — Terraform picks up where it left off and creates the remaining resources.

Security policies

Security policies are built-in rule sets that cover common attack categories, grouped into OWASP threats, IP reputation, Behavioral WAF, Bot protection, CMS protection, and API protection. Each policy can be enabled or disabled per domain.

Enable or disable security policies

The following configuration enables and disables specific security policies for a domain.
1

Open the main.tf file

2

Copy and customize the code

3

Configure the policy resource

  • domain_id — the ID of the WAAP domain.
  • policies — a map of policy IDs to boolean values. true enables the policy, false disables it.
    • Use the gcore_waap_domain_policy data source to look up a policy by name and group instead of hardcoding the ID.
    • Policy IDs are domain-specific and can be retrieved from the WAAP API: GET /waap/v1/domains/{domain_id}/rule-sets. The IDs are in the rules[].id field.
Only policies explicitly listed in the policies map are modified. Policies not listed retain their current state.

Custom rules

Custom rules match incoming requests against conditions and apply an action when all conditions are met. Up to five conditions can be combined in a single rule.

Create a custom rule

The following configuration creates a rule that blocks requests from a specific IP address.
1

Open the main.tf file

2

Copy and customize the code

3

Configure the rule

  • domain_id — the ID of the WAAP domain.
  • name — a descriptive name for the rule.
  • enabled — set to true to activate the rule immediately.
  • (optional) description — additional context for the rule.
Rule names accept letters, digits, whitespace, and the characters .:'";<>?&|. Hyphens and other symbols are rejected with a validation error. This applies to name on custom rules, firewall rules, and advanced rules.
4

Configure the action

  • block — block the request.
    • status_code — HTTP status code returned to the client. Must be one of: 403, 405, 418, 429. Default: 403.
    • action_duration — how long subsequent requests from the same source remain blocked. Format: a number followed by s (seconds), m (minutes), h (hours), or d (days). Example: 12h.
  • allow = true — allow the request, bypassing all other security checks.
  • captcha = true — present a CAPTCHA challenge.
  • handshake = true — perform automatic browser validation (JS challenge).
  • monitor = true — log the request without taking action.
  • tag — a block that attaches user-defined tags to the request for analytics: tag { tags = ["tag-name"] }.
block and tag are blocks; allow, captcha, handshake, and monitor are plain boolean fields.
5

Configure conditions

At least one condition is required, up to five total. All conditions must match for the rule to trigger.Available condition types:All conditions support an optional negation = true field to invert the match.
When multiple custom rules match the same request, the action with the highest priority takes effect. Priority order (highest first): Allow > Block > Captcha > JS Challenge > Monitor. Tag actions run first and do not stop rule evaluation.

Create a rate-limiting rule

The following configuration blocks requests from a single IP that exceed a rate threshold — the same protection configurable as an advanced rate limiting rule in the Gcore Customer Portal.
1

Open the main.tf file

2

Copy and customize the code

3

Configure the request_rate condition

  • path_pattern — a regular expression matching the URL path.
  • requests — number of requests within the time window that triggers the condition.
  • time — time window in seconds.
  • (optional) http_methods — restrict the rate check to specific HTTP methods.
  • (optional) ips — restrict the rate check to specific source IPs.
  • (optional) user_defined_tag — restrict the rate check to requests carrying a specific user-defined tag.

Match requests by tag

Tags in the tags condition are system-assigned IDs, one per detected attack category — xss for cross-site scripting, sql for SQL injection. Resolve an ID from its display name with the gcore_waap_tag data source instead of hardcoding it:
user_defined_tags works the same way but takes the literal tag names created by tag rules — no data source lookup is needed.

Advanced rules

Advanced rules require an Enterprise WAAP plan — accounts without this feature receive a 401 error from the API. Contact Gcore support to upgrade.
Advanced rules use an expression language to match requests with greater precision than custom rules. The expression is evaluated per request, and the rule fires when it returns true.

Create an advanced rule

The following configuration blocks requests from a specific IP in the access phase.
1

Open the main.tf file

2

Copy and customize the code

3

Configure the rule

  • source — the match expression. Uses request object fields — request.ip, request.uri, request.method, request.headers['name'], and more listed in the advanced rule objects reference, which also covers the full expression syntax.
  • phase — the processing phase. Use "access" to evaluate the rule before the request is forwarded to the origin.
  • action — same action types as custom rules: block, allow, captcha, handshake, monitor, tag.

Firewall rules

Firewall rules are IP-focused access controls, equivalent to the IP allowlist and blocklist in the Customer Portal. They support a single condition per rule and are simpler than custom rules.

Create a firewall rule

The following configuration blocks a range of IP addresses.
1

Open the main.tf file

2

Copy and customize the code

3

Configure the rule

  • domain_id — the ID of the WAAP domain.
  • name — a descriptive name.
  • enabled — set to true to activate the rule.
  • actionblock or allow. Supports the same status_code and action_duration fields as custom rules.
  • conditions — one condition block. Supports ip, ip_range, country, url, user_agent, header, header_exists, http_method, and request_rate. All condition types support negation = true.
Use firewall rules for simple IP allowlists and blocklists. For multi-condition logic or rate limiting, use custom rules instead.

API paths

API paths and API Discovery require an Enterprise WAAP plan, same as advanced rules.
API paths define individual endpoints for the API Discovery and Protection feature. Defining paths explicitly lets WAAP enforce API-specific protection independently of traffic-based discovery.

Add an API path

The following configuration registers a single API endpoint for a domain.
1

Open the main.tf file

2

Copy and customize the code

3

Configure the API path

  • domain_id — the ID of the WAAP domain.
  • path — the API path: /v1/items/{id} uses curly braces to mark a dynamic segment.
  • method — the HTTP method. Must be one of: GET, POST, PUT, PATCH, DELETE, TRACE, HEAD, OPTIONS.
  • http_scheme — the scheme. Must be HTTP or HTTPS.
  • (optional) api_version — a version label for the endpoint: "v1".
  • (optional) tags — a list of tags to associate with the path.
  • (optional) api_groups — a list of API group names to associate with the path.
  • (optional) status — the discovery status. Must be one of: CONFIRMED_API, POTENTIAL_API, NOT_API, DELISTED_API. Use CONFIRMED_API for manually defined paths.

Custom response pages

Custom response pages replace the default WAAP challenge and block pages with branded content. A page set is created once and assigned to one or more domains.

Create a custom page set

The following configuration creates a page set with custom block and CAPTCHA pages.
1

Open the main.tf file

2

Copy and customize the code

3

Configure the page set

  • name — a unique name for the page set.
  • domains — a list of WAAP domain IDs to assign this page set to.
4

Configure page types

Each type is an optional block with enabled = true to activate it:Each page block supports:
  • header — text displayed in the page header.
  • title — text displayed as the page title (not available for cookie_disabled and javascript_disabled). Minimum three characters.
  • text — body text. Minimum 20 characters.
  • logo — base64-encoded image (data:image/png;base64,...). Supported formats: JPEG, PNG, JPG. Maximum dimensions: 450 x 130 px.
  • error — error message text (available for captcha only).

Security insight silence rules

Security Insights require an Enterprise WAAP plan, same as advanced rules.
Security insights are alerts generated when WAAP detects configuration issues or patterns that indicate a security risk. Silence rules suppress specific insight types to reduce noise for known or accepted conditions — the same rules shown on the Silence rules tab in the Customer Portal.
As of provider v0.35.0, terraform apply reports an error when creating this resource even though the WAAP API creates the silence rule successfully — the provider fails to parse the API’s 201 response. The resource also does not support terraform import, so a successfully created silence rule cannot be reconciled into Terraform state afterward. Until this is fixed upstream, manage silence rules through the Customer Portal or the Security insights API instead of Terraform.

Create a silence rule

The following configuration silences a specific insight type for a limited period.
1

Open the main.tf file

2

Copy and customize the code

3

Configure the silence rule

  • domain_id — the ID of the WAAP domain.
  • insight_type — the slug of the insight type to silence. Use the gcore_waap_security_insight_type data source to look up a type by name, or retrieve the slug from the WAAP API at /v1/security-insights/types.
  • labels — must use the exact label keys the insight type declares, not arbitrary key-value pairs. attack-on-disabled-policy declares policy_id, attack_type, and policy_name; allowed-high-risk-ip declares ip, rule_id, and rule_name. The insight type’s declared labels are listed alongside its slug at /v1/security-insights/types.
  • comment — a description of why the insight is being silenced.
  • author — the name or identifier of the person or team creating the silence.
  • (optional) expire_at — the date and time when the silence expires, in ISO 8601 format (YYYY-MM-DDTHH:MM:SSZ). If omitted, the silence does not expire.