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

module-utils.mddocs/

0

# Module Utilities

1

2

Ansible Core's module utilities provide comprehensive shared libraries for module development including argument parsing, JSON handling, text conversion, network utilities, validation, platform abstraction, and common functionality used across all Ansible modules.

3

4

## Capabilities

5

6

### Basic Module Framework

7

8

Core module utilities providing the foundation for all Ansible module development with argument parsing, result formatting, and platform abstraction.

9

10

```python { .api }

11

class AnsibleModule:

12

"""

13

Base class for all Ansible modules providing common functionality.

14

15

Parameters:

16

- argument_spec: Module argument specification

17

- bypass_checks: Skip argument validation

18

- no_log: Disable logging of arguments

19

- check_invalid_arguments: Validate unknown arguments

20

- mutually_exclusive: Mutually exclusive argument groups

21

- required_together: Arguments required together

22

- required_one_of: Require at least one of arguments

23

- add_file_common_args: Add common file arguments

24

- supports_check_mode: Module supports check mode

25

26

Attributes:

27

- params: Parsed module parameters

28

- check_mode: Whether in check mode

29

- diff_mode: Whether in diff mode

30

"""

31

32

def __init__(self, argument_spec, bypass_checks=False, no_log=False,

33

check_invalid_arguments=None, mutually_exclusive=None,

34

required_together=None, required_one_of=None,

35

add_file_common_args=False, supports_check_mode=False):

36

"""Initialize module with argument specification"""

37

38

def exit_json(self, **kwargs):

39

"""

40

Exit module with success result.

41

42

Parameters:

43

- kwargs: Result data (changed, msg, etc.)

44

"""

45

46

def fail_json(self, msg, **kwargs):

47

"""

48

Exit module with failure result.

49

50

Parameters:

51

- msg: Failure message

52

- kwargs: Additional result data

53

"""

54

55

def run_command(self, args, check_rc=True, close_fds=True, executable=None,

56

data=None, binary_data=False, path_prefix=None, cwd=None,

57

use_unsafe_shell=False, prompt_regex=None, environ_update=None,

58

umask=None, encoding='utf-8', errors='surrogateescape'):

59

"""

60

Execute command and return result.

61

62

Parameters:

63

- args: Command arguments

64

- check_rc: Check return code

65

- close_fds: Close file descriptors

66

- executable: Shell executable

67

- data: Input data

68

- binary_data: Handle binary data

69

- path_prefix: PATH prefix

70

- cwd: Working directory

71

- use_unsafe_shell: Allow shell injection

72

- prompt_regex: Regex for prompts

73

- environ_update: Environment updates

74

- umask: Process umask

75

- encoding: Text encoding

76

- errors: Error handling

77

78

Returns:

79

tuple: (return_code, stdout, stderr)

80

"""

81

82

def get_bin_path(self, arg, required=False, opt_dirs=None):

83

"""

84

Find binary in PATH.

85

86

Parameters:

87

- arg: Binary name

88

- required: Whether binary is required

89

- opt_dirs: Additional directories to search

90

91

Returns:

92

str: Path to binary or None

93

"""

94

95

def boolean(self, arg):

96

"""

97

Convert argument to boolean.

98

99

Parameters:

100

- arg: Value to convert

101

102

Returns:

103

bool: Boolean value

104

"""

105

106

def md5(self, filename):

107

"""

108

Calculate MD5 hash of file.

109

110

Parameters:

111

- filename: File path

112

113

Returns:

114

str: MD5 hash

115

"""

116

117

def sha1(self, filename):

118

"""

119

Calculate SHA1 hash of file.

120

121

Parameters:

122

- filename: File path

123

124

Returns:

125

str: SHA1 hash

126

"""

127

128

def backup_file(self, fn):

129

"""

130

Create backup of file.

131

132

Parameters:

133

- fn: File path

134

135

Returns:

136

str: Backup file path

137

"""

138

139

def cleanup(self, tmpfile):

140

"""

141

Clean up temporary files.

142

143

Parameters:

144

- tmpfile: Temporary file path

145

"""

146

```

