aws-cloudformation / aws-cloudformation/cloudformation-guard
[Enhancement] Support YAML anchors and aliases (*anchor / &anchor)
- Dominant language
- Rust
- Stars
- 1.4k
- Forks
- 196
- Avg merge
- 3d 6h
- Merged PRs (30d)
- 5
Description
### Summary
Add support for YAML anchors (`&anchor`) and aliases (`*anchor`) in Guard's data loader (`guard/src/rules/libyaml/loader.rs`).
### Problem & Motivation
In production CloudFormation, SAM, and OpenAPI/YAML templates, YAML anchors and merge keys (`<<: *default_tags`) are standard practice for keeping infrastructure definitions DRY (e.g., shared tags, VPC subnets, task definitions, and common environment variables).
Currently, when a template containing YAML anchors is passed to `cfn-guard validate`, the loader explicitly rejects it:
https://github.com/aws-cloudformation/cloudformation-guard/blob/3e265bb6ad26090412b189ba7145719e7e7a8585/guard/src/rules/libyaml/loader.rs#L52-L56
```rust
Event::Alias(_) => {
return Err(Error::ParseError(String::from(
"Guard does not currently support aliases",
)))
}
```
This immediately aborts validation with `Error occurred Parser Error`, forcing users to either:
1. Run third-party pre-processors (e.g., `cfn-flip` or Python YAML parsers) to dereference anchors before passing templates into Guard in CI/CD.
2. Duplicate hundreds of lines of boilerplate across templates to avoid anchors.
### Reproduction
**Data file (`template.yaml`):**
```yaml
homeRegion: &HOME_REGION us-east-1
vpcs:
- name: myvpc
region: *HOME_REGION
defaultSecurityGroupRulesDeletion: true
```
**Rule file (`rules.guard`):**
```guard
rule check_vpc {
vpcs.region == "us-east-1"
}
```
**Command:**
```bash
cfn-guard validate --data template.yaml --rules rules.guard
```
**Current Result:**
```text
Error occurred Parser Error when parsing `Error encountered while parsing data file: template.yaml: Guard does not currently support aliases`
```
### Proposed Implementation
1. In `Loader` (`guard/src/rules/libyaml/loader.rs`), maintain an `anchors: HashMap` mapping anchor identifiers to constructed `MarkedValue` subtrees.
2. During `handle_scalar_event`, `handle_mapping_start`, and `handle_sequence_start`, register any associated `anchor` into the map.
3. Upon receiving `Event::Alias(anchor)`:
- Look up the referenced subtree from `anchors`.
- Clone the node with the alias location and push it to `self.stack`.
4. Include a recursion depth or cycle-detection check to guard against circular alias references (e.g., YAML entity expansion attacks).
Contributor guide
Research direction
Start in guard/src/rules/libyaml/loader.rs, especially the existing Event::Alias handling and the scalar, mapping, and sequence event handlers. Run the provided cfn-guard validate reproduction first; done means anchored values, aliases, and merge keys load successfully while circular alias references are rejected safely.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- cli, tooling
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100