or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

annotations-aspects.mdbackend-configuration.mdcore-infrastructure.mdindex.mditerators-dynamic.mdproviders-modules.mdprovisioners.mdresources-data-sources.mdterraform-functions.mdtesting.mdtokens-expressions.mdvariables-outputs.md

provisioners.mddocs/

0

# Provisioners

1

2

Resource provisioning capabilities for executing scripts, transferring files, and performing custom actions during resource lifecycle events.

3

4

## Capabilities

5

6

### Provisioner Types

7

8

Terraform supports three main provisioner types for executing actions during resource creation and destruction.

9

10

```typescript { .api }

11

/**

12

* File provisioner for transferring files to resources

13

*/

14

interface FileProvisioner {

15

readonly type: "file";

16

readonly source: string;

17

readonly destination: string;

18

readonly connection?: SSHProvisionerConnection | WinrmProvisionerConnection;

19

}

20

21

/**

22

* Local execution provisioner for running commands locally

23

*/

24

interface LocalExecProvisioner {

25

readonly type: "local-exec";

26

readonly command: string;

27

readonly workingDir?: string;

28

readonly interpreter?: string[];

29

readonly environment?: {[key: string]: string};

30

readonly when?: "create" | "destroy";

31

}

32

33

/**

34

* Remote execution provisioner for running commands on resources

35

*/

36

interface RemoteExecProvisioner {

37

readonly type: "remote-exec";

38

readonly inline?: string[];

39

readonly script?: string;

40

readonly scripts?: string[];

41

readonly connection: SSHProvisionerConnection | WinrmProvisionerConnection;

42

readonly when?: "create" | "destroy";

43

}

44

```

45

46

**Usage Examples:**

47

48

```typescript

49

import { AwsInstance } from "cdktf";

50

51

// Instance with multiple provisioners

52

new AwsInstance(this, "web-server", {

53

ami: "ami-12345678",

54

instanceType: "t2.micro",

55

keyName: "my-key",

56

57

provisioners: [

58

// Upload configuration file

59

{

60

type: "file",

61

source: "./config/app.conf",

62

destination: "/tmp/app.conf",

63

connection: {

64

type: "ssh",

65

user: "ubuntu",

66

privateKey: "${file(var.private_key_path)}"

67

}

68

},

69

70

// Run setup script locally

71

{

72

type: "local-exec",

73

command: "echo 'Instance ${self.id} is being created'"

74

},

75

76

// Configure the server remotely

77

{

78

type: "remote-exec",

79

inline: [

80

"sudo apt-get update",

81

"sudo apt-get install -y nginx",

82

"sudo cp /tmp/app.conf /etc/nginx/sites-available/",

83

"sudo systemctl enable nginx",

84

"sudo systemctl start nginx"

85

],

86

connection: {

87

type: "ssh",

88

user: "ubuntu",

89

privateKey: "${file(var.private_key_path)}",

90

host: "${self.public_ip}"

91

}

92

}

93

]

94

});

95

```

96

97

### Connection Configuration

98

99

Provisioners require connection configurations to access remote resources.

100

101

```typescript { .api }

102

/**

103

* SSH connection configuration

104

*/

105

interface SSHProvisionerConnection {

106

readonly type: "ssh";

107

readonly user: string;

108

readonly password?: string;

109

readonly privateKey?: string;

110

readonly certificate?: string;

111

readonly host?: string;

112

readonly port?: number;

113

readonly timeout?: string;

114

readonly scriptPath?: string;

115

readonly bastionHost?: string;

116

readonly bastionHostKey?: string;

117

readonly bastionPort?: number;

118

readonly bastionUser?: string;

119

readonly bastionPassword?: string;

120

readonly bastionPrivateKey?: string;

121

readonly bastionCertificate?: string;

122

readonly agentIdentity?: string;

123

readonly agent?: boolean;

124

readonly hostKey?: string;

125

}

126

127

/**

128

* Windows Remote Management connection configuration

129

*/

130

interface WinrmProvisionerConnection {

131

readonly type: "winrm";

132

readonly user: string;

133

readonly password: string;

134

readonly host?: string;

135

readonly port?: number;

136

readonly timeout?: string;

137

readonly https?: boolean;

138

readonly insecure?: boolean;

139

readonly useNtlm?: boolean;

140

readonly cacert?: string;

141

readonly cert?: string;

142

readonly key?: string;

143

}

144

```

145

146

**Usage Examples:**

147

148

```typescript

149

// SSH with private key

150

const sshConnection: SSHProvisionerConnection = {

151

type: "ssh",

152

user: "ubuntu",

153

privateKey: "${file(var.private_key_path)}",

154

host: "${self.public_ip}",

155

timeout: "2m"

156

};

157

158

// SSH with bastion host

159

const bastionConnection: SSHProvisionerConnection = {

160

type: "ssh",

161

user: "ubuntu",

162

privateKey: "${file(var.private_key_path)}",

163

host: "${self.private_ip}",

164

bastionHost: "bastion.example.com",

165

bastionUser: "ubuntu",

166

bastionPrivateKey: "${file(var.bastion_key_path)}"

167

};

168

169

// WinRM connection

170

const winrmConnection: WinrmProvisionerConnection = {

171

type: "winrm",

172

user: "Administrator",

173

password: "${var.admin_password}",

174

host: "${self.public_ip}",

175

port: 5985,

176

timeout: "10m"

177

};

178

```

179

180

### TerraformSelf Class

181

182

Utility class for self-references within provisioners and resources.

183

184

