or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

azure-batch.mdazure-data-explorer.mdazure-file-share.mdblob-storage.mdcontainer-services.mdcosmos-db.mddata-factory.mddata-lake-storage.mddata-transfers.mdindex.mdmicrosoft-graph.mdpowerbi.mdservice-bus.mdsynapse-analytics.md

container-services.mddocs/

0

# Azure Container Services

1

2

Complete Azure Container Services integration providing comprehensive container orchestration capabilities including Azure Container Instances management, Container Registry operations, and Container Volume handling for containerized workloads.

3

4

## Capabilities

5

6

### Azure Container Instances Hook

7

8

Primary interface for Azure Container Instances management, providing authenticated connections and container lifecycle operations.

9

10

```python { .api }

11

class AzureContainerInstanceHook(BaseHook):

12

"""

13

Hook for Azure Container Instances management.

14

15

Provides methods for creating, managing, and monitoring container instances

16

with support for various container configurations and networking options.

17

"""

18

19

def get_conn(self) -> ContainerInstanceManagementClient:

20

"""

21

Get authenticated Azure Container Instance management client.

22

23

Returns:

24

ContainerInstanceManagementClient: Container management client instance

25

"""

26

27

def create_or_update(

28

self,

29

resource_group_name: str,

30

container_group_name: str,

31

container_group: ContainerGroup

32

) -> ContainerGroup:

33

"""

34

Create or update a container group.

35

36

Args:

37

resource_group_name (str): Name of the resource group

38

container_group_name (str): Name of the container group

39

container_group (ContainerGroup): Container group configuration

40

41

Returns:

42

ContainerGroup: Created or updated container group

43

"""

44

45

def get_state_exitcode_details(

46

self,

47

resource_group_name: str,

48

container_group_name: str,

49

container_name: str

50

) -> tuple[str, int, str]:

51

"""

52

Get container state, exit code, and detailed information.

53

54

Args:

55

resource_group_name (str): Name of the resource group

56

container_group_name (str): Name of the container group

57

container_name (str): Name of the container

58

59

Returns:

60

tuple[str, int, str]: State, exit code, and details

61

"""

62

63

def get_logs(

64

self,

65

resource_group_name: str,

66

container_group_name: str,

67

container_name: str,

68

tail: int | None = None

69

) -> str:

70

"""

71

Get logs from a running or terminated container.

72

73

Args:

74

resource_group_name (str): Name of the resource group

75

container_group_name (str): Name of the container group

76

container_name (str): Name of the container

77

tail (int | None): Number of log lines to retrieve from the end

78

79

Returns:

80

str: Container logs

81

"""

82

83

def delete(

84

self,

85

resource_group_name: str,

86

container_group_name: str

87

) -> None:

88

"""

89

Delete a container group.

90

91

Args:

92

resource_group_name (str): Name of the resource group

93

container_group_name (str): Name of the container group to delete

94

"""

95

96

def exists(

97

self,

98

resource_group_name: str,

99

container_group_name: str

100

) -> bool:

101

"""

102

Check if a container group exists.

103

104

Args:

105

resource_group_name (str): Name of the resource group

106

container_group_name (str): Name of the container group

107

108

Returns:

109

bool: True if container group exists, False otherwise

110

"""

111

112

def get_state(

113

self,

114

resource_group_name: str,

115

container_group_name: str,

116

container_name: str

117

) -> str:

118

"""

119

Get the current state of a container.

120

121

Args:

122

resource_group_name (str): Name of the resource group

123

container_group_name (str): Name of the container group

124

container_name (str): Name of the container

125

126

Returns:

127

str: Current container state (Running, Terminated, Waiting, etc.)

128

"""

129

130

def get_messages(

131

self,

132

resource_group_name: str,

133

container_group_name: str,

134

container_name: str

135

) -> list[str]:

136

"""

137

Get status messages from a container.

138

139

Args:

140

resource_group_name (str): Name of the resource group

141

container_group_name (str): Name of the container group

142

container_name (str): Name of the container

143

144

Returns:

145

list[str]: List of container status messages

146

"""

147

148

def test_connection(self) -> tuple[bool, str]:

149

"""

150

Test the Azure Container Instance connection.

151

152

Returns:

153

tuple[bool, str]: Success status and message

154

"""

155

```