147

148

### Argument Specification and Validation

149

150

Comprehensive argument parsing and validation system supporting complex argument relationships, type checking, and input sanitization.

151

152

```python { .api }

153

def check_required_arguments(argument_spec, parameters):

154

"""

155

Check that all required arguments are provided.

156

157

Parameters:

158

- argument_spec: Argument specification

159

- parameters: Provided parameters

160

161

Raises:

162

AnsibleError: If required arguments missing

163

"""

164

165

def check_type_str(value):

166

"""

167

Ensure value is string type.

168

169

Parameters:

170

- value: Value to check

171

172

Returns:

173

str: String value

174

"""

175

176

def check_type_list(value):

177

"""

178

Ensure value is list type.

179

180

Parameters:

181

- value: Value to check

182

183

Returns:

184

list: List value

185

"""

186

187

def check_type_dict(value):

188

"""

189

Ensure value is dictionary type.

190

191

Parameters:

192

- value: Value to check

193

194

Returns:

195

dict: Dictionary value

196

"""

197

198

def check_type_bool(value):

199

"""

200

Convert value to boolean.

201

202

Parameters:

203

- value: Value to convert

204

205

Returns:

206

bool: Boolean value

207

"""

208

209

def check_type_int(value):

210

"""

211

Convert value to integer.

212

213

Parameters:

214

- value: Value to convert

215

216

Returns:

217

int: Integer value

218

"""

219

220

def check_type_float(value):

221

"""

222

Convert value to float.

223

224

Parameters:

225

- value: Value to convert

226

227

Returns:

228

float: Float value

229

"""

230

231

def check_type_path(value):

232

"""

233

Validate and expand file path.

234

235

Parameters:

236

- value: Path to validate

237

238

Returns:

239

str: Validated path

240

"""

241

```

242

243

### Text Processing and Conversion

244

245

Text handling utilities for encoding conversion, string manipulation, and cross-platform text processing.

246

247

```python { .api }

248

def to_bytes(obj, encoding='utf-8', errors='surrogateescape', nonstring='simplerepr'):

249

"""

250

Convert object to bytes.

251

252

Parameters:

253

- obj: Object to convert

254

- encoding: Text encoding

255

- errors: Error handling

256

- nonstring: Non-string handling

257

258

Returns:

259

bytes: Byte representation

260

"""

261

262

def to_text(obj, encoding='utf-8', errors='surrogateescape', nonstring='simplerepr'):

263

"""

264

Convert object to text string.

265

266

Parameters:

267

- obj: Object to convert

268

- encoding: Text encoding

269

- errors: Error handling

270

- nonstring: Non-string handling

271

272

Returns:

273

str: Text representation

274

"""

275

276

def to_native(obj, encoding='utf-8', errors='surrogateescape', nonstring='simplerepr'):

277

"""

278

Convert object to native string type.

279

280

Parameters:

281

- obj: Object to convert

282

- encoding: Text encoding

283

- errors: Error handling

284

- nonstring: Non-string handling

285

286

Returns:

287

str: Native string

288

"""

289

```

290

291

### JSON Handling

292

293

JSON processing utilities with enhanced error handling and Ansible-specific serialization support.

294

295

```python { .api }

296

def load_json(data):

297

"""

298

Load JSON data with error handling.

299

300

Parameters:

301

- data: JSON string

302

303

Returns:

304

object: Parsed JSON data

305

306

Raises:

307

ValueError: If JSON parsing fails

308

"""

309

310

def dump_json(obj, indent=None):

311

"""

312

Dump object to JSON string.

313

314

Parameters:

315

- obj: Object to serialize

316

- indent: JSON indentation

317

318

Returns:

319

str: JSON string

320

"""

321

322

class AnsibleJSONEncoder:

323

"""JSON encoder with Ansible-specific type handling"""

324

325

def default(self, obj):

326

"""Handle Ansible-specific object types"""

327

```