```typescript { .api }

185

/**

186

* Self-reference utilities for provisioners

187

*/

188

class TerraformSelf {

189

/**

190

* Get string attribute from the current resource

191

* @param key - Attribute name

192

* @returns String value

193

*/

194

static getString(key: string): string;

195

196

/**

197

* Get number attribute from the current resource

198

* @param key - Attribute name

199

* @returns Number value

200

*/

201

static getNumber(key: string): number;

202

203

/**

204

* Get any attribute from the current resource

205

* @param key - Attribute name

206

* @returns Any value

207

*/

208

static getAny(key: string): any;

209

}

210

```

211

212

**Usage Examples:**

213

214

```typescript

215

import { TerraformSelf } from "cdktf";

216

217

new AwsInstance(this, "web", {

218

ami: "ami-12345678",

219

instanceType: "t2.micro",

220

221

provisioners: [

222

{

223

type: "local-exec",

224

command: `echo 'Instance IP: ${TerraformSelf.getString("public_ip")}'`

225

},

226

{

227

type: "remote-exec",

228

inline: [

229

`echo 'My ID is ${TerraformSelf.getString("id")}'`,

230

`echo 'My private IP is ${TerraformSelf.getString("private_ip")}'`

231

],

232

connection: {

233

type: "ssh",

234

user: "ubuntu",

235

privateKey: "${file(var.key_path)}",

236

host: TerraformSelf.getString("public_ip")

237

}

238

}

239

]

240

});

241

```

242

243

### Advanced Provisioner Patterns

244

245

#### Conditional Provisioning

246

247

```typescript

248

import { Fn } from "cdktf";

249

250

const enableMonitoring = new TerraformVariable(this, "enable_monitoring", {

251

type: "bool",

252

default: false

253

});

254

255

new AwsInstance(this, "app-server", {

256

ami: "ami-12345678",

257

instanceType: "t2.micro",

258

259

provisioners: [

260

// Always run basic setup

261

{

262

type: "remote-exec",

263

inline: [

264

"sudo apt-get update",

265

"sudo apt-get install -y nginx"

266

],

267

connection: sshConnection

268

},

269

270

// Conditionally install monitoring

271

...(enableMonitoring.booleanValue ? [{

272

type: "remote-exec",

273

inline: [

274

"curl -sSL https://agent.datadoghq.com/install.sh | bash",

275

"sudo systemctl enable datadog-agent",

276

"sudo systemctl start datadog-agent"

277

],

278

connection: sshConnection

279

}] : [])

280

]

281

});

282

```

283

284

#### Multi-Stage Provisioning

285

286

```typescript

287

new AwsInstance(this, "database-server", {

288

ami: "ami-12345678",

289

instanceType: "t3.large",

290

291

provisioners: [

292

// Stage 1: Upload files

293

{

294

type: "file",

295

source: "./scripts/setup-database.sh",

296

destination: "/tmp/setup-database.sh",

297

connection: sshConnection

298

},

299

{

300

type: "file",

301

source: "./config/database.conf",

302

destination: "/tmp/database.conf",

303

connection: sshConnection

304

},

305

306

// Stage 2: Setup system

307

{

308

type: "remote-exec",

309

inline: [

310

"chmod +x /tmp/setup-database.sh",

311

"sudo /tmp/setup-database.sh"

312

],

313

connection: sshConnection

314

},

315

316

// Stage 3: Configure application

317

{

318

type: "remote-exec",

319

script: "./scripts/configure-app.sh",

320

connection: sshConnection

321

},

322

323

// Stage 4: Local notification

324

{

325

type: "local-exec",

326

command: "curl -X POST -H 'Content-type: application/json' --data '{\"text\":\"Database server ${self.id} is ready\"}' ${var.slack_webhook_url}"

327

}

328

]

329

});

330

```

331

332

#### Destroy-Time Provisioning

333

334

```typescript

335

new AwsInstance(this, "app-server", {

336

ami: "ami-12345678",

337

instanceType: "t2.micro",

338

339

provisioners: [

340

// Creation-time provisioner

341

{

342

type: "remote-exec",

343

inline: [

344

"sudo systemctl start myapp"

345

],

346

connection: sshConnection

347

},

348

349

// Destroy-time provisioner for cleanup

350

{

351

type: "remote-exec",

352

when: "destroy",

353

inline: [

354

"sudo systemctl stop myapp",

355

"sudo rm -rf /var/lib/myapp/data",

356

"sudo userdel myapp"

357

],

358

connection: sshConnection

359

},

360

361

// Local cleanup

362

{

363

type: "local-exec",

364

when: "destroy",

365

command: "rm -f ./generated-config-${self.id}.json"

366

}

367

]

368

});

369

```

370

371

### Error Handling and Retries

372

373

```typescript

374

new AwsInstance(this, "web-server", {

375

ami: "ami-12345678",

376

instanceType: "t2.micro",

377

378

provisioners: [

379

{

380

type: "remote-exec",

381

inline: [

382

// Wait for cloud-init to complete

383

"while [ ! -f /var/lib/cloud/instance/boot-finished ]; do echo 'Waiting for cloud-init...'; sleep 2; done",

384

385

// Retry package installation

386

"for i in {1..5}; do sudo apt-get update && break || sleep 5; done",

387

"for i in {1..5}; do sudo apt-get install -y nginx && break || sleep 5; done",

388

389

// Verify installation

390

"systemctl is-active nginx || exit 1"

391

],

392

connection: {

393

type: "ssh",

394

user: "ubuntu",

395

privateKey: "${file(var.private_key_path)}",

396

host: "${self.public_ip}",

397

timeout: "5m"

398

}

399

}

400

]

401

});

402

```