156

157

### Azure Container Registry Hook

158

159

Hook for Azure Container Registry operations providing image management and credential handling capabilities.

160

161

```python { .api }

162

class AzureContainerRegistryHook(BaseHook):

163

"""

164

Hook for Azure Container Registry operations.

165

166

Provides methods for managing container registries, retrieving credentials,

167

and handling image operations.

168

"""

169

170

def get_conn(self) -> ImageRegistryCredential:

171

"""

172

Get registry credentials for authentication.

173

174

Returns:

175

ImageRegistryCredential: Registry credentials for authentication

176

"""

177

178

def get_registry_credentials(

179

self,

180

registry_name: str,

181

resource_group_name: str

182

) -> dict[str, str]:

183

"""

184

Get container registry admin credentials.

185

186

Args:

187

registry_name (str): Name of the container registry

188

resource_group_name (str): Name of the resource group

189

190

Returns:

191

dict[str, str]: Registry credentials including username and passwords

192

"""

193

194

def get_login_server(

195

self,

196

registry_name: str,

197

resource_group_name: str

198

) -> str:

199

"""

200

Get the login server URL for the container registry.

201

202

Args:

203

registry_name (str): Name of the container registry

204

resource_group_name (str): Name of the resource group

205

206

Returns:

207

str: Login server URL

208

"""

209

210

def list_repositories(

211

self,

212

registry_name: str,

213

resource_group_name: str

214

) -> list[str]:

215

"""

216

List all repositories in the container registry.

217

218

Args:

219

registry_name (str): Name of the container registry

220

resource_group_name (str): Name of the resource group

221

222

Returns:

223

list[str]: List of repository names

224

"""

225

226

def list_tags(

227

self,

228

registry_name: str,

229

resource_group_name: str,

230

repository_name: str

231

) -> list[str]:

232

"""

233

List all tags for a specific repository.

234

235

Args:

236

registry_name (str): Name of the container registry

237

resource_group_name (str): Name of the resource group

238

repository_name (str): Name of the repository

239

240

Returns:

241

list[str]: List of image tags

242

"""

243

244

def delete_repository(

245

self,

246

registry_name: str,

247

resource_group_name: str,

248

repository_name: str

249

) -> None:

250

"""

251

Delete a repository from the container registry.

252

253

Args:

254

registry_name (str): Name of the container registry

255

resource_group_name (str): Name of the resource group

256

repository_name (str): Name of the repository to delete

257

"""

258

259

def delete_tag(

260

self,

261

registry_name: str,

262

resource_group_name: str,

263

repository_name: str,

264

tag: str

265

) -> None:

266

"""

267

Delete a specific tag from a repository.

268

269

Args:

270

registry_name (str): Name of the container registry

271

resource_group_name (str): Name of the resource group

272

repository_name (str): Name of the repository

273

tag (str): Tag to delete

274

"""

275

276

def test_connection(self) -> tuple[bool, str]:

277

"""

278

Test the Azure Container Registry connection.

279

280

Returns:

281

tuple[bool, str]: Success status and message

282

"""

283

```

284

285

### Azure Container Volume Hook

286

287

Hook for Azure Container Volume management providing persistent storage capabilities for containers.

288

289

