or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

aws-hooks.mdcli.mdcompilation-hooks.mdcore-objects.mdhelpers.mdindex.mdresource-collections.md

resource-collections.mddocs/

0

# Resource Collections

1

2

Framework for creating reusable, parameterized groups of Terraform resources that can be instantiated with different configurations. Resource collections support environment-specific variants, inheritance patterns, and validation using the schematics library.

3

4

## Capabilities

5

6

### ResourceCollection Base Class

7

8

Base class for creating reusable groups of Terraform resources with parameter validation and environment-specific variants.

9

10

```python { .api }

11

class ResourceCollection(schematics.Model):

12

def __init__(self, **kwargs):

13

"""

14

Create a resource collection instance.

15

16

Parameters:

17

- **kwargs: Collection-specific parameters defined as schematics types

18

19

The constructor automatically validates parameters and calls create_resources().

20

"""

21

22

def create_resources(self):

23

"""

24

Abstract method that must be implemented by subclasses.

25

26

This method should create the Terraform resources for this collection.

27

Access collection parameters via self.parameter_name.

28

"""

29

raise NotImplementedError("Subclasses must implement create_resources()")

30

31

# Variant support

32

def __init__(self, **kwargs):

33

"""

34

Supports variant-specific parameter overrides.

35

36

Parameters ending with '_variant' are used as overrides when

37

within a matching Variant context.

38

39

Example:

40

MyCollection(count=2, production_variant={'count': 5})

41

"""

42

```

43

44

### Variant Context Manager

45

46

Context manager for environment-specific configurations that enables automatic parameter overrides based on environment context.

47

48

```python { .api }

49

class Variant:

50

def __init__(self, name: str):

51

"""

52

Create a variant context.

53

54

Parameters:

55

- name: str - Variant name (e.g., 'production', 'staging', 'development')

56

57

Example:

58

with Variant('production'):

59

# Collections instantiated here use production-specific overrides

60

pass

61

"""

62

63

def __enter__(self):

64

"""Enter variant context - subsequent collections use variant overrides."""

65

66

def __exit__(self, exc_type, exc_val, exc_tb):

67

"""Exit variant context."""

68

```

69

70

## Usage Examples

71

72

### Basic Resource Collection

73

74

```python

75

from terraformpy import ResourceCollection, Resource

76

import schematics

77

78

class WebServerStack(ResourceCollection):

79

# Define collection parameters using schematics types

80

instance_type = schematics.StringType(default='t3.micro')

81

instance_count = schematics.IntType(default=1, min_value=1)

82

environment = schematics.StringType(required=True)

83

84

def create_resources(self):

85

# Create resources using collection parameters

86

for i in range(self.instance_count):

87

Resource('aws_instance', f'web_{i}',

88

instance_type=self.instance_type,

89

ami='ami-12345678',

90

tags={

91

'Name': f'WebServer-{i}-{self.environment}',

92

'Environment': self.environment

93

}

94

)

95

96

# Instantiate the collection

97

web_stack = WebServerStack(

98

instance_count=3,

99

environment='production'

100

)

101

```

102

103

### Collection with Dependencies

104

105

```python

106

from terraformpy import ResourceCollection, Resource, Data

107

import schematics

108

109

class DatabaseStack(ResourceCollection):

110

db_instance_class = schematics.StringType(default='db.t3.micro')

111

db_name = schematics.StringType(required=True)

112

subnet_group_name = schematics.StringType(required=True)

113

114

def create_resources(self):

115

# Query existing security group

116

db_sg = Data('aws_security_group', 'db_sg',

117

filters={'tag:Name': f'{self.db_name}-db-sg'}

118

)

119

120

# Create RDS instance

121

db_instance = Resource('aws_db_instance', 'main',

122

identifier=self.db_name,

123

instance_class=self.db_instance_class,

124

engine='postgres',

125

engine_version='13.7',

126

allocated_storage=20,

127

db_name=self.db_name,

128

username='postgres',

129

manage_master_user_password=True,

130

db_subnet_group_name=self.subnet_group_name,

131

vpc_security_group_ids=[db_sg.id]

132

)

133

134

# Create parameter group

135

Resource('aws_db_parameter_group', 'main',

136

family='postgres13',

137

name=f'{self.db_name}-params',

138

parameters=[

139

{'name': 'log_connections', 'value': '1'},

140

{'name': 'log_checkpoints', 'value': '1'}

141

]

142

)

143

144

# Use the collection

145

db_stack = DatabaseStack(

146

db_name='myapp',

147

db_instance_class='db.r6g.large',

148

subnet_group_name='myapp-db-subnets'

149

)

150

```

