A Guardrail that Is Attached, Versioned and Not Empty
Creating a guardrail does not apply it: the application must send guardrailIdentifier and guardrailVersion on every call, and DRAFT is mutable. This publishes a numbered version, outputs the two values your code needs, and refuses a guardrail with no policies at all - which attaches successfully, filters nothing, and reports as active.
Verification
Static-verifiedPassed: validated and lint-clean (provider-schema-validated for AWS/Azure/GCP; Terraform-language lint elsewhere).
Conformance
- Static validation (fmt · validate · tflint)
- Security scan clean (Checkov)
- Plan tests (mocked: validation rules · outputs)
Provenance
- SHA-256 checksum
- Signature (pending)
Functional
- Live test pending (no cloud run yet)
Last verified 2026-09-13 · how we verify
Use it from the registry
terraform · opentofumodule "bedrock_guardrail" {
source = "www.iac-bazaar.com/iac-bazaar/aws-bedrock-guardrail/aws"
version = "1.0.0"
}Needs a registry token from /account/tokens. The module itself is free; the account is what identifies you. Full setup: registry docs.
Inputs & outputs
Create a free account to read this module's contract
The declared contract - every input name, type, default and description, plus every output - is shown to signed-in accounts, not to anonymous visitors.
A free account sees the contract of every module in the catalogue. There is no subscription and nothing to buy - the modules are free to download, and they run under Vizier.
Documentation
aws-bedrock-guardrail
A Bedrock guardrail with filters that are actually set, a pinned version, and a
place to send a record of what the model was asked. Works with Terraform and
OpenTofu (>= 1.6), AWS provider >= 6.0, < 7.0.
Creating a guardrail does not apply it, and nothing in Terraform can. A
guardrail takes effect only when the calling application passes
guardrailIdentifier and guardrailVersion on InvokeModel, or when it is
attached to an agent. Apply this module, change nothing in your application, and
every prompt is still unfiltered. That is why invoke_parameters is an output:
it is the part that has to reach your code. An unattached guardrail is a
document, not a control, and it is worth being blunt about that because the
console shows it as active either way.
An empty guardrail is the dangerous case. Every policy block is optional at the API, so a guardrail with no filters, no PII rules, no denied topics and no word list is created successfully, attaches successfully, filters nothing - and appears in every dashboard as a guardrail that is in place. A precondition refuses it. The defaults here set all six content filters and nine PII types, so the module is useful before you configure anything.
DRAFT is mutable. An application that references DRAFT gets whatever the
guardrail is at the moment of the call, including a version someone widened this
morning. The module publishes a numbered version and outputs it, with
skip_destroy so an application still pinned to an older version does not have
it deleted from underneath.
PII actions are chosen per type, deliberately. BLOCK refuses the whole
message; ANONYMIZE replaces the value and lets the rest through. Blocking a
support transcript because it contains a customer's name is how a guardrail ends
up switched off, so identifiers are anonymised and secrets are blocked. The
credential types matter more than they look: people paste code and stack traces
into these applications, and a model that has seen an access key will repeat it.
Model invocation logging is off by default, and not because it does not
matter. Without it there is no record of any prompt or completion, so a
jailbreak or a leak leaves nothing to investigate. It is off because it is a
single account-and-region-wide setting - two copies of this module in one
account would overwrite each other on every apply. Turn
manage_account_invocation_logging on in exactly one place, and remember the
destination holds whatever your users typed.
Smaller things: PROMPT_ATTACK is input-only and a precondition catches a
non-NONE output_strength before the API does; the blocked-input message
deliberately does not name which filter fired, since that tells someone probing
the guardrail exactly what to adjust; and contextual_grounding is empty by
default rather than set to a number that would look active while doing nothing,
because it only applies when the caller passes grounding sources.
Verification
Static validation runs tofu fmt, init, validate, tflint and checkov.
This module has not yet had a live test, so it is published as statically
validated with its live test pending and does not carry the live-tested mark.
Usage code & full reference need an account
The complete copy-paste usage, the full input/output reference, and operational notes are free with an account - shown here and bundled in the download. Sign in and this section fills in.
- Usage