```python { .api }

290

class AzureContainerVolumeHook(BaseHook):

291

"""

292

Hook for Azure Container Volume management.

293

294

Provides methods for creating and managing persistent volumes

295

for Azure Container Instances with various storage backends.

296

"""

297

298

def get_conn(self) -> Any:

299

"""

300

Get authenticated connection for volume operations.

301

302

Returns:

303

Any: Volume management client

304

"""

305

306

def create_file_share_volume(

307

self,

308

volume_name: str,

309

share_name: str,

310

storage_account_name: str,

311

storage_account_key: str,

312

read_only: bool = False

313

) -> Volume:

314

"""

315

Create a volume backed by Azure File Share.

316

317

Args:

318

volume_name (str): Name of the volume

319

share_name (str): Name of the Azure File Share

320

storage_account_name (str): Storage account name

321

storage_account_key (str): Storage account key

322

read_only (bool): Whether the volume is read-only (default: False)

323

324

Returns:

325

Volume: Created volume configuration

326

"""

327

328

def create_secret_volume(

329

self,

330

volume_name: str,

331

secrets: dict[str, str]

332

) -> Volume:

333

"""

334

Create a volume for storing secrets.

335

336

Args:

337

volume_name (str): Name of the volume

338

secrets (dict[str, str]): Dictionary of secret files and content

339

340

Returns:

341

Volume: Created secret volume configuration

342

"""

343

344

def create_empty_dir_volume(

345

self,

346

volume_name: str

347

) -> Volume:

348

"""

349

Create an empty directory volume.

350

351

Args:

352

volume_name (str): Name of the volume

353

354

Returns:

355

Volume: Created empty directory volume configuration

356

"""

357

358

def create_git_repo_volume(

359

self,

360

volume_name: str,

361

repository_url: str,

362

directory_name: str | None = None,

363

revision: str | None = None

364

) -> Volume:

365

"""

366

Create a volume from a Git repository.

367

368

Args:

369

volume_name (str): Name of the volume

370

repository_url (str): URL of the Git repository

371

directory_name (str | None): Directory to clone into

372

revision (str | None): Specific revision to clone

373

374

Returns:

375

Volume: Created Git repository volume configuration

376

"""

377

378

def test_connection(self) -> tuple[bool, str]:

379

"""

380

Test the Azure Container Volume connection.

381

382

Returns:

383

tuple[bool, str]: Success status and message

384

"""

385

```

386

387

## Container Services Operators

388

389

Execute Azure Container Services operations as Airflow tasks with comprehensive container management capabilities.

390

391

### Azure Container Instances Operator

392

393

```python { .api }

394

class AzureContainerInstancesOperator(BaseOperator):

395

"""

396

Runs containers on Azure Container Instances.

397

398

Supports creating and managing containerized workloads with custom

399

configurations, networking, and volume mounting options.

400

"""

401

402

def __init__(

403

self,

404

*,

405

ci_conn_id: str = "azure_container_instance_default",

406

registry_conn_id: str | None = None,

407

resource_group: str,

408

name: str,

409

image: str,

410

region: str = "West US",

411

environment_variables: dict[str, str] | None = None,

412

secured_variables: list[str] | None = None,

413

volumes: list[Volume] | None = None,

414

volume_mounts: list[VolumeMount] | None = None,

415

memory_in_gb: float = 1.5,

416

cpu: float = 1.0,

417

gpu: GpuResource | None = None,

418

command: list[str] | None = None,

419

restart_policy: str = "Never",

420

os_type: str = "Linux",

421

ports: list[ContainerPort] | None = None,

422

dns_name_label: str | None = None,

423

ip_address_type: str = "Public",

424

network_profile: ContainerGroupNetworkProfile | None = None,

425

tags: dict[str, str] | None = None,

426

**kwargs

427

):

428

"""

429

Initialize Azure Container Instances operator.

430

431

Args:

432

ci_conn_id (str): Airflow connection ID for Container Instances

433

registry_conn_id (str | None): Connection ID for container registry

434

resource_group (str): Azure resource group name

435

name (str): Container group name

436

image (str): Container image to run

437

region (str): Azure region (default: "West US")

438

environment_variables (dict[str, str] | None): Environment variables

439

secured_variables (list[str] | None): Secured environment variables

440

volumes (list[Volume] | None): Volumes to mount

441

volume_mounts (list[VolumeMount] | None): Volume mount configurations

442

memory_in_gb (float): Memory allocation in GB (default: 1.5)

443

cpu (float): CPU allocation (default: 1.0)

444

gpu (GpuResource | None): GPU resource configuration

445

command (list[str] | None): Command to run in container

446

restart_policy (str): Restart policy (default: "Never")

447

os_type (str): Operating system type (default: "Linux")

448

ports (list[ContainerPort] | None): Port configurations

449

dns_name_label (str | None): DNS name label for public IP

450

ip_address_type (str): IP address type (default: "Public")

451

network_profile (ContainerGroupNetworkProfile | None): Network profile

452

tags (dict[str, str] | None): Resource tags

453

"""

454

455

def execute(self, context: Context) -> str:

456

"""

457

Execute container instance creation and management.

458

459

Args:

460

context (Context): Airflow task context

461

462

Returns:

463

str: Container execution results or status

464

"""

465

466

def on_kill(self) -> None:

467

"""Clean up container resources on task termination."""

468

```