328

329

### Network Utilities

330

331

Network-related utilities for IP address validation, network calculations, and network interface operations.

332

333

```python { .api }

334

def is_ip(address):

335

"""

336

Check if string is valid IP address.

337

338

Parameters:

339

- address: Address to check

340

341

Returns:

342

bool: True if valid IP

343

"""

344

345

def is_ipv4(address):

346

"""Check if address is IPv4"""

347

348

def is_ipv6(address):

349

"""Check if address is IPv6"""

350

351

def get_network_address(ip, prefix):

352

"""

353

Calculate network address from IP and prefix.

354

355

Parameters:

356

- ip: IP address

357

- prefix: Network prefix

358

359

Returns:

360

str: Network address

361

"""

362

363

def get_network_size(prefix):

364

"""

365

Get network size from prefix.

366

367

Parameters:

368

- prefix: Network prefix

369

370

Returns:

371

int: Number of addresses

372

"""

373

```

374

375

### File and Directory Operations

376

377

File system utilities for cross-platform file operations, permission handling, and path manipulation.

378

379

```python { .api }

380

def mkstemp(suffix="", prefix="tmp", dir=None):

381

"""

382

Create temporary file.

383

384

Parameters:

385

- suffix: File suffix

386

- prefix: File prefix

387

- dir: Directory for temp file

388

389

Returns:

390

tuple: (file_descriptor, path)

391

"""

392

393

def mkdtemp(suffix="", prefix="tmp", dir=None):

394

"""

395

Create temporary directory.

396

397

Parameters:

398

- suffix: Directory suffix

399

- prefix: Directory prefix

400

- dir: Parent directory

401

402

Returns:

403

str: Temporary directory path

404

"""

405

406

def cleanup_tmp_file(path):

407

"""

408

Clean up temporary file.

409

410

Parameters:

411

- path: File path to clean up

412

"""

413

414

def set_mode_if_different(path, mode, changed):

415

"""

416

Set file mode if different.

417

418

Parameters:

419

- path: File path

420

- mode: Desired mode

421

- changed: Whether file was changed

422

423

Returns:

424

bool: True if mode was changed

425

"""

426

427

def set_owner_if_different(path, owner, changed):

428

"""

429

Set file owner if different.

430

431

Parameters:

432

- path: File path

433

- owner: Desired owner

434

- changed: Whether file was changed

435

436

Returns:

437

bool: True if owner was changed

438

"""

439

440

def set_group_if_different(path, group, changed):

441

"""

442

Set file group if different.

443

444

Parameters:

445

- path: File path

446

- group: Desired group

447

- changed: Whether file was changed

448

449

Returns:

450

bool: True if group was changed

451

"""

452

```

453

454

### Dictionary Transformations

455

456

Dictionary manipulation utilities for merging, flattening, and transforming data structures commonly used in automation.

457

458

```python { .api }

459

def dict_merge(base_dict, other_dict):

460

"""

461

Recursively merge dictionaries.

462

463

Parameters:

464

- base_dict: Base dictionary

465

- other_dict: Dictionary to merge

466

467

Returns:

468

dict: Merged dictionary

469

"""

470

471

def flatten_dict(d, separator='.'):

472

"""

473

Flatten nested dictionary.

474

475

Parameters:

476

- d: Dictionary to flatten

477

- separator: Key separator

478

479

Returns:

480

dict: Flattened dictionary

481

"""

482

483

def camel_dict_to_snake_dict(camel_dict):

484

"""

485

Convert camelCase keys to snake_case.

486

487

Parameters:

488

- camel_dict: Dictionary with camelCase keys

489

490

Returns:

491

dict: Dictionary with snake_case keys

492

"""

493

494

def snake_dict_to_camel_dict(snake_dict, capitalize_first=False):

495

"""

496

Convert snake_case keys to camelCase.

497

498

Parameters:

499

- snake_dict: Dictionary with snake_case keys

500

- capitalize_first: Capitalize first letter

501

502

Returns:

503

dict: Dictionary with camelCase keys

504

"""

505

```

