Pseudo parameters are CloudFormation's built-in variables that surface AWS environment details (region, account, stack info) without requiring you to declare them in the `Parameters` section. They're how you write **portable** templates that adapt to whichever account/region they're deployed into.
## The full list
| Name | Returns | Use when |
|------|---------|----------|
| `AWS::AccountId` | `123456789012` (12-digit account ID) | Building IAM ARNs, S3 bucket names that include account ID |
| `AWS::Region` | `us-west-2` | Any region-specific value (AMI lookup, region-suffixed names) |
| `AWS::StackName` | `teststack` | Building unique resource names (`!Sub "${AWS::StackName}-bucket"`) |
| `AWS::StackId` | Full stack ARN (`arn:aws:cloudformation:...:stack/...`) | Tagging, audit logging |
| `AWS::Partition` | `aws` (or `aws-cn`, `aws-us-gov`) | Constructing ARNs that work across partitions |
| `AWS::URLSuffix` | `amazonaws.com` (or `amazonaws.com.cn`) | Constructing API endpoint URLs |
| `AWS::NotificationARNs` | List of SNS topic ARNs (set via `--notification-arns`) | Plumbing stack notifications into resources |
| `AWS::NoValue` | (special) | Removes the property entirely when used as `!If` return value |
## Two reference patterns
```yaml
# Via Ref
!Ref AWS::Region
# Via Sub interpolation
!Sub "Region is ${AWS::Region}"
```
`!Sub` is usually cleaner because pseudo parameters most often appear inside composed strings (ARNs, resource names).
## Why `AWS::Partition` matters
Hardcoding `arn:aws:...` breaks the template in:
- AWS GovCloud (US-East/West) — partition is `aws-us-gov`
- China (Beijing/Ningxia) — partition is `aws-cn`
The portable form:
```yaml
!Sub "arn:${AWS::Partition}:s3:::${AWS::AccountId}-bucket"
```
Same logic for `AWS::URLSuffix` when constructing service endpoint URLs (`s3.${AWS::URLSuffix}`).
If you'll never deploy outside commercial AWS, the cost of using these is one extra interpolation. The benefit is the template doesn't silently break when GovCloud/China deployment becomes a requirement years later.
## `AWS::NoValue` — the conditional property remover
`AWS::NoValue` is the only pseudo parameter that's not a value — it's a sentinel that tells CFN to **omit a property entirely**. Combined with `Fn::If`, this lets you make a property conditionally present:
```yaml
DBSnapshotIdentifier: !If
- UseDBSnapshot
- !Ref DBSnapshotName
- !Ref AWS::NoValue # property is removed if condition is false
```
Without `AWS::NoValue`, you'd have to provide a "default" value, which often isn't valid for the property type. `AWS::NoValue` is the escape hatch.
## `AWS::NotificationARNs` quirk
Unlike all the other pseudo parameters, `AWS::NotificationARNs` returns a **list**, not a scalar. Access individual elements with `Fn::Select`:
```yaml
TopicARN: !Select [0, !Ref AWS::NotificationARNs]
```
These ARNs come from whatever was passed to `create-stack --notification-arns` (or the console equivalent). If nothing was passed, the list is empty and `Select` will fail at evaluation time.
## Implicit availability
Pseudo parameters do **not** need to be declared in the `Parameters` section. They're injected by CFN at evaluation time. They're also automatically available inside the `Conditions` section.
## Related
- [[CFN Ref vs Fn-GetAtt]]
- [[CFN Fn-Sub String Interpolation]]
- [[CFN Conditions Boolean Logic]]