469

470

## Usage Examples

471

472

### Basic Container Execution

473

474

```python

475

from airflow import DAG

476

from airflow.providers.microsoft.azure.operators.container_instances import AzureContainerInstancesOperator

477

from airflow.operators.python import PythonOperator

478

from datetime import datetime, timedelta

479

480

def check_container_results(**context):

481

"""Check and process container execution results."""

482

result = context['task_instance'].xcom_pull(task_ids='run_data_processing')

483

print(f"Container execution result: {result}")

484

485

dag = DAG(

486

'azure_container_workflow',

487

default_args={

488

'owner': 'container-team',

489

'retries': 2,

490

'retry_delay': timedelta(minutes=5)

491

},

492

description='Azure Container Instances workflow',

493

schedule_interval=timedelta(hours=6),

494

start_date=datetime(2024, 1, 1),

495

catchup=False

496

)

497

498

# Run data processing container

499

run_container = AzureContainerInstancesOperator(

500

task_id='run_data_processing',

501

ci_conn_id='azure_container_conn',

502

resource_group='data-processing-rg',

503

name='data-processor-{{ ds_nodash }}',

504

image='myregistry.azurecr.io/data-processor:latest',

505

region='East US',

506

memory_in_gb=4.0,

507

cpu=2.0,

508

environment_variables={

509

'INPUT_PATH': '/data/input',

510

'OUTPUT_PATH': '/data/output',

511

'PROCESSING_MODE': 'batch'

512

},

513

command=[

514

'python',

515

'process_data.py',

516

'--input', '/data/input',

517

'--output', '/data/output'

518

],

519

restart_policy='Never',

520

dag=dag

521

)

522

523

# Process results

524

check_results = PythonOperator(

525

task_id='check_results',

526

python_callable=check_container_results,

527

dag=dag

528

)

529

530

run_container >> check_results

531

```

532

533

### Advanced Container Configuration

534

535