506

507

### Process and System Utilities

508

509

System-level utilities for process management, signal handling, and platform-specific operations.

510

511

```python { .api }

512

def get_platform():

513

"""

514

Get current platform name.

515

516

Returns:

517

str: Platform name (Linux, Darwin, Windows, etc.)

518

"""

519

520

def get_distribution():

521

"""

522

Get Linux distribution information.

523

524

Returns:

525

tuple: (name, version, codename)

526

"""

527

528

def get_all_subclasses(cls):

529

"""

530

Get all subclasses of a class.

531

532

Parameters:

533

- cls: Base class

534

535

Returns:

536

set: All subclasses

537

"""

538

539

def run_cmd(module, args, **kwargs):

540

"""

541

Run command using module's run_command method.

542

543

Parameters:

544

- module: AnsibleModule instance

545

- args: Command arguments

546

- kwargs: Additional options

547

548

Returns:

549

tuple: (return_code, stdout, stderr)

550

"""

551

```

552

553

### Validation Utilities

554

555

Input validation and sanitization utilities for securing module inputs and ensuring data integrity.

556

557

```python { .api }

558

def check_required_if(parameters, argument_spec):

559

"""

560

Check conditional requirements.

561

562

Parameters:

563

- parameters: Module parameters

564

- argument_spec: Argument specification

565

566

Raises:

567

AnsibleError: If requirements not met

568

"""

569

570

def check_required_one_of(parameters, required_one_of):

571

"""

572

Check that one of required arguments is provided.

573

574

Parameters:

575

- parameters: Module parameters

576

- required_one_of: Required argument groups

577

578

Raises:

579

AnsibleError: If no required arguments provided

580

"""

581

582

def check_required_together(parameters, required_together):

583

"""

584

Check that related arguments are provided together.

585

586

Parameters:

587

- parameters: Module parameters

588

- required_together: Related argument groups

589

590

Raises:

591

AnsibleError: If related arguments not together

592

"""

593

594

def check_mutually_exclusive(parameters, mutually_exclusive):

595

"""

596

Check that mutually exclusive arguments are not both provided.

597

598

Parameters:

599

- parameters: Module parameters

600

- mutually_exclusive: Mutually exclusive groups

601

602

Raises:

603

AnsibleError: If exclusive arguments both provided

604

"""

605

606

def sanitize_keys(obj, no_log_strings):

607

"""

608

Remove sensitive data from object.

609

610

Parameters:

611

- obj: Object to sanitize

612

- no_log_strings: Sensitive strings to remove

613

614

Returns:

615

object: Sanitized object

616

"""

617

```

618

619

## Module Development Patterns

620

621

### Basic Module Structure

622

623

```python

624

#!/usr/bin/python

625

# -*- coding: utf-8 -*-

626

627

from ansible.module_utils.basic import AnsibleModule

628

629

DOCUMENTATION = '''

630

---

631

module: my_module

632

short_description: Example module

633

description:

634

- This is an example module

635

options:

636

name:

637

description:

638

- Name parameter

639

required: true

640

type: str

641

state:

642

description:

643

- Desired state

644

choices: ['present', 'absent']

645

default: present

646

type: str

647

'''

648

649

EXAMPLES = '''

650

- name: Ensure resource is present

651

my_module:

652

name: example

653

state: present

654

'''

655

656

RETURN = '''

657

changed:

658

description: Whether changes were made

659

type: bool

660

returned: always

661

message:

662

description: Result message

663

type: str

664

returned: always

665

'''

666

667

def main():

668

argument_spec = dict(

669

name=dict(type='str', required=True),

670

state=dict(type='str', default='present', choices=['present', 'absent'])

671

)

672

673

module = AnsibleModule(

674

argument_spec=argument_spec,

675

supports_check_mode=True

676

)

677

678

name = module.params['name']

679

state = module.params['state']

680

changed = False

681

682

if module.check_mode:

683

module.exit_json(changed=changed, msg="Check mode - no changes made")

684

685

# Module logic here

686

if state == 'present':

687

# Create/update resource

688

changed = True

689

msg = f"Resource {name} created"

690

else:

691

# Remove resource

692

changed = True

693

msg = f"Resource {name} removed"

694

695

module.exit_json(changed=changed, msg=msg)

696

697

if __name__ == '__main__':

698

main()

699

```

