- Naming conventions:
- Functions = camelCase
- Classes = PascalCase
- Interfaces/Types = PascalCase
- Constants = UPPER_CASE_SNAKE_CASE
- File names like what the export (e.g.
class FooBar
→Foobar.ts
) - AWS Stacks, Resources, IDs = PascalCase
- Avoid concrete resource names as long as possible to prevent names clashes
- Use resource-names.ts to define name of resources
- Use destructoring imports over
* as foobar
to get proper intellisense - Name the file of a stack with suffix
-stack.ts
but omit suffixes on constructs - Use git commit message convention
- ...
Resources shared across stacks should be exchanged either directly or if not possible with SSM Parameter or concrete names. There are pseudo code snippets under Resolve dependencies to how it could be implemented. Concrete names should be used in case of cross account deployments (e.g. granting some permissions to a role). Directly resolved dependencies can be traced directly in the code but those with SSM Parameter or concrete names not, however you could express those with filling the table under Dependencies between stacks. I would recommend to use a single place for parameter and resource names and import them from there (e.g. lib/shared/resource-names.ts)
Anyways, be sure to follow this order when exchanging resources between stacks.
- Directly
- SSM Parameter
- Concrete names (can lead to name clashes)
Between | What? | Resolved with |
---|---|---|
StackA → StackB | some resource | SSM Parameter |
StackA (Account1) → StackC (Account2) | some resource | Concrete name |
class StackA {
puplic readonly resource: Resource;
constructor() {
this.resource = new Resource();
}
}
interface StackBProps {
resource: Resource,
}
class StackB {
constructor(props: StackBProps) {
// Do something with props.resouce from StackA
}
}
const stack = new StackA();
new StackB({ resouce: stack.resource })
import ssmParamNames from 'shared';
class StackA {
constructor() {
const resource = new Resource();
new StringParameter({
parameterName: ssmParamNames.PARAM_NAME,
strinValue: resource.Arn,
});
}
}
class StackB {
constructor() {
const bucket = new Bucket();
const resourceArn = StringParameter.fromStringParameterName(ssmParamNames.PARAM_NAME);
bucket.grantRead(Resource.fromArn(resourceArn.stringValue));
}
}
import roleNames from 'shared';
class StackA {
constructor() {
new Role({
roleName: roleNames.ROLE_XYZ,
});
}
}
class StackB {
constructor() {
const bucket = new Bucket();
// Could also use new ArnPrincipal()
const role = Role.fromRoleArn(`arn:aws:iam::${this.account}:role/${roleNames.ROLE_XYZ}`)
bucket.grantRead(role);
}
}