```python

536

from airflow import DAG

537

from airflow.providers.microsoft.azure.operators.container_instances import AzureContainerInstancesOperator

538

from airflow.providers.microsoft.azure.hooks.container_volume import AzureContainerVolumeHook

539

from azure.mgmt.containerinstance.models import (

540

Volume, VolumeMount, ContainerPort, GpuResource,

541

ContainerGroupNetworkProfile, ResourceRequests, ResourceRequirements

542

)

543

from datetime import datetime, timedelta

544

545

def setup_volumes():

546

"""Set up volumes for container workload."""

547

volume_hook = AzureContainerVolumeHook(azure_container_volume_conn_id='volume_conn')

548

549

# Create file share volume for persistent storage

550

data_volume = volume_hook.create_file_share_volume(

551

volume_name='data-volume',

552

share_name='container-data',

553

storage_account_name='mystorageaccount',

554

storage_account_key='storage-key-here',

555

read_only=False

556

)

557

558

# Create secret volume for configuration

559

config_volume = volume_hook.create_secret_volume(

560

volume_name='config-volume',

561

secrets={

562

'config.json': '{"database": "prod", "debug": false}',

563

'secrets.env': 'DB_PASSWORD=secret123\nAPI_KEY=key456'

564

}

565

)

566

567

return [data_volume, config_volume]

568

569

dag = DAG(

570

'advanced_container_workflow',

571

default_args={

572

'owner': 'ml-team',

573

'retries': 1,

574

'retry_delay': timedelta(minutes=3)

575

},

576

description='Advanced container workflow with GPU and volumes',

577

schedule_interval=timedelta(days=1),

578

start_date=datetime(2024, 1, 1),

579

catchup=False

580

)

581

582

# Configure volumes

583

volumes = [

584

Volume(

585

name='data-volume',

586

azure_file={

587

'share_name': 'ml-data',

588

'storage_account_name': 'mlstorageaccount',

589

'storage_account_key': 'storage-key'

590

}

591

),

592

Volume(

593

name='model-volume',

594

azure_file={

595

'share_name': 'ml-models',

596

'storage_account_name': 'mlstorageaccount',

597

'storage_account_key': 'storage-key',

598

'read_only': True

599

}

600

)

601

]

602

603

# Configure volume mounts

604

volume_mounts = [

605

VolumeMount(

606

name='data-volume',

607

mount_path='/data',

608

read_only=False

609

),

610

VolumeMount(

611

name='model-volume',

612

mount_path='/models',

613

read_only=True

614

)

615

]

616

617

# Configure GPU resources for ML workload

618

gpu_resource = GpuResource(

619

count=1,

620

sku='K80'

621

)

622

623

# Configure network ports

624

ports = [

625

ContainerPort(port=8080, protocol='TCP'),

626

ContainerPort(port=8443, protocol='TCP')

627

]

628

629

# Run ML training container with GPU

630

ml_training = AzureContainerInstancesOperator(

631

task_id='run_ml_training',

632

ci_conn_id='azure_container_conn',

633

registry_conn_id='azure_container_registry_conn',

634

resource_group='ml-training-rg',

635

name='ml-trainer-{{ ds_nodash }}',

636

image='mlregistry.azurecr.io/trainer:v2.1',

637

region='East US',

638

memory_in_gb=16.0,

639

cpu=4.0,

640

gpu=gpu_resource,

641

volumes=volumes,

642

volume_mounts=volume_mounts,

643

ports=ports,

644

environment_variables={

645

'DATASET_PATH': '/data/training_set.csv',

646

'MODEL_OUTPUT_PATH': '/data/models',

647

'EPOCHS': '100',

648

'BATCH_SIZE': '32',

649

'LEARNING_RATE': '0.001'

650

},

651

secured_variables=['DB_PASSWORD', 'API_SECRET_KEY'],

652

command=[

653

'python',

654

'train_model.py',

655

'--config', '/config/training_config.json',

656

'--data-path', '/data',

657

'--model-path', '/models',

658

'--gpu'

659

],

660

restart_policy='Never',

661

dns_name_label='ml-trainer-{{ ds_nodash }}',

662

tags={

663

'project': 'machine-learning',

664

'environment': 'production',

665

'cost-center': 'research'

666

},

667

dag=dag

668

)

669

670

# Run inference container

671

ml_inference = AzureContainerInstancesOperator(

672

task_id='run_ml_inference',

673

ci_conn_id='azure_container_conn',

674

registry_conn_id='azure_container_registry_conn',

675

resource_group='ml-inference-rg',

676

name='ml-inference-{{ ds_nodash }}',

677

image='mlregistry.azurecr.io/inference:v2.1',

678

region='East US',

679

memory_in_gb=8.0,

680

cpu=2.0,

681

volumes=[volumes[0]], # Only data volume needed

682

volume_mounts=[volume_mounts[0]],

683

environment_variables={

684

'MODEL_PATH': '/data/models/latest_model.pkl',

685

'INPUT_PATH': '/data/inference_input.csv',

686

'OUTPUT_PATH': '/data/inference_output.csv'

687

},

688

command=[

689

'python',

690

'run_inference.py',

691

'--model', '/data/models/latest_model.pkl',

692

'--input', '/data/inference_input.csv',

693

'--output', '/data/inference_output.csv'

694

],

695

restart_policy='Never',

696

dag=dag

697

)

698

699

ml_training >> ml_inference

700

```

