Cloud Resource Name (CRN)¶
A Cloud Resource Name (CRN) is a unique identifier assigned to every resource managed by cdkx. Similar to AWS ARN (Amazon Resource Name), the CRN provides a standardized way to identify and reference resources across different providers.
Format¶
| Segment | Required | Description |
|---|---|---|
crn |
✅ | Fixed prefix |
cdkx |
✅ | Framework identifier |
<provider> |
✅ | Provider name (e.g., hetzner, multipass) |
<domain> |
✅ | Resource domain (e.g., networking, compute, storage) |
<region> |
❌ | Optional region/zone (e.g., fsn1, nbg1) |
<account> |
❌ | Optional account/project identifier |
<resource-type> |
✅ | Type of resource (e.g., network, server, volume) |
<resource-id> |
✅ | Provider-assigned unique identifier |
Examples¶
Hetzner Resources¶
// Simple resource without region/account
crn:cdkx:hetzner:networking:network/12345
// Resource with region
crn:cdkx:hetzner:networking:fsn1:primary-ip/67890
// Composite ID (action resources)
crn:cdkx:hetzner:networking:subnet/network/12345/10.0.1.0_24
crn:cdkx:hetzner:networking:route/network/12345/10.100.0.0_24
Multipass Resources¶
Using CRNs¶
Accessing CRN After Deployment¶
Every L1 construct exposes attrCrn, an IResolvable that resolves to the CRN string after deployment:
CRN in Engine State¶
After deployment, the CRN is persisted in the engine state file (.cdkx/engine-state.json):
{
"stacks": {
"NetworkStack": {
"resources": {
"NetA1B2C3D4": {
"status": "CREATE_COMPLETE",
"physicalId": "12345",
"crn": "crn:cdkx:hetzner:networking:network/12345",
"outputs": {
"networkId": 12345,
"name": "my-network",
"ipRange": "10.0.0.0/16"
}
}
}
}
}
}
CRN API¶
The Crn class provides methods for parsing and formatting CRN strings:
Parsing¶
import { Crn } from '@cdk-x/core';
const crn = Crn.parse('crn:cdkx:hetzner:networking:network/12345');
console.log(crn.provider); // 'hetzner'
console.log(crn.domain); // 'networking'
console.log(crn.resourceType); // 'network'
console.log(crn.resourceId); // '12345'
console.log(crn.region); // undefined
console.log(crn.account); // undefined
Formatting¶
import { Crn } from '@cdk-x/core';
const crnString = Crn.format({
provider: 'hetzner',
domain: 'networking',
region: 'fsn1', // optional
account: 'proj-123', // optional
resourceType: 'server',
resourceId: '98765',
});
console.log(crnString);
// 'crn:cdkx:hetzner:networking:fsn1:proj-123:server/98765'
Validation¶
import { Crn } from '@cdk-x/core';
// Check if string is valid CRN format
Crn.isCrn('crn:cdkx:hetzner:networking:network/12345'); // true
Crn.isCrn('not-a-crn'); // false
Crn.isCrn('arn:aws:ec2:us-east-1:123:instance/i-123'); // false
Implementing buildCrn in Handlers¶
Each resource handler must implement the buildCrn() method to construct the CRN string:
Benefits¶
- Uniqueness: Each CRN is unique within its provider scope
- Portability: Standard format works across all providers (Hetzner, Multipass, etc.)
- Auditability: CRNs appear in engine state for resource tracking
- Future-proof: Foundation for cross-stack references and resource imports
See also
- Tokens & Cross-stack References — how tokens resolve CRNs at deploy time
- Deployment Lifecycle — how the engine persists CRNs
- Stack — deployment units that contain resources with CRNs