or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli.mdconfiguration.mderrors.mdexecution.mdindex.mdinventory.mdmodule-utils.mdplaybook.mdplugins.mdtemplating.md

playbook.mddocs/

0

# Playbook Engine

1

2

Ansible Core's playbook engine provides YAML-based automation workflow execution supporting plays, tasks, handlers, roles, blocks, includes, and imports with comprehensive control flow, error handling, and variable management.

3

4

## Capabilities

5

6

### Playbook Management

7

8

The main playbook container that loads, validates, and coordinates the execution of multiple plays with shared context and variable management.

9

10

```python { .api }

11

class Playbook:

12

"""

13

Main playbook container managing plays and execution context.

14

15

Attributes:

16

- _entries: List of play entries

17

- _basedir: Base directory for relative paths

18

- _file_name: Playbook filename

19

- _loader: DataLoader instance

20

- _variable_manager: Variable manager instance

21

"""

22

23

@staticmethod

24

def load(filename, variable_manager=None, loader=None, vars=None):

25

"""

26

Load playbook from YAML file.

27

28

Parameters:

29

- filename: Path to playbook file

30

- variable_manager: Variable manager instance

31

- loader: DataLoader instance

32

- vars: Additional variables

33

34

Returns:

35

Playbook: Loaded playbook instance

36

"""

37

38

def get_plays(self):

39

"""

40

Get all plays in playbook.

41

42

Returns:

43

list: Play objects

44

"""

45

46

def get_vars(self):

47

"""

48

Get playbook-level variables.

49

50

Returns:

51

dict: Playbook variables

52

"""

53

```

54

55

### Play Management

56

57

Individual play representation containing tasks, handlers, and play-level configuration with host targeting and execution control.

58

59

```python { .api }

60

class Play:

61

"""

62

Individual play representation with tasks and configuration.

63

64

Attributes:

65

- name: Play name

66

- hosts: Target host pattern

67

- tasks: List of task objects

68

- handlers: List of handler objects

69

- vars: Play variables

70

- tags: Play tags

71

- gather_facts: Whether to gather facts

72

- remote_user: Remote user for connections

73

- become: Privilege escalation settings

74

"""

75

76

def __init__(self):

77

"""Initialize empty play"""

78

79

@staticmethod

80

def load(data, variable_manager=None, loader=None, basedir=None):

81

"""

82

Load play from data structure.

83

84

Parameters:

85

- data: Play data dictionary

86

- variable_manager: Variable manager

87

- loader: DataLoader instance

88

- basedir: Base directory for paths

89

90

Returns:

91

Play: Loaded play instance

92

"""

93

94

def get_tasks(self):

95

"""

96

Get all tasks in play including role tasks.

97

98

Returns:

99

list: Task objects

100

"""

101

102

def get_handlers(self):

103

"""

104

Get all handlers in play including role handlers.

105

106

Returns:

107

list: Handler objects

108

"""

109

110

def get_roles(self):

111

"""

112

Get all roles in play.

113

114

Returns:

115

list: Role objects

116

"""

117

118

def get_vars(self):

119

"""

120

Get play variables.

121

122

Returns:

123

dict: Play-level variables

124

"""

125

```

126

127

### Task Management

128

129

Task representation with action, parameters, conditionals, loops, and execution control supporting all Ansible modules and plugins.

130

131

```python { .api }

132

class Task:

133

"""

134

Task representation with action and execution parameters.

135

136

Attributes:

137

- action: Module or action name

138

- args: Task arguments

139

- name: Task name

140

- when: Conditional expression

141

- loop: Loop specification

142

- tags: Task tags

143

- register: Variable to register result

144

- delegate_to: Delegation target

145

- become: Privilege escalation

146

- ignore_errors: Whether to ignore failures

147

- changed_when: When to mark as changed

148

- failed_when: When to mark as failed

149

"""

150

151

def __init__(self):

152

"""Initialize empty task"""

153

154

@staticmethod

155

def load(data, block=None, role=None, task_include=None, variable_manager=None, loader=None):

156

"""

157

Load task from data structure.

158

159

Parameters:

160

- data: Task data dictionary

161

- block: Parent block object

162

- role: Parent role object

163

- task_include: Task include object

164

- variable_manager: Variable manager

165

- loader: DataLoader instance

166

167

Returns:

168

Task: Loaded task instance

169

"""

170

171

def get_vars(self):

172

"""

173

Get task variables.

174

175

Returns:

176

dict: Task-level variables

177

"""

178

179

def evaluate_conditional(self, templar, all_vars):

180

"""

181

Evaluate task conditional expression.

182

183

Parameters:

184

- templar: Templating engine

185

- all_vars: Available variables

186

187

Returns:

188

bool: Whether conditional passes

189

"""

190

```

191

192

### Block Management

193

194