701

702

### Container Registry Integration

703

704

```python

705

from airflow import DAG

706

from airflow.providers.microsoft.azure.hooks.container_registry import AzureContainerRegistryHook

707

from airflow.operators.python import PythonOperator

708

from datetime import datetime, timedelta

709

710

def manage_container_images():

711

"""Manage container registry images."""

712

registry_hook = AzureContainerRegistryHook(

713

azure_container_registry_conn_id='registry_conn'

714

)

715

716

registry_name = 'myregistry'

717

resource_group = 'container-rg'

718

719

# Get registry credentials

720

credentials = registry_hook.get_registry_credentials(

721

registry_name=registry_name,

722

resource_group_name=resource_group

723

)

724

print(f"Registry username: {credentials['username']}")

725

726

# Get login server

727

login_server = registry_hook.get_login_server(

728

registry_name=registry_name,

729

resource_group_name=resource_group

730

)

731

print(f"Login server: {login_server}")

732

733

# List repositories

734

repositories = registry_hook.list_repositories(

735

registry_name=registry_name,

736

resource_group_name=resource_group

737

)

738

print(f"Found repositories: {repositories}")

739

740

# List tags for each repository

741

for repo in repositories:

742

tags = registry_hook.list_tags(

743

registry_name=registry_name,

744

resource_group_name=resource_group,

745

repository_name=repo

746

)

747

print(f"Repository {repo} tags: {tags}")

748

749

# Clean up old tags (keep only latest 5)

750

if len(tags) > 5:

751

old_tags = sorted(tags)[:-5] # Keep latest 5

752

for old_tag in old_tags:

753

try:

754

registry_hook.delete_tag(

755

registry_name=registry_name,

756

resource_group_name=resource_group,

757

repository_name=repo,

758

tag=old_tag

759

)

760

print(f"Deleted old tag: {repo}:{old_tag}")

761

except Exception as e:

762

print(f"Failed to delete tag {old_tag}: {e}")

763

764

def monitor_container_execution():

765

"""Monitor running container instances."""

766

from airflow.providers.microsoft.azure.hooks.container_instance import AzureContainerInstanceHook

767

768

aci_hook = AzureContainerInstanceHook(azure_container_instance_conn_id='aci_conn')

769

770

resource_group = 'container-rg'

771

container_group = 'data-processor'

772

container_name = 'processor'

773

774

# Check if container exists

775

if aci_hook.exists(resource_group, container_group):

776

# Get container state

777

state = aci_hook.get_state(resource_group, container_group, container_name)

778

print(f"Container state: {state}")

779

780

# Get logs if container is running or terminated

781

if state in ['Running', 'Terminated']:

782

logs = aci_hook.get_logs(

783

resource_group,

784

container_group,

785

container_name,

786

tail=100

787

)

788

print(f"Container logs:\n{logs}")

789

790

# Get detailed state information

791

state, exit_code, details = aci_hook.get_state_exitcode_details(

792

resource_group,

793

container_group,

794

container_name

795

)

796

print(f"State: {state}, Exit Code: {exit_code}, Details: {details}")

797

798

# Get status messages

799

messages = aci_hook.get_messages(resource_group, container_group, container_name)

800

for message in messages:

801

print(f"Status message: {message}")

802

803

dag = DAG(

804

'container_registry_management',

805

default_args={

806

'owner': 'devops-team',

807

'retries': 1,

808

'retry_delay': timedelta(minutes=2)

809

},

810

description='Container registry and instance management',

811

schedule_interval=timedelta(hours=12),

812

start_date=datetime(2024, 1, 1),

813

catchup=False

814

)

815

816

manage_images = PythonOperator(

817

task_id='manage_registry_images',

818

python_callable=manage_container_images,

819

dag=dag

820

)

821

822

monitor_containers = PythonOperator(

823

task_id='monitor_containers',

824

python_callable=monitor_container_execution,

825

dag=dag

826

)

827

828

manage_images >> monitor_containers

829

```