700

701

### Advanced Module with Validation

702

703

```python

704

from ansible.module_utils.basic import AnsibleModule

705

from ansible.module_utils.common.validation import check_required_arguments

706

707

def validate_parameters(module):

708

"""Custom parameter validation"""

709

params = module.params

710

711

if params['state'] == 'present' and not params.get('config'):

712

module.fail_json(msg="config required when state is present")

713

714

if params.get('port') and not (1 <= params['port'] <= 65535):

715

module.fail_json(msg="port must be between 1 and 65535")

716

717

def main():

718

argument_spec = dict(

719

name=dict(type='str', required=True),

720

state=dict(type='str', default='present', choices=['present', 'absent']),

721

config=dict(type='dict'),

722

port=dict(type='int'),

723

enable_ssl=dict(type='bool', default=False),

724

ssl_cert=dict(type='path'),

725

ssl_key=dict(type='path', no_log=True)

726

)

727

728

module = AnsibleModule(

729

argument_spec=argument_spec,

730

supports_check_mode=True,

731

required_together=[('ssl_cert', 'ssl_key')],

732

required_if=[('enable_ssl', True, ('ssl_cert', 'ssl_key'))]

733

)

734

735

# Custom validation

736

validate_parameters(module)

737

738

# Module implementation

739

result = {'changed': False}

740

741

try:

742

# Execute module logic

743

if module.params['state'] == 'present':

744

# Implementation here

745

result['changed'] = True

746

result['msg'] = 'Resource created successfully'

747

748

module.exit_json(**result)

749

750

except Exception as e:

751

module.fail_json(msg=f"Module failed: {str(e)}")

752

753

if __name__ == '__main__':

754

main()

755

```

756

757

## Usage Examples

758

759

### Using Module Utils in Custom Modules

760

761

```python

762

from ansible.module_utils.basic import AnsibleModule

763

from ansible.module_utils.common.text.converters import to_text, to_bytes

764

from ansible.module_utils.common.validation import check_type_dict

765

from ansible.module_utils.common.dict_transformations import dict_merge

766

import json

767

768

def process_config(module, config_data):

769

"""Process configuration with utilities"""

770

771

# Validate input

772

config = check_type_dict(config_data)

773

774

# Convert text encoding

775

processed_config = {}

776

for key, value in config.items():

777

key_text = to_text(key)

778

value_text = to_text(value) if isinstance(value, (str, bytes)) else value

779

processed_config[key_text] = value_text

780

781

# Merge with defaults

782

defaults = {'timeout': 30, 'retries': 3}

783

final_config = dict_merge(defaults, processed_config)

784

785

return final_config

786

787

def run_external_command(module, cmd):

788

"""Execute external command safely"""

789

790

rc, stdout, stderr = module.run_command(cmd, check_rc=False)

791

792

if rc != 0:

793

module.fail_json(

794

msg=f"Command failed: {cmd}",

795

rc=rc,

796

stdout=stdout,

797

stderr=stderr

798

)

799

800

return to_text(stdout).strip()

801

```

802

803

### Error Handling and Logging

804

805

```python

806

def safe_operation(module):

807

"""Example of safe operation with error handling"""

808

809

try:

810

# Risky operation

811

result = perform_operation()

812

813

# Sanitize sensitive data

814

from ansible.module_utils.common.parameters import sanitize_keys

815

safe_result = sanitize_keys(result, ['password', 'secret'])

816

817

return safe_result

818

819

except Exception as e:

820

module.fail_json(

821

msg=f"Operation failed: {str(e)}",

822

exception=traceback.format_exc()

823

)

824

```