Task grouping container supporting error handling, rescue, and always sections with shared conditionals and variables.

195

196

```python { .api }

197

class Block:

198

"""

199

Task block container with error handling support.

200

201

Attributes:

202

- block: List of main tasks

203

- rescue: List of rescue tasks (on failure)

204

- always: List of tasks that always run

205

- when: Block conditional

206

- tags: Block tags

207

- vars: Block variables

208

"""

209

210

def __init__(self, parent_block=None, role=None, task_include=None, use_handlers=True, implicit=False):

211

"""Initialize block container"""

212

213

@staticmethod

214

def load(data, play=None, parent_block=None, role=None, task_include=None, variable_manager=None, loader=None):

215

"""

216

Load block from data structure.

217

218

Parameters:

219

- data: Block data dictionary

220

- play: Parent play

221

- parent_block: Parent block

222

- role: Parent role

223

- task_include: Task include

224

- variable_manager: Variable manager

225

- loader: DataLoader instance

226

227

Returns:

228

Block: Loaded block instance

229

"""

230

231

def get_tasks(self):

232

"""

233

Get all tasks in block sections.

234

235

Returns:

236

list: All task objects (block + rescue + always)

237

"""

238

239

def has_tasks(self):

240

"""

241

Check if block has any tasks.

242

243

Returns:

244

bool: True if block contains tasks

245

"""

246

```

247

248

### Handler Management

249

250

Event-driven task execution triggered by notify actions with deduplication and ordered execution.

251

252

```python { .api }

253

class Handler(Task):

254

"""

255

Handler task triggered by notifications.

256

257

Inherits from Task with additional handler-specific behavior.

258

259

Attributes:

260

- listen: List of notification names to listen for

261

- _hash: Handler hash for deduplication

262

"""

263

264

def __init__(self):

265

"""Initialize handler task"""

266

267

@staticmethod

268

def load(data, block=None, role=None, task_include=None, variable_manager=None, loader=None):

269

"""

270

Load handler from data structure.

271

272

Parameters:

273

- data: Handler data dictionary

274

- block: Parent block

275

- role: Parent role

276

- task_include: Task include

277

- variable_manager: Variable manager

278

- loader: DataLoader instance

279

280

Returns:

281

Handler: Loaded handler instance

282

"""

283

```

284

285

### Role Management

286

287

Role definition and metadata management supporting role dependencies, parameters, and modular playbook organization.

288

289

```python { .api }

290

class Role:

291

"""

292

Role definition with tasks, handlers, variables, and metadata.

293

294

Attributes:

295

- _role_name: Role name

296

- _role_path: Path to role directory

297

- _role_params: Role parameters

298

- _default_vars: Default variables

299

- _role_vars: Role variables

300

- _dependencies: Role dependencies

301

- _metadata: Role metadata

302

"""

303

304

def __init__(self, play=None, from_files=None, from_include=False):

305

"""Initialize role"""

306

307

@staticmethod

308

def load(role_include, play, parent_role=None, from_files=None, from_include=False):

309

"""

310

Load role from role include specification.

311

312

Parameters:

313

- role_include: Role include specification

314

- play: Parent play

315

- parent_role: Parent role for nested roles

316

- from_files: Load from specific files

317

- from_include: Whether loaded from include

318

319

Returns:

320

Role: Loaded role instance

321

"""

322

323

def get_name(self):

324

"""

325

Get role name.

326

327

Returns:

328

str: Role name

329

"""

330

331

def get_tasks(self):

332

"""

333

Get role tasks.

334

335

Returns:

336

list: Task objects

337

"""

338

339

def get_handlers(self):

340

"""

341

Get role handlers.

342

343

Returns:

344

list: Handler objects

345

"""

346

347

def get_default_vars(self):

348

"""

349

Get role default variables.

350

351

Returns:

352

dict: Default variables

353

"""

354

355

def get_vars(self):

356

"""

357

Get role variables.

358

359

Returns:

360

dict: Role variables

361

"""

362

363

def get_dependencies(self):

364

"""

365

Get role dependencies.

366

367

Returns:

368

list: Dependency role objects

369

"""

370

```

371

372

### Include and Import Management

373

374

Dynamic and static content inclusion supporting conditional includes, variable passing, and modular playbook composition.

375

376

```python { .api }

377

class TaskInclude(Task):

378

"""

379

Task include for dynamic content inclusion.

380

381

Supports conditional includes with variable passing.

382

"""

383

384

@staticmethod

385

def load(data, block=None, role=None, task_include=None, variable_manager=None, loader=None):

386

"""Load task include from data"""

387

388

class PlaybookInclude:

389

"""

390

Playbook include for importing entire playbooks.

391

392

Supports variable passing and conditional inclusion.

393

"""

394

395

@staticmethod

396

def load(data, basedir=None, variable_manager=None, loader=None):

397

"""Load playbook include from data"""

398

```