151

152

### Environment-Specific Variants

153

154

```python

155

from terraformpy import ResourceCollection, Resource, Variant

156

import schematics

157

158

class ApplicationStack(ResourceCollection):

159

instance_type = schematics.StringType(default='t3.micro')

160

min_size = schematics.IntType(default=1)

161

max_size = schematics.IntType(default=3)

162

desired_capacity = schematics.IntType(default=2)

163

164

def create_resources(self):

165

# Auto Scaling Group

166

Resource('aws_autoscaling_group', 'app',

167

min_size=self.min_size,

168

max_size=self.max_size,

169

desired_capacity=self.desired_capacity,

170

launch_template={

171

'id': '${aws_launch_template.app.id}',

172

'version': '$Latest'

173

}

174

)

175

176

# Launch Template

177

Resource('aws_launch_template', 'app',

178

instance_type=self.instance_type,

179

image_id='ami-12345678'

180

)

181

182

# Development environment

183

with Variant('development'):

184

dev_stack = ApplicationStack(

185

instance_type='t3.micro',

186

min_size=1,

187

max_size=2,

188

desired_capacity=1,

189

# Development-specific overrides

190

development_variant={

191

'instance_type': 't3.nano', # Smaller instances in dev

192

'min_size': 0, # Allow scaling to zero

193

'desired_capacity': 0 # Start with no instances

194

}

195

)

196

197

# Production environment

198

with Variant('production'):

199

prod_stack = ApplicationStack(

200

instance_type='t3.medium',

201

min_size=2,

202

max_size=10,

203

desired_capacity=4,

204

# Production-specific overrides

205

production_variant={

206

'instance_type': 'c5.large', # More powerful instances

207

'min_size': 3, # Higher minimum

208

'max_size': 20, # Higher maximum

209

'desired_capacity': 6 # More initial capacity

210

}

211

)

212

```

213

214

### Collection Composition

215

216

```python

217

from terraformpy import ResourceCollection

218

import schematics

219

220

class NetworkingStack(ResourceCollection):

221

vpc_cidr = schematics.StringType(default='10.0.0.0/16')

222

223

def create_resources(self):

224

# VPC resources

225

Resource('aws_vpc', 'main', cidr_block=self.vpc_cidr)

226

# ... other networking resources

227

228

class SecurityStack(ResourceCollection):

229

vpc_id = schematics.StringType(required=True)

230

231

def create_resources(self):

232

# Security groups, NACLs, etc.

233

Resource('aws_security_group', 'web',

234

vpc_id=self.vpc_id,

235

# ... security group rules

236

)

237

238

class FullStack(ResourceCollection):

239

environment = schematics.StringType(required=True)

240

241

def create_resources(self):

242

# Compose multiple stacks

243

network = NetworkingStack()

244

245

# Reference network resources in security stack

246

security = SecurityStack(vpc_id='${aws_vpc.main.id}')

247

248

# Deploy complete infrastructure

249

full_stack = FullStack(environment='staging')

250

```

251

252

### Parameter Validation

253

254

```python

255

from terraformpy import ResourceCollection

256

import schematics

257

258

class ValidatedStack(ResourceCollection):

259

# String with choices

260

environment = schematics.StringType(

261

required=True,

262

choices=['dev', 'staging', 'production']

263

)

264

265

# Integer with validation

266

instance_count = schematics.IntType(

267

default=1,

268

min_value=1,

269

max_value=10

270

)

271

272

# Custom validation

273

def validate_instance_count(self, value):

274

if self.environment == 'production' and value < 2:

275

raise schematics.ValidationError(

276

'Production environment requires at least 2 instances'

277

)

278

return value

279

280

def create_resources(self):

281

for i in range(self.instance_count):

282

Resource('aws_instance', f'app_{i}',

283

instance_type='t3.micro',

284

tags={'Environment': self.environment}

285

)

286

287

# This will raise ValidationError

288

try:

289

ValidatedStack(environment='production', instance_count=1)

290

except schematics.ValidationError as e:

291

print(f"Validation failed: {e}")

292

293

# This will succeed

294

ValidatedStack(environment='production', instance_count=3)

295

```