830

831

## Connection Configuration

832

833

### Container Instances Connection (`azure_container_instance`)

834

835

Configure Azure Container Instances connections in Airflow:

836

837

```python

838

# Connection configuration for Container Instances

839

{

840

"conn_id": "azure_container_instance_default",

841

"conn_type": "azure_container_instance",

842

"extra": {

843

"subscriptionId": "your-subscription-id",

844

"tenantId": "your-tenant-id",

845

"clientId": "your-client-id",

846

"clientSecret": "your-client-secret"

847

}

848

}

849

```

850

851

### Container Registry Connection (`azure_container_registry`)

852

853

Configure Azure Container Registry connections in Airflow:

854

855

```python

856

# Connection configuration for Container Registry

857

{

858

"conn_id": "azure_container_registry_default",

859

"conn_type": "azure_container_registry",

860

"login": "myregistry", # Registry name

861

"host": "myregistry.azurecr.io", # Registry URL

862

"extra": {

863

"subscriptionId": "your-subscription-id",

864

"resourceGroupName": "your-resource-group",

865

"tenantId": "your-tenant-id",

866

"clientId": "your-client-id",

867

"clientSecret": "your-client-secret"

868

}

869

}

870

```

871

872

### Container Volume Connection (`azure_container_volume`)

873

874

Configure Azure Container Volume connections in Airflow:

875

876

```python

877

# Connection configuration for Container Volume

878

{

879

"conn_id": "azure_container_volume_default",

880

"conn_type": "azure_container_volume",

881

"extra": {

882

"tenantId": "your-tenant-id",

883

"clientId": "your-client-id",

884

"clientSecret": "your-client-secret"

885

}

886

}

887

```

888

889

### Authentication Methods

890

891

All container services support multiple authentication methods:

892

893

1. **Service Principal Authentication**:

894

```python

895

extra = {

896

"tenantId": "your-tenant-id",

897

"clientId": "your-client-id",

898

"clientSecret": "your-client-secret"

899

}

900

```

901

902

2. **Managed Identity Authentication**:

903

```python

904

extra = {

905

"managedIdentityClientId": "your-managed-identity-client-id"

906

}

907

```

908

909

3. **Azure CLI Authentication**:

910

```python

911

extra = {

912

"use_azure_cli": True

913

}

914

```

915

916

## Error Handling

917

918

### Common Exception Patterns

919

920

```python

921

from azure.core.exceptions import ResourceNotFoundError, ResourceExistsError

922

from azure.mgmt.containerinstance.models import ContainerGroup

923

from airflow.providers.microsoft.azure.hooks.container_instance import AzureContainerInstanceHook

924

925

def robust_container_operations():

926

"""Demonstrate error handling patterns for container operations."""

927

hook = AzureContainerInstanceHook(azure_container_instance_conn_id='aci_conn')

928

929

resource_group = 'my-rg'

930

container_group_name = 'my-container-group'

931

932

try:

933

# Check if container group exists before creating

934

if hook.exists(resource_group, container_group_name):

935

print("Container group already exists, deleting first...")

936

hook.delete(resource_group, container_group_name)

937

# Wait for deletion to complete

938

import time

939

time.sleep(30)

940

941

# Create container group

942

container_group = ContainerGroup(

943

location='East US',

944

containers=[],

945

os_type='Linux'

946

)

947

948

result = hook.create_or_update(

949

resource_group_name=resource_group,

950

container_group_name=container_group_name,

951

container_group=container_group

952

)

953

print(f"Container group created: {result.name}")

954

955

except ResourceNotFoundError as e:

956

print(f"Resource not found: {e}")

957

# Handle missing resource group or other dependencies

958

959

except ResourceExistsError as e:

960

print(f"Resource already exists: {e}")

961

# Handle existing resources

962

963

except Exception as e:

964

print(f"Unexpected error: {e}")

965

# Cleanup on failure

966

try:

967

hook.delete(resource_group, container_group_name)

968

except:

969

pass # Ignore cleanup errors

970

raise

971

```