399

400

## Playbook Structure

401

402

### Basic Playbook Format

403

404

```yaml

405

---

406

- name: Web server setup

407

hosts: webservers

408

become: yes

409

vars:

410

http_port: 80

411

server_name: "{{ inventory_hostname }}"

412

413

tasks:

414

- name: Install Apache

415

package:

416

name: apache2

417

state: present

418

notify: restart apache

419

420

- name: Copy configuration

421

template:

422

src: apache.conf.j2

423

dest: /etc/apache2/apache2.conf

424

notify: restart apache

425

426

handlers:

427

- name: restart apache

428

service:

429

name: apache2

430

state: restarted

431

```

432

433

### Advanced Features

434

435

```yaml

436

---

437

- name: Advanced playbook example

438

hosts: all

439

gather_facts: yes

440

vars:

441

app_version: "1.2.3"

442

443

tasks:

444

- name: Conditional task

445

debug:

446

msg: "Running on {{ ansible_os_family }}"

447

when: ansible_os_family == "RedHat"

448

449

- name: Loop example

450

user:

451

name: "{{ item }}"

452

state: present

453

loop:

454

- alice

455

- bob

456

- charlie

457

458

- name: Block with error handling

459

block:

460

- name: Risky operation

461

command: /bin/might-fail

462

rescue:

463

- name: Handle failure

464

debug:

465

msg: "Operation failed, continuing"

466

always:

467

- name: Cleanup

468

file:

469

path: /tmp/cleanup

470

state: absent

471

472

- name: Include tasks conditionally

473

include_tasks: database.yml

474

when: setup_database | default(false)

475

476

- name: Import role

477

import_role:

478

name: common

479

vars:

480

role_var: value

481

```

482

483

## Control Flow

484

485

### Conditionals

486

487

```yaml

488

# Simple conditional

489

- name: Task with when

490

debug:

491

msg: "Executed"

492

when: ansible_os_family == "Debian"

493

494

# Complex conditional

495

- name: Multiple conditions

496

debug:

497

msg: "Complex condition"

498

when:

499

- ansible_distribution == "Ubuntu"

500

- ansible_distribution_version is version('18.04', '>=')

501

- inventory_hostname in groups['webservers']

502

```

503

504

### Loops

505

506

```yaml

507

# Simple loop

508

- name: Create users

509

user:

510

name: "{{ item }}"

511

loop:

512

- alice

513

- bob

514

515

# Loop with dictionaries

516

- name: Create users with details

517

user:

518

name: "{{ item.name }}"

519

groups: "{{ item.groups }}"

520

loop:

521

- name: alice

522

groups: admin

523

- name: bob

524

groups: users

525

526

# Loop with conditionals

527

- name: Install packages on Debian

528

package:

529

name: "{{ item }}"

530

loop:

531

- nginx

532

- mysql-server

533

when: ansible_os_family == "Debian"

534

```

535

536

### Error Handling

537

538

```yaml

539

# Ignore errors

540

- name: Command that might fail

541

command: /bin/might-fail

542

ignore_errors: yes

543

544

# Custom failure conditions

545

- name: Check service

546

command: systemctl is-active nginx

547

register: nginx_status

548

failed_when: nginx_status.rc not in [0, 3]

549

550

# Custom change conditions

551

- name: Touch file

552

file:

553

path: /tmp/myfile

554

state: touch

555

changed_when: false

556

```

557

558

## Usage Examples

559

560

### Basic Playbook Execution

561

562

```python

563

from ansible.playbook import Playbook

564

from ansible.inventory.manager import InventoryManager

565

from ansible.parsing.dataloader import DataLoader

566

from ansible.vars.manager import VariableManager

567

568

# Initialize components

569

loader = DataLoader()

570

inventory = InventoryManager(loader=loader, sources=['inventory'])

571

variable_manager = VariableManager(loader=loader, inventory=inventory)

572

573

# Load playbook

574

pb = Playbook.load('site.yml', variable_manager=variable_manager, loader=loader)

575

576

# Get plays

577

plays = pb.get_plays()

578

for play in plays:

579

print(f"Play: {play.name}")

580

tasks = play.get_tasks()

581

for task in tasks:

582

print(f" Task: {task.name}")

583

```

584

585

### Task Manipulation

586

587

```python

588

from ansible.playbook.task import Task

589

590

# Create task programmatically

591

task_data = {

592

'name': 'Install package',

593

'package': {

594

'name': 'nginx',

595

'state': 'present'

596

},

597

'become': True,

598

'tags': ['packages']

599

}

600

601

task = Task.load(task_data, variable_manager=variable_manager, loader=loader)

602

603

# Check task properties

604

print(f"Task name: {task.name}")

605

print(f"Task action: {task.action}")

606

print(f"Task args: {task.args}")

607

```