972

973

### Connection Testing

974

975

```python

976

def test_container_connections():

977

"""Test all container service connections."""

978

979

# Test Container Instances connection

980

try:

981

aci_hook = AzureContainerInstanceHook(azure_container_instance_conn_id='aci_conn')

982

success, message = aci_hook.test_connection()

983

print(f"Container Instances: {message}")

984

except Exception as e:

985

print(f"Container Instances connection failed: {e}")

986

987

# Test Container Registry connection

988

try:

989

acr_hook = AzureContainerRegistryHook(azure_container_registry_conn_id='acr_conn')

990

success, message = acr_hook.test_connection()

991

print(f"Container Registry: {message}")

992

except Exception as e:

993

print(f"Container Registry connection failed: {e}")

994

995

# Test Container Volume connection

996

try:

997

volume_hook = AzureContainerVolumeHook(azure_container_volume_conn_id='volume_conn')

998

success, message = volume_hook.test_connection()

999

print(f"Container Volume: {message}")

1000

except Exception as e:

1001

print(f"Container Volume connection failed: {e}")

1002

```

1003

1004

## Performance Considerations

1005

1006

### Optimizing Container Workloads

1007

1008

```python

1009

def optimize_container_performance():

1010

"""Demonstrate performance optimization techniques."""

1011

1012

# Use appropriate resource sizing

1013

memory_optimized_config = {

1014

'memory_in_gb': 8.0, # Adequate memory for workload

1015

'cpu': 2.0, # Balanced CPU allocation

1016

}

1017

1018

# Configure restart policies appropriately

1019

batch_job_config = {

1020

'restart_policy': 'Never', # For batch jobs

1021

}

1022

1023

long_running_config = {

1024

'restart_policy': 'Always', # For services

1025

}

1026

1027

# Use local SSD storage for temporary files

1028

volume_config = [

1029

Volume(

1030

name='temp-volume',

1031

empty_dir={} # Uses local SSD storage

1032

)

1033

]

1034

1035

# Pre-pull images for faster startup

1036

# This would be done in the registry/image management process

1037

1038

return {

1039

'optimized_resources': memory_optimized_config,

1040

'batch_config': batch_job_config,

1041

'service_config': long_running_config,

1042

'volume_config': volume_config

1043

}

1044

1045

def implement_container_monitoring():

1046

"""Implement comprehensive container monitoring."""

1047

hook = AzureContainerInstanceHook(azure_container_instance_conn_id='aci_conn')

1048

1049

def monitor_container_health(resource_group: str, container_group: str, container_name: str):

1050

"""Monitor container health and performance."""

1051

1052

# Get current state

1053

state = hook.get_state(resource_group, container_group, container_name)

1054

1055

# Get recent logs for error detection

1056

logs = hook.get_logs(resource_group, container_group, container_name, tail=50)

1057

1058

# Check for error patterns in logs

1059

error_keywords = ['ERROR', 'FATAL', 'Exception', 'Failed']

1060

errors_found = []

1061

1062

for line in logs.split('\n'):

1063

for keyword in error_keywords:

1064

if keyword in line:

1065

errors_found.append(line.strip())

1066

1067

# Get detailed status information

1068

state, exit_code, details = hook.get_state_exitcode_details(

1069

resource_group, container_group, container_name

1070

)

1071

1072

health_status = {

1073

'state': state,

1074

'exit_code': exit_code,

1075

'details': details,

1076

'errors_found': errors_found,

1077

'healthy': state == 'Running' and len(errors_found) == 0

1078

}

1079

1080

return health_status

1081

1082

return monitor_container_health

1083

```

1084

1085

This comprehensive documentation covers all Azure Container Services capabilities in the Apache Airflow Microsoft Azure Provider, including Container Instances, Container Registry, and Container Volume management with practical usage patterns and optimization techniques.