> This is part 1 of 3 of the full documentation (pages 1–100 of 241).
> The content is paginated: fetch every part to see all of it.
> Next part: https://docs.ionos.com/ansible/llms-full.txt/1
> Page index: https://docs.ionos.com/ansible/llms.txt

# Introduction

## Introduction

### Overview

Ansible is an IT automation tool that allows you to configure, deploy, and orchestrate advanced tasks, such as continuous deployments or zero downtime rolling updates. The IONOS module for Ansible leverages the IONOS CLOUD API.

### Getting Started

The module is also available on [Ansible Galaxy](https://galaxy.ansible.com/ionoscloudsdk/ionoscloud).

The IONOS module for Ansible requires the following:

* IONOS CLOUD account
* Python >= 3.5
* [Ansible](https://www.ansible.com/)
* [IONOS CLOUD **Compute Engine** Python SDK](https://pypi.org/project/ionoscloud/) >= 6.1.6
* [IONOS CLOUD **DBaaS PostgreSQL** Python SDK](https://pypi.org/project/ionoscloud-dbaas-postgres/) >= 1.1.1
* [IONOS CLOUD **DBaaS MongoDB** Python SDK](https://pypi.org/project/ionoscloud-dbaas-mongo/) >= 1.2.2
* [IONOS CLOUD **Container Registry** Python SDK](https://pypi.org/project/ionoscloud-container-registry/) >= 1.0.0
* [IONOS CLOUD **Certificate Manager** Python SDK](https://pypi.org/project/ionoscloud-cert-manager/) >= 1.0.0

> ***NOTE:*** The Ansible module does not support Python 2. It only supports Python >= 3.5.

Before you begin you will need an IONOS account. The credentials from your registration will be used to authenticate against the IONOS CLOUD API.

Ansible must also be installed before the IONOS module can be used. Please review the official [Ansible Documentation](http://docs.ansible.com/ansible/intro_installation.html) for more information on installing Ansible.

The IONOS module requires the IONOS SDK for Python to be installed. This can easily be accomplished with Python PyPI:

```bash
pip install ionoscloud
pip install ionoscloud-dbaas-postgres
pip install ionoscloud-dbaas-mongo
pip install ionoscloud-container-registry
pip install ionoscloud-cert-manager
```

## Installation

### I. Using Ansible galaxy *(recommended)*

Run the following command:

```bash
ansible-galaxy collection install ionoscloudsdk.ionoscloud
```

### II. Downloading the module from GitHub

1. The IONOS module for Ansible must first be downloaded from GitHub. This can be accomplished a few different ways such as downloading and extracting the archive using `curl` or cloning the GitHub repository locally.

Download and extract with `curl`:

```bash
mkdir -p ionos-module-ansible && curl -L https://github.com/ionos-cloud/module-ansible/tarball/master | tar zx -C ionos-module-ansible/ --strip-components=1
```

Clone the GitHub repository locally:

```bash
git clone https://github.com/ionos-cloud/module-ansible
```

2. Install the collection with ansible-galaxy.

```bash
ansible-galaxy collection build .
ansible-galaxy collection install ionoscloudsdk-ionoscloud-<module_version>.tar.gz
```

### FAQ

1. How can I open a bug/feature request?

Bugs & feature requests can be open on the repository issues: <https://github.com/ionos-cloud/module-ansible/issues/new/choose>

2. Can I contribute to the Ansible Module?

Sure! Our repository is public, feel free to fork it and file a PR for one of the issues opened in the issues list. We will review it and work together to get it released.


# Changelog

## 7.10.0

### Features

* added new DBaaS MariaDB v2 modules `mariadb_cluster_v2`, `mariadb_cluster_v2_info`, `mariadb_backup_v2_info`, `mariadb_backup_location_v2_info` and `mariadb_version_v2_info`

### Changes

* updated the MariaDB SDK requirement to `ionoscloud_dbaas_mariadb>=3,<4`, the pydantic 2 SDK for the MariaDB v2 API, and pointed the MariaDB regional endpoints at their `/v2` path
* the v1 MariaDB modules (`mariadb_cluster`, `mariadb_cluster_info`, `mariadb_backup_info`) target the v1 API, which the new SDK no longer ships; use the `_v2` modules instead

### Fixes

* `postgres_cluster_v2` and `inmemorydb_cluster_v2` now return the cluster polled by the wait rather than the create/update response captured before it, so a task run with `wait: true` no longer reports `metadata.state` as `PROVISIONING` or `UPDATING` for a cluster that has already reached `AVAILABLE`
* `postgres_cluster_v2` and `inmemorydb_cluster_v2` now build the full-replacement PUT for `update` and `restore` from the cluster polled after the pre-update wait. The PUT falls back to the existing value for every field the caller did not supply, so a change that landed while the wait was in progress was previously sent back in its pre-wait form and reverted

## 7.9.0

### Features

* added new DBaaS In-Memory DB v2 modules `inmemorydb_cluster_v2`, `inmemorydb_cluster_v2_info`, `inmemorydb_snapshot_v2_info`, `inmemorydb_snapshot_location_v2_info` and `inmemorydb_version_v2_info`
* added support for the `de/fra/1` and `de/fra/2` locations to the `datacenter`, `server`, `vcpu_server` and MariaDB modules. Both are facilities inside the `de/fra` metro region and use the same regional endpoint. Note that some resources still exist only in `de/fra` itself
* added the missing `gb/bhx` endpoint to the MariaDB modules

### Changes

* modules with regional endpoints now fail with a clear message when given an unsupported `location`, instead of silently falling back to the SDK's default region. Setting `api_url` still overrides `location`, and skips the check

## 7.8.0

### Features

* added new DBaaS PostgreSQL v2 modules `postgres_cluster_v2`, `postgres_cluster_v2_info`, `postgres_backup_v2_info`, `postgres_backup_location_v2_info` and `postgres_version_v2_info`
* added volume performance classes `ESSENTIAL`, `BALANCED` and `PERFORMANCE` to the `disk_type` options of the `volume`, `server`, `cube_server` and `vcpu_server` modules

### Changes

* updated SDK requirements to the latest major releases (built on pydantic 2): `ionoscloud_dbaas_postgres>=3`, `ionoscloud_cert_manager>=3`, `ionoscloud_container_registry>=2`, `ionoscloud_dbaas_mariadb>=2`, `ionoscloud_dns>=2`, `ionoscloud_logging>=2`, `ionoscloud_object_storage_management>=2` and `ionoscloud_vm_autoscaling>=2`; older SDK versions are no longer supported

### Fixes

* `user` module now returns `changed=False` when the requested group membership already matches the user's current groups

### Docs

* regenerated module documentation from the latest API specifications, including Confidential Computing notes for `server` and `cube_server` and a replication mode deprecation note for `postgres_cluster`

## 7.7.1

### Fixes

* added pagination to DNS modules (`dns_zone`, `dns_zone_info`, `dns_record`, `dns_record_info`, `dns_secondary_zone`, `dns_secondary_zone_info`)
* fixed `AttributeError` caused by unsafe chained `.get()` calls in the `registry` module

### Docs

* added missing SDK requirements to README

### Changes

* aligned brand references to IONOS CLOUD across all user-facing content

## 7.7.0

### Features

* added new object storage management modules `object_storage_access_key_info`, `object_storage_access_key` and `object_storage_region_info`

## 7.6.0

### Features

* added check\_mode and diff to the `s3key` module
* added new certificate manager v2 modules `auto_certificate`, `auto_certificate_info`, `certificate_provider` and `certificate_provider_info`
* added `nic_multi_queue` to `server` and `vcpu_server`

### Fixes

* fixed `group_info` not working with user specified

### Changes

* changed `vcpu_server` module to be declarative, like the `server` module
* changed existing certificate manager to use the the certificate manager v2 API. Will not be compatible with sdk versions bellow 2.0.0
* removed dataplatform as the API was discontinued

## 7.5.3

### Changes

* change most arguments which have the possible values defined to only use them for the documentation instead of failing when the supplied value is not in the list
* cpu\_family does not default to INTEL\_ICELAKE anymore

### Fixes

* remove upgrade\_needed from server\_info as it was removed from the API
* use correct imports for Lan and LanProperties in cube\_server and vcpu\_server
* updated snapshot creation and restore methods to use new SDK object structure, the module is not longer compatible with sdks before 6.1.10

## 7.5.2

### Fixes

* use pagination to retrieve all datacenters when limit is exceeded
* show warning when resources are not found only for verbosity higher or equal to 3

## 7.5.1

### Features

* added location to mariadb modules

### Fixes

* throw error when data center is not found in volume modules

### Docs

* catch errors in docs generation

## 7.5.0

### Features

* Added check\_mode and diff to the user module
* Added ignored\_properties to the user module

### Changes

* use filters when retrieving user to speed up the request

### Fixes

* mark RegEx pattern as a raw string (fix by @jaudriga)

### Docs

* Added declarative modules page to summary

## 7.5.0-beta.1

### Features

* Added check\_mode and diff to the user module
* Added ignored\_properties to the user module

### Changes

* use filters when retrieving user to speed up the request

### Fixes

* mark RegEx pattern as a raw string (fix by @jaudriga)

### Docs

* Added declarative modules page to summary

## 7.4.1

### Fixes

* disk\_type on cube\_server now defaults to DAS, other arguments would have caused the call to fail

### Docs

* Added tutorials to docs, these show how this Ansible module can be used to provision many of our more commonly-used Compute resources and Managed Services in combinations that are at least *representative* of 'real-world' deployments.
* Updated the examples in the files to use the steps from our test playbooks to ensure they are working. This should fix numerous bugs within the examples.

## 7.4.0

### Features

* Added MariaDB modules
  * new modules: mariadb\_cluster, mariadb\_cluster\_info, mariadb\_backup\_info

## 7.3.0

* Refactor to use module\_utile to remove duplicate code.

### Changes

* Using ansible-galaxy when installing from github
* Modules called with the whole path(ionoscloudsdk.ionoscloud.\<module\_name>)
* allow\_replace and depth have been removed from modules that do not support replace, they can still be sent so past playbooks that use it do not fail

## 7.2.0

### Features

* Added Container Registry Vulnerability Scanning feature
  * new modules: registry\_artifact\_info, registry\_repository, registry\_repository\_info, registry\_vulnerability\_info
  * new argument for registry: features
* Added Private Kubernetes feature
  * new arguments for k8s\_cluster: public, location, nat\_gateway\_ip and node\_subnet

### Fixes

* Fixed argument lan not available in state present for module nic
* Fixed some wrong examples

### Known Issues

* When a registry is to be replaced while retaining the same name it would cause an error because the API does not allow two resources with the same name. Please change the name as well if you want to replace a registry for now

## 7.1.0

### Features

* Added Logging modules: pipeline and pipeline\_info
* Added VM Autoscaling modules: vm\_autoscaling\_group, vm\_autoscaling\_action\_info, vm\_autoscaling\_group\_info and vm\_autoscaling\_server\_info

## 7.0.0

### Features

* Added DNS modules: dns\_zone, dns\_record, dns\_secondary\_zone and corresponding info modules
* changed info modules to have the same format
* generating summary to include all modules, and split in them in subcategories
* Changed Private Cross Connect references in docs to Cross Connect

## 7.0.0-beta.1

### Features

* Reworked all modules to be declarative, for more details <https://github.com/ionos-cloud/module-ansible/blob/master/docs/usage/declarative\\_changes.md>
* changed info modules to have the same format
* added ipv6 support
* updated docs, added return examples and updated option descriptions

## 6.5.3

### Features

* Added support for [vCPU Servers](/ansible/api/compute-engine/modules/vcpu_server)

## 6.5.2

### Fixes

* Fixed error when exceeding maximum users per page

## 6.5.1

### Features

* New licenceType supported for `snapshot` and `volume` modules: `RHEL`
* Extend dynamic inventory to support regex-based grouping

## 6.5.0

### Features

* Implement filters for Container Registry info modules
* New Product: **DataPlatform**. Modules added:
  * dataplatform\_cluster
  * dataplatform\_cluster\_config
  * dataplatform\_cluster\_info
  * dataplatform\_nodepool
  * dataplatform\_nodepool\_info

⚠️ **Note:** Data Platform is currently in the Early Access (EA) phase. We recommend keeping usage and testing to non-production critical applications. Please contact your sales representative or support for more information.

### Fixes:

* Removed sensitive data from repository
* Fix #138 lan\_ids param is now a list of dicts

**Full Changelog**: <https://github.com/ionos-cloud/module-ansible/compare/v6.4.3...v6.5.0>

## 6.4.3

### Bug fixes:

* `k8s_version` is no longer a required parameter for cluster update

## 6.4.2

### Bug fixes:

* remove cpu\_family parameter from cube\_server module
* Cube Server documentation is now available on docs.ionos.com

## 6.4.1

### Features:

* added new modules for Container Registry (registry, registry\_token, registry\_info and registry\_token\_info)

## 6.4.0

### Features:

* added new modules for DBaaS Mongo (mongo\_cluster\_info, mongo\_cluster\_template\_info, mongo\_cluster\_user\_info, mongo\_cluster\_user and mongo\_cluster)
* added new modules for Certificate Manager (certificate, certificate\_info) and integration with the application\_load\_balancer\_forwardingrule module using the new `new_server_certificates` parameter
* added a new module for working with CUBE servers, cube\_server and depracationd notices when using the server module with CUBE servers
* added certificate pinning option to all modules using the certificate\_fingerprint parameter

### Bug fixes:

* fixed documentation for k8s\_nodepool should node\_count as string instead of int

## 6.3.2

### Features:

* added new `manage_dbaas` parameter to `group` module
* added new `depth` and `filters` parameters to info modules: `server_info`, `volume_info`, `postgres_backup_info`, `postgres_cluster_info`, `s3key_info`

### Bug fixes:

* fixed inventory cache
* name no longer required for k8s\_cluster update
* fix module indentation for nic and image

## 6.3.1

### Bug fixes

* Added token authentication for ALB
* For CUBE servers, on `state: present`, `user_data` and `ssh_keys` are now sent to the API

## 6.3.0

### Enhancements

* depth value for certain GET operations has been reduced

### Bug fixes

* Bug fixes relating to multiple resources sharing the exact same name:
  * If multiple resources have been found in an operation, an error is thrown. **Important Note: Please make sure you do not have multiple resources of the same type that share the same name. (i.e. two datacenters with the same name, or two volumes with identical name on the same server).**
  * For Server and Volume modules, you can now only rename one resource at a time. In practice, this means that now, `instance_ids` param now can only contain one ID if `state: update` and `name is not None`.
  * For Server and Volume modules, removed `auto_increment` flag. Now incrementation is done automatically if `count > 1` on creating new instances (because creating two instances with the same name is forbidden)
  * You can no longer rename a resource to have the same name as some other resource within the same entity (i.e. if by renaming a volume you will end up with two volumes sharing the same name within a server, then throw an error and fail the operation)
* Do not delete resources that have already been marked as `deleting`
* Inventory script fixes:
  * Inventory output is now JSON
  * Print with variable indent
  * Removed unused params: `group_by_licence_type`, `group_by_image_name`
* Now it is possible to rename ENTERPRISE servers, not just CUBE servers
* It is now also possible to use UUID to to identify users / nic\_flowlogs when `state` is `remove`
* When updating a user (respectively group) with other groups (respectively other users), registered variable at end of operation now correctly contains the new, updated groups that the user belongs to (respectively users belonging to that group)

### Features

* Added `user_data` parameter for server's module creation state. (The cloud-init configuration for the volume as a base64 encoded string.)
* Added ALB (Application Loadbalancer) modules:
  * application\_load\_balancer
  * application\_load\_balancer\_flowlog
  * application\_load\_balancer\_forwardingrule

## 6.2.0

### Bug fixes

* for s3key-info module, username & password parameters "required" status was too strict: now only required if no token provided
* remove duplicate lan arg in server module (now lan is a 'str')

### Features

* remove public, gateway\_ip params for k8s\_cluster and k8s\_nodepool (removed from python sdk)
* dbaas updates: added backup\_location to postgres\_cluster
* volume info module (#23)
* server info module (#22)

## 6.1.3

### Bug fixes

* **network\_load\_balancer\_rule** module: fixed `health_check` parameter *(the dict now supports snake case items instead of camel case)*

### Enhancements

* refactored the documentation based on states
* fix #1: added support for http proxies *(only for `ionoscloud` python package >= 6.0.3)*
  * using ***IONOS\_HTTP\_PROXY*** and ***IONOS\_HTTP\_PROXY\_HEADERS*** environment variables

### Features

* fix #63: implemented support for Token Authentication: can be used with `token` parameter or `IONOS_TOKEN` env variable
* new info module: **s3key\_info** - can be used to list all the s3keys
* **k8s\_nodepool** module: add support for updating labels and annotations
* fix #67: added new parameter on s3key module `idempotency` that ensures that If an s3key already exists, returns with already existing key instead of creating more

## 6.1.2

### Bug fixes:

* fix STOP server bug: the resources are now deallocated when a shut off server is stopped

## 6.1.1

### Enhancements:

* new parameters on *k8s\_cluster* module: `public`, `api_subnet_allow_list` and `s3_buckets`
* new parameters on *k8s\_nodepool* module: `gateway_ip`
* documentation updates related to Ansible Galaxy installation and usage

## 6.1.0

### Enhancements:

* add support for Dbaas Postgres: 3 new modules were added (postgres\_cluster, postgres\_cluster\_info, postgres\_backup\_info)

## 6.0.1

### Bug fixes:

* fix create volume bug that forced disk\_type to be always `HDD`

### Enhancements:

* add support for SSD storage *(new options for volume storage type: SSD Standard, SSD Premium)* - **SSD Premium is the default** if disk\_type=SSD

## 6.0.0 (11 January, 2022)

### Bug fixes:

* fix #31 - group deletion
* fix create volume response -> it will return the entire list of created volumes, not an empty list anymore

### Enhancements:

* improved deletion on all resources -> when trying to delete a resource that does not exist, the module will not fail anymore and it will succeed with `changed: False`
* allow name updates for volumes
* fix #28 - added new group permissions according to the Cloud API
* user resource now supports password updates

### Misc:

* docs: updated the name of the module in examples

## 6.0.0-beta.4 (23 October, 2021)

### Bug fixes:

* Remove the default value of `dhcp` parameter for `nic` module. The default value was `False`, which was not aligned with the CloudAPI swagger file.

## 6.0.0-beta.3 (September, 2021)

### Bug fixes:

* fixed issue: `Volume Module: HTTP 304 "Failed to parse request body" when attaching a volume to a server`

### Improvements:

* Added support for using image aliases when creating a volume. The modules now support *image ID, snapshot ID or image alias* values for the `image` parameter. If the image alias is provided, the module will resolve the image alias and use the correspondent image ID.
* new parameter for the `volume` module: `location` - used for identifying the image when image alias is used

## 6.0.0-beta.2 (June, 2021)

### Features:

* Added a new module (`image`). [Here](/ansible/api/compute-engine/modules/image) you can find the more details about this feature.
* New parameters on `volume` module:
  * image\_alias
  * backupunit\_id
  * user\_data
  * cpu\_hot\_plug
  * ram\_hot\_plug
  * nic\_hot\_plug
  * nic\_hot\_unplug
  * disc\_virtio\_hot\_plug
  * disc\_virtio\_hot\_unplug
* New parameters on `server` module:
  * type
  * template\_uuid
  * boot\_volume
  * boot\_cdrom
* Removed the `cube_server` module. Now the users can create **CUBE servers** using the `server` module.

## 6.0.0-beta.1 (May, 2021)

### Features:

* Added the following modules:
  * cube\_server
  * template
  * nat\_gateway
  * nat\_gateway\_rule
  * nat\_gateway\_rule
  * network\_load\_balancer
  * network\_load\_balancer\_flowlog
  * network\_load\_balancer\_rule

### Misc:

* Removed `nat` parameter from **nic** and **server** module
* Added `user_password` parameter on **user** module


# Authentication

Credentials can be supplied within a Playbook with the following parameters:

* **username** (**subscription\_user** is a legacy alias)
* **password** (**subscription\_password** is a legacy alias)
* **token**

However, the module can also inherit the credentials from environment variables:

* `IONOS_USERNAME`
* `IONOS_PASSWORD`
* `IONOS_TOKEN`

Username and password can be substituted by the token. Usage of the token is not mandatory. For generating a token, see [this](https://docs.ionos.com/cli-ionosctl/subcommands/authentication/token-generate)

> ***NOTE:*** The API URL can be changed using the following parameter **api\_url** in playbooks or using the `IONOS_API_URL` environment variable.

Storing credentials in environment variables is useful if you plan to store your PlayBooks using version control.


# Using proxies

You can use http proxies by setting the following environment variables:

* `IONOS_HTTP_PROXY` - proxy URL
* `IONOS_HTTP_PROXY_HEADERS` - proxy headers


# Ansible Playbooks

## Ansible Playbooks

Ansible leverages YAML manifest files called Playbooks. The Playbook will describe the infrastructure to build and is processed from top down. Here is a simple Playbook that will provision two identical servers:

`example.yml`:

```yaml
      - hosts: localhost
      connection: local
      gather_facts: false

      tasks:
      - name: Provision a set of instances
          ionoscloudsdk.ionoscloud.server:
              datacenter: Example
              name: server%02d
              auto_increment: true
              count: 2
              cores: 4
              ram: 4096
              image: 25cfc4fd-fe2f-11e6-afc5-525400f64d8d
              image_password: secretpassword
              location: us/las
              assign_public_ip: true
              remove_boot_volume: true
              state: present
          register: ionos
```

> :warning: If you are using names instead of UUIDs to reference objects and they contain field marked with no\_log (such as passwords), they may not work, so please use UUIDs instead in those cases!

**NOT WORKING**:

```yaml
      - hosts: localhost
      connection: local
      gather_facts: false

      tasks:
      - name: Create Cluster
        ionoscloudsdk.ionoscloud.postgres_cluster:
          display_name: test
          db_password: test
        register: cluster_response

      - name: Delete Cluster
      ionoscloudsdk.ionoscloud.postgres_cluster:
          postgres_cluster: "{{ cluster_response.postgres_cluster.properties.display_name }}"
          state: absent
```

In this case you should use the UUID of the cluster as the above example will not work:

**WORKING**:

```yaml
      - hosts: localhost
      connection: local
      gather_facts: false

      tasks:
      - name: Create Cluster
          ionoscloudsdk.ionoscloud.postgres_cluster:
              display_name: test
              db_password: test
          register: cluster_response

      - name: Delete Cluster
          ionoscloudsdk.ionoscloud.postgres_cluster:
              postgres_cluster: "{{ cluster_response.postgres_cluster.id }}"
              state: absent
```

## Execute a Playbook

If your credentials are not already defined:

```bash
export IONOS_USERNAME=username
export IONOS_PASSWORD=password
```

The `ansible-playbook` command will execute the above Playbook.

```bash
ansible-playbook example.yml
```


# Wait for Services

There may be occasions where additional waiting is required. For example, a server may be finished provisioning and shown as available, but IP allocation and network access is still pending. The built-in Ansible module **wait\_for** can be invoked to monitor SSH connectivity.

```yaml
  - name: Wait for SSH connectivity
    wait_for:
      port: 22
      host: "{{ item.public_ip }}"
      search_regex: OpenSSH
      delay: 10
    with_items: ""
```


# Incrementing servers

The **servers** module will provision a number of identical and fully operational servers based on the **count** parameter. A **count** parameter of 10 will provision ten servers with system volumes and network connectivity.

The server **name** parameter with a value of `server%02d` will appended the name with the incremental count. For example, server01, server02, server03, and so forth.

The **auto\_increment** parameter can be set to `false` to disable this feature and provision a single server.


# Check Mode and Diff

> ***NOTE:*** More info on using check\_mode and diff can be found here <https://docs.ansible.com/ansible/latest/playbook\\_guide/playbooks\\_checkmode.html>

Read bellow for info on how the IONOS Ansible module handles check mode and diff.

### Check Mode

When using check\_mode the playbook will not make changes in the API and a message will be returned if such changes would have been made. Example: "user would be updated.". The returned state is "changed". For operations that do not cause changes the regular response will be returned.

> ***NOTE:*** Please note that the value returned when using check mode is not exactly the same as what is returned by the server and even though check mode is passing without error, errors may occur when making the api calls.

### Diff

When using diff an additional property will be returned on the object showing the object states with before and after. These states only include the attributes which are checked by Ansible for update and recreate. Diff is not shown for when the object does not exist or for when it ill be deleted

> ***NOTE:*** Check mode and diff more are independent! Using diff does not stop the changes from being made in the api. To check what changes will be made without actually making them use both check\_mode and diff.

For now only the user modules offers support for check\_mode and diff.

### Examples

Usage:

```yaml
tasks:
- name: Create user
    ionoscloudsdk.ionoscloud.user:
    firstname: John
    lastname: Doe
    email: <email>
    administrator: false
    user_password: <password>
    force_sec_auth: false
    state: present
    check_mode: true
    diff: true
```

Output:

```json
{
    "user_response": {
        "changed": true,
        "diff": {
            "after": {
                "administrator": false,
                "email": "<email>",
                "firstname": "John",
                "force_sec_auth": false,
                "groups": "",
                "lastname": "Doe",
                "user_password": "user password will be updated"
            },
            "before": {
                "administrator": false,
                "email": "<email>",
                "firstname": "John",
                "force_sec_auth": false,
                "groups": "",
                "lastname": "Doe",
                "user_password": ""
            }
        },
        "failed": false,
        "msg": "User <email> would be updated",
        "user": {
            "id": "<user-id>",
            "properties": {
                "administrator": false,
                "email": "<email>",
                "firstname": "John",
                "force_sec_auth": false,
                "groups": "",
                "lastname": "Doe",
                "user_password": "user password will be updated"
            }
        }
    }
}
```


# SSH Key Authentication

The Ionos module sets server authentication using the **image\_password** and **ssh\_keys** parameters. Previous examples have demonstrated the administrative user password being set with the **image\_password** parameter. The following example demonstrates two public SSH keys being supplied with two different methods.

1. Set the public key as a string in the Playbook.
2. Load the public key into a variable from a local file.

`example.yml`:

```yaml
  - hosts: localhost 
    connection: local 
    gather_facts: false

    vars: 
        ssh_public_key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"

  tasks:
  - name: Provision a server
   ionoscloudsdk.ionoscloud.server:
      datacenter: Example
      name: server%02d
      assign_public_ip: true
      image: 25cfc4fd-fe2f-11e6-afc5-525400f64d8d
      ssh_keys:
          - "{{ ssh_public_key }}"
          - "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDPCNA2YgJ...user@hostname"
      state: present
```


# Return values

## create

For create operations, the module returns a dict containing:

| Name     | Value                | Description                                                                                       |
| -------- | -------------------- | ------------------------------------------------------------------------------------------------- |
| action   | always **create**    | The name of the current action                                                                    |
| change   | `True` or `False`    | If the task made changes within the resources                                                     |
| failed   | `True` or `False`    | If the task failed                                                                                |
| resource | The current resource | The key contains the resource name and the value is a dictionary containing the current resource. |

Example for datacenter resource:

```json
{
    "action": "create",
    "changed": false,
    "datacenter": {
        "entities": {},
        "href": "https://api.ionos.com/cloudapi/v5/datacenters/3f0a326d-5a51-4a4e-bd9c-a4c8d9df06f7",
        "id": "3f0a326d-5a51-4a4e-bd9c-a4c8d9df06f7",
        "metadata": {},
        "properties": {
            "description": null,
            "features": [
                "SSD"
            ],
            "location": "de/fra",
            "name": "ANSIBLE TEST",
            "sec_auth_protection": false,
            "version": 6
        },
        "type": "datacenter"
    },
    "failed": false
}
```

## update

For update operations, the module returns a dict containing:

| Name     | Value                | Description                                                                                       |
| -------- | -------------------- | ------------------------------------------------------------------------------------------------- |
| action   | always **update**    | The name of the current action                                                                    |
| change   | `True` or `False`    | If the task made changes within the resources                                                     |
| failed   | `True` or `False`    | If the task failed                                                                                |
| resource | The current resource | The key contains the resource name and the value is a dictionary containing the current resource. |

Example for datacenter resource:

```
{
    "action": "update",
    "changed": true,
    "datacenter": {
        "entities": {},
        "href": "https://api.ionos.com/cloudapi/v5/datacenters/3f0a326d-5a51-4a4e-bd9c-a4c8d9df06f7",
        "id": "3f0a326d-5a51-4a4e-bd9c-a4c8d9df06f7",
        "metadata": {},
        "properties": {
            "description": "Ansible test description 2 - RENAMED",
            "features": [
                "SSD"
            ],
            "location": "de/fra",
            "name": "ANSIBLE TEST",
            "sec_auth_protection": false,
            "version": 6
        },
        "type": "datacenter"
    },
    "failed": false
}
```

## delete

For delete operations, the module returns a dict containing:

| Name   | Value                  | Description                                   |
| ------ | ---------------------- | --------------------------------------------- |
| action | always **delete**      | The name of the current action                |
| change | `True` or `False`      | If the task made changes within the resources |
| failed | `True` or `False`      | If the task failed                            |
| id     | The id of the resource |                                               |

Example for datacenter resource:

```
{
    "action": "delete",
    "changed": true,
    "failed": false,
    "id": "a8ddad52-bc71-439d-9f56-fc2c103af8f2"
}
```


# Testing

Set your IONOS user credentials.

```bash
export IONOS_USERNAME=username
export IONOS_PASSWORD=password
```

Change into the `tests` directory and execute the Playbooks.

```bash
cd tests
ansible-playbook server-test.yml
```

Note: The IONOS public image UUIDs change periodically due to updates. Therefore, it is recommended to use image aliases.


# Declarative Changes

## Object Identification

With the introduction of the declarative tasks update (Version 7.0.0), module parameters have been revised to allow identification of objects using a single parameter that can accept either the name or the ID of the object. This replaces the need for multiple parameters previously used for object identification.

Example: Instead of using separate `id` and `name` parameters to identify a `datacenter`, a new parameter (`datacenter`) is now used, which accepts either the ID or the name of the datacenter.

This change applies to various other parameters used for identification, not limited to the resource created by the module.

Example: For `nic` identification, apart from the `nic` parameter, other resources like `datacenter`, `server`, and `lan` will be utilized.

> ***NOTE:*** For this mechanism to function properly, ansible now assumes unique names for objects. If multiple objects with the same names are found, the operation will fail.

## State Behavior for Modules

The update introduces changes in how states will work for the modules:

```yaml
    present:
        Looks for the object:
            - If it does not exist, create it.
            - If it already exists, it will function in the same way as the update state.

    update:
        - Updates the object if no unchangeable properties are modified.
        - Replaces the object if unchangeable properties are modified, creating a new object and removing the old one.
        - If `allow_replace` is set to false, the module will fail instead of replacing the object to avoid resource loss.

    absent:
        - Looks for the object:
            - If it does not exist, the operation is successful.
            - If it exists, delete it.
```

### The allow\_replace parameter

Defaults to `false`

* If set to `true`, the replace behavior is allowed.
* If set to `false`, when a resource would be replaced, an error will be thrown instead.

## List of Parameters Triggering Resource Replacement

The following parameters, when changed or set, trigger resource replacement:

| Module                 | Replace if Changed                                                                                       | Replace if Set                         |
| ---------------------- | -------------------------------------------------------------------------------------------------------- | -------------------------------------- |
| backupunit             | name                                                                                                     | -                                      |
| certificate            | certificate\_file, certificate\_chain\_file                                                              | private\_key\_file                     |
| cube\_server           | template\_uuid, availability\_zone                                                                       | -                                      |
| datacenter             | location                                                                                                 | -                                      |
| ipblock                | size, location                                                                                           | -                                      |
| k8s\_nodepool          | name, cpu\_family, cores\_count, ram\_size, availability\_zone, storage\_type, storage\_size, datacenter | -                                      |
| mongo\_cluster         | mongo\_db\_version, location                                                                             | -                                      |
| postgres\_cluster      | connections, backup\_location, location, synchronization\_mode, storage\_type                            | -                                      |
| registry\_token        | name                                                                                                     | -                                      |
| registry               | name, location                                                                                           | -                                      |
| volume                 | image, size, disk\_type, availability\_zone, licence\_type, user\_data                                   | backupunit, image\_password, ssh\_keys |
| vm\_autoscaling\_group | datacenter                                                                                               | -                                      |

> ***NOTE:*** The following parameters used to have default values which have been removed to avoid triggering a replacement without a value being set by the user (the former default value is in parentheses) :

* cube\_server:
  * availability\_zone ('AUTO')
* datacenter:
  * location ('us/las')
* ipblock:
  * size (1)
* volume:
  * size (10)
  * ssh\_keys (\[])
  * disk\_type ('HDD')
  * licence\_type ('UNKNOWN')

## List of Parameter Changes

The update involves changes in parameter names, removal of parameters, and addition of new parameters for various modules. Here is the detailed list:

**application\_load\_balancer:**

* datacenter\_id -> datacenter
* application\_load\_balancer\_id -> application\_load\_balancer

**application\_load\_balancer\_flowlog:**

* datacenter\_id -> datacenter
* application\_load\_balancer\_id -> application\_load\_balancer
* flowlog\_id -> flowlog

**application\_load\_balancer\_forwardingrule:**

* datacenter\_id -> datacenter
* application\_load\_balancer\_id -> application\_load\_balancer
* forwarding\_rule\_id -> forwarding\_rule

**backupunit:**

* backupunit\_id -> backupunit

**certificate:**

* certificate\_id -> certificate

**datacenter:**

* removed id
* added datacenter

**firewall\_rule:**

* added firewall\_rule

**group:**

* added group

**ipblock:**

* added ipblock

**k8s\_cluster:**

* k8s\_cluster\_id -> k8s\_cluster

**k8s\_nodepool:**

* removed nodepool\_id
* added k8s\_nodepool
* k8s\_cluster\_id -> k8s\_cluster
* datacenter\_id -> datacenter
* lan\_ids -> lans
* nodepool\_name -> name

**lan:**

* added lan
* pcc\_id -> pcc

**mongo\_cluster\_user:**

* mongo\_cluster\_id -> mongo\_cluster

**nat\_gateway:**

* nat\_gateway\_id -> nat\_gateway
* datacenter\_id -> datacenter

**nat\_gateway\_flowlog:**

* nat\_gateway\_id -> nat\_gateway
* datacenter\_id -> datacenter
* flowlog\_id -> flowlog

**nat\_gateway\_rule:**

* nat\_gateway\_id -> nat\_gateway
* datacenter\_id -> datacenter
* nat\_gateway\_rule\_id -> nat\_gateway\_rule

**network\_load\_balancer:**

* network\_load\_balancer\_id -> network\_load\_balancer
* datacenter\_id -> datacenter

**network\_load\_balancer\_flowlog:**

* network\_load\_balancer\_id -> network\_load\_balancer
* datacenter\_id -> datacenter
* flowlog\_id -> flowlog

**network\_load\_balancer\_flowlog:**

* network\_load\_balancer\_id -> network\_load\_balancer
* datacenter\_id -> datacenter
* forwarding\_rule\_id -> forwarding\_rule

**nic:**

* removed id
* added nic

**nic\_flowlog:**

* datacenter\_id -> datacenter
* server\_id -> server
* nic\_id -> nic
* flowlog\_id -> flowlog

**pcc:**

* pcc\_id -> pcc

**registry:**

* registry\_id -> registry

**registry\_token:**

* removed token\_id
* added registry\_token
* registry\_id -> registry

**registry\_token\_info:**

* registry\_id -> registry

**s3\_key:**

* user\_id -> user

**s3\_key\_info:**

* user\_id -> user

**server:**

* remove template\_uuid and type, use cube\_server

**snapshot:**

* added snapshot

**target\_group:**

* target\_group\_id -> target\_group

**user:**

* removed s3\_canonical\_user\_id
* added user

**volume:**

* backupunit\_id -> backupunit


# Tutorials introduction

> **Warning**
>
> The notes and code-snippets included in this repository are provided *without warranty*, as examples of how to perform certain tasks or operations using our Configuration Management tools and/or to help replicate and diagnose potential issues more quickly.
>
> While every effort has been made to ensure that the information and/or code contained herein is current and works as intended, it has not been through any formal or rigorous testing process, and therefore should be used at your own discretion.
>
> For *definitive* information and documentation, please see [docs.ionos.com/ansible](https://docs.ionos.com/ansible)

## Overview

In this series, we will introduce the [IONOS CLOUD Ansible Module](https://docs.ionos.com/ansible), and show how it can be used to provision many of our more commonly-used Compute resources and Managed Services in combinations that are at least *representative* of 'real-world' deployments.

Beyond providing prototypical examples, we will also introduce a few more general conventions and patterns which can be used to make your code more readable and reusable, and where there are a few different ways of performing the same task, we will try to introduce them, via comments, directly in the source files.

### Intended audience

The examples and code-snippets contained in this repository are intended for people who are not necessarily familiar with IONOS CLOUD's product offerings and/or our Ansible module, but are wanting to learn how to provision and configure such resources in a scriptable way. A certain familiarity with Linux (or other UNIX-like operating systems) is assumed, and *some* experience with Ansible or other scripting and/or programming languages would also help.

For some of the more 'advanced' topics — including our Managed Kubernetes and Database offerings — it is assumed that you are already familiar with the underlying software; in these cases, we will not be introducing basic concepts — rather, we will focus on IONOS CLOUD-specific configuration and optimisation options.

A secondary use for these tutorials is to provide 'known-working' reference implementations, especially for Managed Services that have *practical* dependencies on other types of resources. For this use case, the relevant examples can be provisioned and configured using Ansible, but then inspected and, potentially, 'tweaked' interactively via the Data Center Designer (DCD) or the API to get a better understanding of how these products might be used in 'production environments'.

### What's in this collection?

This collection consists of the following tutorials — while each one typically focuses on one, or at most two complementary types of resources, some of them also introduce 'better practices' and/or techniques that can help make your code more modular, and while they are basically independent, they trace out a certain 'trajectory' in terms of complexity and 'real-world applicability':

| File                                                                                                                                        | Description                                                                                                                                                                                                                                                                                                                     |
| ------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`01__minimal_example`](/ansible/tutorials/01__minimal_example)                                                                             | A very minimal example that creates a one-server datacenter and shows: (a) how to retrieve a few pieces of information 'programmatically'; and (b) how to change the VM's state, before cleaning up after itself                                                                                                                |
| [`02__server_with_multiple_nics_and_storage_volumes`](/ansible/tutorials/02__server_with_multiple_nics_and_storage_volumes)                 | This example builds upon the first one by showing you how to create and attach secondary NICs and storage volumes to a server                                                                                                                                                                                                   |
| [`03__jumpbox_with_internal_server`](/ansible/tutorials/03__jumpbox_with_internal_server)                                                   | This example introduces the Cube server, and shows you how an SSH ['jump server / jump box'](https://en.wikipedia.org/wiki/Jump_server) can be used to provide shell access, and apply Ansible Playbooks to an otherwise inaccessible VM; it also shows how one can 'bridge' IaaS-level provisioning and VM-level configuration |
| [`04__working_with_existing_resources`](/ansible/tutorials/04__working_with_existing_resources)                                             | This example shows how `info` modules, external tools (in this case, `ionosctl`), and the [ansible.builtin.uri](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/uri_module.html) module can be used to obtain information about, and work with pre-existing resources                                       |
| [`05__introducing_roles`](/ansible/tutorials/05__introducing_roles)                                                                         | In this example, we briefly look at [Ansible Roles](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_reuse_roles.html), and how they can be used to make your Ansible code more modular and reusable                                                                                                            |
| [`06__introducing_the_nat_gateway_and_network_load_balancer`](/ansible/tutorials/06__introducing_the_nat_gateway_and_network_load_balancer) | In this example, we introduce the NAT Gateway and Network Load Balancer, and see how they can be used to implement source and destination NAT, respectively                                                                                                                                                                     |
| [`07__introducing_the_application_load_balancer`](/ansible/tutorials/07__introducing_the_application_load_balancer)                         | In this example, we introduce the Application Load Balancer and see how it can be used to implement *Layer 7* load balancing with rule-based forwarders                                                                                                                                                                         |
| [`09__a_quick_introduction_to_dbaas`](/ansible/tutorials/09__a_quick_introduction_to_dbaas)                                                 | In this example, we introduce our Managed PostgreSQL and MongoDB Services, and show how they can be accessed from servers in different locations                                                                                                                                                                                |

## Before you begin

In order to use the examples in this tutorial series, you will need a working installation of [Ansible](https://docs.ansible.com/ansible/latest/installation_guide/installation_distros.html) and our [Ansible module](https://docs.ionos.com/ansible/#installation); if you have [git](https://git-scm.com) installed as well, that will make it easier to download and manage these examples' source and configuration files.

While the recommended way to explore our APIs, SDKs and Confirguration Management Tools is to install the necessary software components as described in their respective documentation, a quick-and-easy way to get started is to use the [IONOS CLOUD API / SDK 'Sandpit'](https://hub.docker.com/r/metzionos/ionos-cloud-api-sandpit) Docker container, assuming you have access to a machine with a working installation of [Docker Engine](https://docs.docker.com/engine/) or [Docker Desktop](https://docs.docker.com/desktop/) that's capable of running amd64-based Linux images.

If you do, then just follow the instructions over at the image's [Docker Hub page](https://hub.docker.com/r/metzionos/ionos-cloud-api-sandpit) to spin up a 'sandpit environment' that you can use to explore our [Ansible module](https://docs.ionos.com/ansible) and [Terraform provider](https://docs.ionos.com/terraform-provider/), along with some other command line utilities...

> **Note:** Upon trying to 'apply' any of the examples in this repository, an 'End User Licence Agreement'-like statement will be displayed, which must also be accepted before the tasks proper can be executed.
>
> Also note that, while potentially quite minimal, you will incur charges for the resources based upon how long you keep them provisioned; for more information on the actual costs, you can follow the links displayed in the 'EULA' text. (But also, as a rough guide, a single-core VM with 1GB of RAM and 10GB of HDD storage would cost about 4.5 (Euro)cents per hour, as of April 2024.)
>
> **While every effort has been made to ensure each example 'cleans up' after itself, this cannot be guaranteed — particularly if an error is thrown, e.g., when trying out custom changes or otherwise experimenting with the provided files. To avoid any unexpected charges, we strongly recommend that you review your resources in the DCD, and manually delete anything that was missed by the Ansible Playbooks.**

### Important note about token- vs password-based authentication

Although most of our Configuration Management tools, Software Development Kits (SDKs) and APIs support both password- and token-based authentication, the use of tokens is generally preferred. While far from exhaustive, reasons for using tokens over passwords include that they can provide more finely-grained *per application* credentials that can expire and/or be invalidated independently of each other, and in contrast to passwords, should a *token* be compromised, the chances that it will leak information which can be used to compromise other services are also significantly reduced.

Accordingly, whenever the code included in this repository makes lower-level calls to our Cloud API, it assumes that the `IONOS_TOKEN` environment variable contains a valid token, and will *not* fallback to using the `IONOS_USERNAME` and `IONOS_PASSWORD` environment variables.

For information on how to create a token that can be used for IONOS CLOUD API calls, see our [Authentication API](https://api.ionos.com/docs/authentication/v1/#tag/tokens) documentation or [ionosctl / Authentication / Login](https://docs.ionos.com/cli-ionosctl/subcommands/authentication/login) and [TokenGenerate](https://docs.ionos.com/cli-ionosctl/subcommands/authentication/token-generate).

### A few good-to-knows

In addition to the above disclaimers, the following notes might help you troubleshoot problems commonly encountered when getting started:

* If you get any `couldn't resolve module/action ... This often indicates a misspelling, missing collection, or incorrect module path` error messages, make sure you've downloaded and 'setup' the IONOS CLOUD Ansible module; see [this page](https://docs.ionos.com/ansible/#installation) for the definitive information, however two ways of doing this are:
  * to run `ansible-galaxy collection install ionoscloudsdk.ionoscloud` as *yourself* (i.e. without calling `sudo` or otherwise running this as `root`) — under Linux, this will install said module under `~/.ansible/collections/ansible_collections`; or
  * to clone the module into the location of your choosing using the command `git clone https://github.com/ionos-cloud/module-ansible`, and to inform Ansible of this location, either through the use of the `ANSIBLE_LIBRARY` environment variable or via a command-line argument (e.g., `ansible-playbook --module-path ${MODULE_PATH} ...`)
* If you get a `name 'certificate_manager_sdk_version' is not defined` error message when working with the Application Load Balancer, make sure you have the module installed (this can be done by running the command `pip install ionoscloud-cert-manager`)
* You will need to set the `IONOS_TOKEN` environment variable before running any of the playbooks contained in this subdirectory. For information on how to create a token, see the section above.
* Should you wish to 'invoke' IONOS CLOUD modules *without* having to use their fully qualified collection name (FQCN) every time, you can use the [`collections`](https://docs.ansible.com/ansible/latest/collections_guide/collections_using_playbooks.html#simplifying-module-names-with-the-collections-keyword) keyword and the `ionoscloudsdk.ionoscloud` 'namespace'. (Whilst convenient, this *could*, in theory, lead to 'namespace collisions' with other third-party modules, hence the advice to use FQCNs in any production code.)

## Glossary

The following key terms are used throughout this series of tutorials:

| Term | Description                                                                                                                                                                                                                                                                            |
| ---- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| DCD  | [Data Center Designer](https://docs.ionos.com/cloud/getting-started/data-center-designer), a unique graphical tool for creating and managing Virtual Data Centers (VDC) in the cloud; configuration is intuitive and straightforward with a JavaScript-based graphical user interface. |
| VDC  | A Virtual Data Center is a collection of cloud resources used for creating an enterprise-grade IT infrastructure. VDC resources include the processors, memory, disk space, and networks from which virtual machines are built.                                                        |

## Source files

The source files for all of the examples in this tutorial series can be downloaded from [github.com/ionos-cloud/module-ansible/tree/master/docs/tutorials](https://github.com/ionos-cloud/module-ansible/tree/master/docs), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials` sub-directory.


# Minimal example

## Overview

We begin our look at the IONOS CLOUD Ansible Module with a minimal example that creates, and then deletes a Virtual Data Center (VDC) containing one server. It also shows you how the Ansible Module can be used to shut off a VM and power it back on.

## Before you begin

If you're looking at this example whilst also learning about Ansible, then the following notes / hints might prove helpful:

1. Read through the table below, which describes the files that make up this example.
2. At a minimum, go through `main.yml` and `../vars.yml` to get a feeling for how everything fits together. What do you expect to happen?
3. Follow the steps outlined in the 'Usage' section below to actually provision your VM.
4. Look at what was created in the DCD, at a minimum, and possibly using an API tool like the rather excellent [IonosCTL](https://docs.ionos.com/cli-ionosctl) command-line tool.
5. Go back through `main.yml` to compare what the various stanzas *say* with what they *do*.
6. Once you have a general understanding of what this example does (and *how* it does what it does), feel free to make whatever changes you want to, knowing that you can always just do a `git diff`, `git revert` or `git pull` if you 'break something' along the way. (That said, the scope for modification is a *bit* limited due to the minimal nature of this example — if you want to start playing around with multiple storage volumes or NICs, you might want to wait until the next example.)

### What's in this example?

Even though this example is quite minimal, it includes and/or depends upon the following files:

| File             | Description                                                                                                                                                                                           |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `main.yml`       | As its name suggests, this is the example's main (and only) Ansible file                                                                                                                              |
| `../vars.yml`    | This file is common to all of our Ansible examples and contains a set of more generally-used variable definitions                                                                                     |
| `cloud-init.txt` | This file contains the [cloud-init data](https://docs.ionos.com/cloud/compute-engine/virtual-servers/how-tos/boot-cloud-init) that will be used to tailor the new server while it's being provisioned |

## Usage

> **Note:** As with all other 'executable' examples in this repository, an 'End User Licence Agreement'-like statement will be displayed, which must be accepted before the tasks proper can be executed.
>
> Please note that, while potentially quite minimal, you will incur charges for the resources based upon how long you keep them provisioned; for more information on the actual costs, you can follow the links displayed in the 'EULA' text. (But also, as a rough guide, a single-core VM with 1GB of RAM and 10GB of HDD storage would cost about 4.5 (Euro)cents per hour, as of April 2024.)

To provision this infrastructure:

1. make sure that you have a working installation of Ansible and the IONOS CLOUD Ansible module as described in the '[Before you begin](/ansible/tutorials/tutorials#before-you-begin)' section of this series' introduction, and that your `IONOS_TOKEN` environment variable is set; and
2. run the following command on your Ansible host:

   ```
   ansible-playbook main.yml
   ```

If you let it run until it completes successfully, you shouldn't *need* to do anything else, however we still recommend that you confirm (via the DCD or `ionosctl`) that the server and its containing data center have been deleted as expected; if the playbook failed with errors, then you will *definitely* want to do this.

Should you have any problems running this playbook, you might want to refer to the section entitled '[A few good to knows](/ansible/tutorials/tutorials#a-few-good-to-knows)' for some troubleshooting tips.

## Summary

Although quite limited in its scope, this example illustrates several things (at least to the beginner) including:

1. how to provision IONOS CLOUD Data Centers and Servers, and to change the state of the latter;
2. how to read in the contents of files and environment variables (in `../vars.yml`);
3. how to prompt for user input (and evaluate composite conditionals); and
4. how to use the results of previous tasks (i.e. register variables) — e.g., `datacenter_response` and `create_server_response`

## Source files

The source files for this tutorial can be downloaded from its [Github repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/01__minimal_example` sub-directory.


# cloud-init.txt.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/01__minimal_example` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```bash
#!/bin/bash
dd if=/dev/zero of=/swapfile bs=1M count=512
chmod 0600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile    none    swap    sw    0    0' >> /etc/fstab

```

{% endcode %}


# main.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/01__minimal_example` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```yml
---
# The following host and connection specs are mandatory as the IONOS CLOUD
# Ansible module is 'proxied' via localhost
- hosts: localhost
  connection: local
  gather_facts: false

  vars_files:
    - ../vars.yml

  vars:
    - datacenter_name: Ansible Tutorials - Minimal Functional Test
    - server_name:     Example server


  tasks:
    # =======================================================================
    - name: Display EULA
      ansible.builtin.pause:
        prompt: "{{ IONOS_UNSUPPORTED_EULA }}"
      register: INTERACTIVE_EULA_ACCEPTED
      when: IONOS_UNSUPPORTED_EULA_ACCEPTED != "yes"


    - name: Confirm acceptance of EULA
      ansible.builtin.assert:
        that:
          - IONOS_UNSUPPORTED_EULA_ACCEPTED == "yes" or INTERACTIVE_EULA_ACCEPTED.user_input == "yes"  




    # =======================================================================
    # See https://docs.ionos.com/ansible/api/compute-engine/datacenter for
    # more information
    - name: Create the datacenter '{{ datacenter_name }}' in {{ location }}
      ionoscloudsdk.ionoscloud.datacenter:
        name: "{{ datacenter_name }}"
        location: "{{ location }}"
        state: present
      register: datacenter_response

    

    # See https://docs.ionos.com/ansible/api/compute-engine/server for more
    # information
    - name: Create the server '{{ server_name }}' --- this may take a while, please don't interrupt this operation...)
      ionoscloudsdk.ionoscloud.server:
        # quite a bit longer than just 'datacenter_name', to be sure, but it shows
        # you how you can get the name from the register variable returned above
        datacenter: "{{ datacenter_response.datacenter.properties.name }}"
        name: "{{ server_name }}"
        cores: "1"
        ram: "1024"
        cpu_family: "{{ datacenter_response.datacenter.properties.cpu_architecture[0].cpu_family }}"
        assign_public_ip: true
        disk_type: HDD
        volume_size: "5"
        image: "{{ image_alias }}"
        image_password: "{{ default_password }}"
        ssh_keys:
          - "{{ ssh_public_key }}"
        # if you don't want to perform any first-boot tasks using cloud-init,
        # simply remove the following line
        user_data: "{{ lookup('file', 'cloud-init.txt') | string | b64encode }}"

        state: present
        wait: true
        wait_timeout: "{{ wait_timeout }}"
      register: create_server_response


    - name: Print the newly-provisioned server's public IP address
      ansible.builtin.debug:
        msg:
          - "The server's IP address is {{ create_server_response.machines[0].entities.nics['items'][0].properties.ips[0] }}"
          - "(Please note this _will_ change across VM _power-cycles / hard-resets_)"




    # =======================================================================
    - name: Wait for user confirmation
      ansible.builtin.pause:
        prompt: "The server is now created, and may be inspected. Press <Enter> when you are ready for it to be (forcibly) shutdown. (This may take a while...)"
      when: pause_between_operations


    - name: Stop '{{ server_name }}'
      ionoscloudsdk.ionoscloud.server:
        datacenter: "{{ datacenter_name }}"
        instance_ids:
          - "{{ server_name }}"

        state: stopped
        wait_timeout: "{{ wait_timeout }}"




    # =======================================================================
    - name: Wait for user confirmation
      ansible.builtin.pause:
        prompt: "The server is now stopped. Press <Enter> when you are ready for it to be powered back on. (This may take a while...)"
      when: pause_between_operations
        
        
    - name: Start '{{ server_name }}'
      ionoscloudsdk.ionoscloud.server:
        datacenter: "{{ datacenter_name }}"
        instance_ids:
          - "{{ server_name }}"

        state: running
        wait_timeout: "{{ wait_timeout }}"




    # =======================================================================
    - name: Wait for user confirmation
      ansible.builtin.pause:
        prompt: "End of example. Press <Enter> when you are ready for the contents of '{{ datacenter_name }}' to be deleted..."
      when: pause_between_operations


    - name: Remove the server
      ionoscloudsdk.ionoscloud.server:
        datacenter: "{{ datacenter_name }}"
        instance_ids:
          - "{{ server_name }}"

        state: absent
        wait_timeout: "{{ wait_timeout }}"


    # This will remove all servers, volumes, and other objects contained therein
    - name: Delete the datacenter '{{ datacenter_name }}'
      ionoscloudsdk.ionoscloud.datacenter:
        datacenter: "{{ datacenter_response.datacenter.id }}"    # can delete by name or id
        state: absent

```

{% endcode %}


# Server with multiple NICs and storage volumes

## Overview

In this installment, we will add a second NIC and volume to our basic server — whilst still rather trivial, this playbook might be useful as an example of how to do this using the output of a previous task (since it's not currently possible to pass arrays of NICs, etc. to `ionoscloudsdk.ionoscloud.server`).

## Before you begin

Continuing with the thought of learning about Ansible *and* the IONOS CLOUD module at the same time, you might find the following notes / hints helpful:

1. At a minimum, go through `main.yml` and `../vars.yml` to get a feeling for how everything fits together. What do you expect to happen?
2. Follow the steps outlined in the 'Usage' section below to actually provision your VM.
3. Look at what has been created using the DCD, at a minimum, and possibly using an API tool like [IonosCTL](https://docs.ionos.com/cli-ionosctl).
4. Go back through `main.yml` to compare what the various stanzas *say* with what they *do*.
5. If you're not already familiar with Ansible's [registered variables](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html#registering-variables), then you might want to set `verbose_debugging` to true (see `../vars.yml`) and re-run this playbook to see what each task is outputting upon completion.

For 'extra marks', you could:

1. use, e.g., [jsonpathfinder.com](https://jsonpathfinder.com) and/or Ansible's [Playbook Debugger](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_debugger.html) to see how — and, in some cases, *why* — the playbook references the nested variables that it does; and
2. expand this example to create a second server that's connected to the same LANs as the first using the contents of registered variables *as succinctly as possible* — when and where can you use dot notation to access [nested variables](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html#referencing-nested-variables), and where do you need to use bracket notation?

### What's in this Example?

Even though this example is still quite minimal, it includes and/or depends upon the following files:

| File          | Description                                                                                                       |
| ------------- | ----------------------------------------------------------------------------------------------------------------- |
| `main.yml`    | This is the example's main (and only) Ansible file                                                                |
| `../vars.yml` | This file is common to all of our Ansible examples and contains a set of more generally-used variable definitions |

## Usage

> **Note:** As with all other 'executable' examples in this repository, an 'End User Licence Agreement'-like statement will be displayed, which must also be accepted before the tasks proper can be executed.
>
> Please note that, while potentially quite minimal, you will incur charges for the resources based upon how long you keep them provisioned; for more information on the actual costs, you can follow the links displayed in the 'EULA' text. (But also, as a rough guide, a single-core VM with 1GB of RAM and 10GB of HDD storage would cost about 4.5 (Euro)cents per hour, as of April 2024.)

To provision this infrastructure:

1. make sure that your `IONOS_TOKEN` environment variable has been set; and
2. run the following command on your Ansible host:

   ```
   ansible-playbook main.yml
   ```

If you let it run until it completes successfully, you shouldn't *need* to do anything else, however we still recommend that you confirm (via the DCD or `ionosctl`) that the server and its containing Virtual Data Center (VDC) have been deleted as expected; if the playbook failed with errors, then you will definitely want to do this.

> From this point on, we will assume that you have a working environment, and are aware of the costs associated with provisioning resources (albeit temporarily) and the importance of making sure all example resources have been completely unprovisioned afterwards; if you haven't already done so, we suggest you visit, e.g., [cloud.ionos.com/prices](https://cloud.ionos.com/prices) or [cloud.ionos.de/preise](https://cloud.ionos.de/preise), depending on where your contract is based.

## Summary

In this tutorial, we saw examples of:

1. how to use the `ionoscloudsdk.ionoscloud.nic` and `volume` modules to provision additional network interfaces and storage volumes; and
2. how one can access slightly more complicated nested attributes that one will often see when working with register variables.

## Source Files

The source files for this tutorial can be downloaded from its [Github repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/02__server_with_multiple_nics_and_storage_volumes` sub-directory.


# main.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/02__server_with_multiple_nics_and_storage_volumes` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```yml
---
- hosts: localhost
  connection: local
  gather_facts: false

  vars_files:
    - ../vars.yml

  vars:
    - datacenter_name: Ansible Tutorials - Server with multiple NICs and Storage Volumes
    - server_name:     Example server


  tasks:
    # =======================================================================
    - name: Display EULA
      ansible.builtin.pause:
        prompt: "{{ IONOS_UNSUPPORTED_EULA }}"
      register: INTERACTIVE_EULA_ACCEPTED
      when: IONOS_UNSUPPORTED_EULA_ACCEPTED != "yes"


    - name: Confirm acceptance of EULA
      ansible.builtin.assert:
        that:
          - IONOS_UNSUPPORTED_EULA_ACCEPTED == "yes" or INTERACTIVE_EULA_ACCEPTED.user_input == "yes"  




    # =======================================================================
    - name: Create the datacenter '{{ datacenter_name }}' in {{ location }}
      ionoscloudsdk.ionoscloud.datacenter:
        name: "{{ datacenter_name }}"
        location: "{{ location }}"
        state: present
      register: datacenter_response


    - name: Create the server '{{ server_name }}' --- this may take a while, please don't interrupt this operation...
      ionoscloudsdk.ionoscloud.server:
        datacenter: "{{ datacenter_response.datacenter.properties.name }}"
        name: "{{ server_name }}"
        cores: "1"
        ram: "1024"
        cpu_family: "{{ datacenter_response.datacenter.properties.cpu_architecture[0].cpu_family }}"
        assign_public_ip: true
        disk_type: HDD
        volume_size: "5"
        image: "{{ image_alias }}"
        image_password: "{{ default_password }}"
        ssh_keys:
          - "{{ ssh_public_key }}"

        state: present
        wait: true
        wait_timeout: "{{ wait_timeout }}"
      register: create_server_response


    - name: Print contents of 'create_server_response'
      ansible.builtin.debug:
        var: create_server_response
      when: verbose_debugging




    # =======================================================================
    # See https://docs.ionos.com/ansible/api/compute-engine/lan for more
    # information
    - name: Create a second LAN within '{{ datacenter_name }}'
      ionoscloudsdk.ionoscloud.lan:
        datacenter: "{{ datacenter_response.datacenter.properties.name }}"
        name: "internal"
        public: false
      register: create_second_lan_response


    - name: Print contents of 'create_second_lan_response'
      ansible.builtin.debug:
        var: create_second_lan_response
      when: verbose_debugging


    # See https://docs.ionos.com/ansible/api/compute-engine/nic for more
    # information
    - name: Create a second NIC for '{{ server_name }}' (this time with a 'static' IP address)
      ionoscloudsdk.ionoscloud.nic:
        datacenter: "{{ datacenter_response.datacenter.properties.name }}"
        name: "{{ server_name }}.eth1"
        server: "{{ server_name }}"
        lan: "{{ create_second_lan_response.lan.id }}"
        ips:
          - 192.168.16.16
        dhcp: true

        state: present
        wait: true
        wait_timeout: "{{ wait_timeout }}"
      register: create_second_nic_response


    - name: Print contents of 'create_second_nic_response'
      ansible.builtin.debug:
        var: create_second_nic_response
      when: verbose_debugging




    # =======================================================================
    # See https://docs.ionos.com/ansible/api/compute-engine/volume for more
    # information
    - name: Create a second volume for '{{ server_name }}'
      ionoscloudsdk.ionoscloud.volume:
        datacenter: "{{ datacenter_response.datacenter.properties.name }}"
        name: "{{ server_name }}.hdd1"
        server: "{{ server_name }}"
        size: 10
        disk_type: "HDD"
        licence_type: "OTHER"
      register: create_second_volume_response


    - name: Print contents of 'create_second_volume_response'
      ansible.builtin.debug:
        var: create_second_volume_response
      when: verbose_debugging




    # =======================================================================
    - name: Print some information about the created resources
      ansible.builtin.debug:
        msg:
          - "Server: [ {{ create_server_response.machines[0].id }} ]"
          # Unfortunately, due to how object-attributes are handled / expanded
          # within Jinja templates, we can't just write, e.g.,
          # {{ create_server_response.machines[0].entities.nics.items[0].properties.lan }}
          # or {{ create_server_response.machines[0].entities.volumes.id }}
          - "NIC_0:  [ {{ create_server_response['machines'][0]['entities']['nics']['items'][0]['properties']['lan'] }}, {{ create_server_response['machines'][0]['entities']['nics']['items'][0]['properties']['ips'][0] }} ]"
          - "NIC_1:  [ {{ create_second_nic_response.nic.properties.lan }}, {{ create_second_nic_response.nic.properties.ips[0] }} ]"
          - "Vol_0:  [ {{ create_server_response['machines'][0]['entities']['volumes']['items'][0]['id'] }} ]"
          - "Vol_1:  [ {{ create_second_volume_response.volumes[0].id }} ]"




    # =======================================================================
    - name: Wait for user confirmation
      ansible.builtin.pause:
        prompt: "End of example. Press <Enter> when you are ready for the contents of '{{ datacenter_name }}' to be deleted..."
      when: pause_between_operations


    # This will remove all servers, volumes, and other objects contained therein
    - name: Delete the datacenter '{{ datacenter_name }}' and everything contained therein
      ionoscloudsdk.ionoscloud.datacenter:
        datacenter: "{{ datacenter_name }}"
        state: absent

```

{% endcode %}


# Jumpbox with internal server

## 3. Provision a Jumpbox and an Internal Server

## Overview

In this example, we will see how one might provision an 'internal server' (i.e. one that isn't directly connected to the Internet) along with a [Jumpbox (aka Jump Box aka Jump server)](https://en.wikipedia.org/wiki/Jump_server) that can be used to log into this 'semi-isolated' VM via SSH, and which can also be used, e.g., to run additional Ansible Playbooks *on the VM* to perform additional, post-provisioning tasks. (In order to install additional packages, etc., on the new VM, it would, of course, need some kind of *outgoing* network connectivity — we will look at how this can be done using our [NAT Gateway](https://docs.ionos.com/cloud/early-access/nat-gateway/overview) in Part 6 of this series.)

### Before you begin

This example also introduces a few new modules, techniques and 'code snippets' that you might find interesting, including:

1. how the `ionoscloudsdk.ionoscloud.cube_template` and `cube_server` modules can be used to provision a [Cube Server](https://docs.ionos.com/cloud/compute/cloud-cubes/cloud-cubes) given its desired 'size' name;
2. pointers to and/or examples of how files can be created 'on the fly' (e.g. via `ansible.builtin.shell` + HEREDOCs, via the `copy` module, and via Jinja templates); and
3. how `ssh_config` and Ansible inventory files can be automatically generated and then used, together, to allow you to ssh into, and run Ansible playbooks on a server that isn't directly connected to the Internet.

#### What's in this example?

This example includes and/or depends on the following files:

| File                            | Description                                                                                                                                                                                                     |
| ------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `main.yml`                      | This is the example's main Ansible file; it communicates via `localhost` and our Ansible Module with the IONOS CLOUD [Cloud API](https://api.ionos.com/docs/cloud/) in order to provision our virtual resources |
| `configure-internal-server.yml` | This playbook is run *on the internal VM* via the jumpbox (see `ansible_ssh_common_args` in `inventory.yml` and/or `ssh_config` *after* running `main.yml`)                                                     |
| `cloud-init.txt`                | This file contains the [cloud-init data](https://docs.ionos.com/cloud/compute-engine/virtual-servers/how-tos/boot-cloud-init) that will be used to tailor the internal server when it's being provisioned       |
| `templates/ssh_config.j2`       | A simple [Jinja template](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_templating.html), in this case, to dynamically create the `ssh_config` file mentioned above                          |
| `../vars.yml`                   | This file is common to all of our Ansible examples and contains a set of more generally-used variable definitions                                                                                               |

### Usage

1. To provision this infrastructure, simply run the following command:

   ```
   ansible-playbook main.yml
   ```
2. Optionally, look at the contents of the dynamically-created files (in particular, `ssh_config` and `inventory.yml`)
3. To ssh into the VMs, type the following *from the same directory in another shell* (where `${DESIRED_SERVER}` is either `jumpbox` or `internal`):

   ```
   ssh -F ssh_config ${DESIRED_SERVER}
   ```
4. To configure the internal server via the jumpbox, you can then run the following command (also from a secondary shell):

   ```
   ansible-playbook -i inventory.yml configure-internal-server.yml
   ```
5. Once you have finished exploring this example, press `<Enter>` in the shell from Step 1 to let the `main.yml` playbook delete the provisioned resources.

### Summary

In this tutorial, we saw examples of:

1. how to use the `ionoscloudsdk.ionoscloud.cube_template` and `cube_server` modules to provision a Cube Server;
2. how the `ansible.builtin.shell` module and the `ssh-keygen` command can be used to generate a temporary SSH key-pair;
3. how the `ansible.builtin.template` module, and the `ansible.builtin.shell` module and the `cat` command can be used to dynamically create files based upon the contents of register variables
4. how we can use the above to configure a jumpbox that can, in turn, be used to access and configure an 'internal server' that is otherwise inaccessible from the Internet

### Source files

The source files for this tutorial can be downloaded from its [Github repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git`, and changing into the `module-ansible/docs/tutorials/03__jumpbox_with_internal_server` sub-directory.


# cloud-init.txt.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/03__jumpbox_with_internal_server` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```bash
#!/bin/bash
dd if=/dev/zero of=/swapfile bs=1M count=512
chmod 0600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile    none    swap    sw    0    0' >> /etc/fstab

```

{% endcode %}


# configure-internal-server.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/03__jumpbox_with_internal_server` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```yml
---
# Unlike main.yml (which communicates with the IONOS CLOUD Ansible module via
# localhost), _this_ playbook is run on the internal server (i.e. the VM that
# has _no_ connection to the Internet) via the jumpbox). Given said lack of
# Internet access, we're not able to, e.g., install or update any software, so
# instead, we will just dump some host information to a file on the internal
# server, and copy it back to our 'local' computer
- hosts: internal

  tasks:
    - name: Log information of interest
      ansible.builtin.blockinfile:
        path: "/tmp/internal-server-hostinfo"
        create: yes
        marker: ""
        block: |
          fqdn: {{ ansible_facts.fqdn }}
          distribution: {{ ansible_distribution_file_variety }} {{ ansible_distribution }} {{ ansible_distribution_version }} {{ ansible_distribution_release }}
          kernel_version: {{ ansible_kernel }} {{ ansible_kernel_version }}
          interfaces: {{ ansible_interfaces }}


    - name: And copy them back to our localhost
      ansible.builtin.fetch:
        src: /tmp/internal-server-hostinfo
        dest: "internal-server-hostinfo.txt"
        flat: yes


```

{% endcode %}


# main.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/03__jumpbox_with_internal_server` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```yml
---
# The following host and connection specs are mandatory as the IONOS CLOUD
# Ansible module is 'proxied' via localhost
- hosts: localhost
  connection: local
  gather_facts: false

  vars_files:
    - ../vars.yml

  vars:
    - datacenter_name: Ansible Tutorials - Jumpbox with Internal Server
    - jumpbox_name:    Jumpbox
    - cube_size:       CUBES XS
    - int_server_name: Example internal server




  tasks:
    # =======================================================================
    - name: Display EULA
      ansible.builtin.pause:
        prompt: "{{ IONOS_UNSUPPORTED_EULA }}"
      register: INTERACTIVE_EULA_ACCEPTED
      when: IONOS_UNSUPPORTED_EULA_ACCEPTED != "yes"


    - name: Confirm acceptance of EULA
      ansible.builtin.assert:
        that:
          - IONOS_UNSUPPORTED_EULA_ACCEPTED == "yes" or INTERACTIVE_EULA_ACCEPTED.user_input == "yes"  




    # =======================================================================
    - name: Create the datacenter '{{ datacenter_name }}' in {{ location }}
      ionoscloudsdk.ionoscloud.datacenter:
        name: "{{ datacenter_name }}"
        location: "{{ location }}"
        state: present
      register: datacenter_response




    - name: Create a temporary ssh-key-pair so we can connect to the 'internal server' via the jumpbox
      ansible.builtin.shell:
        cmd: ssh-keygen -t rsa -b 4096 -f temporary_id_rsa -N "" || true




    # =======================================================================
    # See https://docs.ionos.com/ansible/api/compute-engine/cube_template
    - name: Retrieve Cube templates
      ionoscloudsdk.ionoscloud.cube_template_info:
        filters: "{ 'properties.name': '{{ cube_size }}' }"
      register: template_list


    # See https://docs.ionos.com/ansible/api/compute-engine/cube_server
    - name: Provision a minimal Cube Jumpbox
      ionoscloudsdk.ionoscloud.cube_server:
        datacenter: "{{ datacenter_name }}"
        name: "{{ jumpbox_name }}"
        template_uuid: "{{ template_list.cube_templates[0].id }}"
        disk_type: DAS
        image: "{{ image_alias }}"
        image_password: "{{ default_password }}"
        ssh_keys:
          - "{{ ssh_public_key }}"
        assign_public_ip: true

        state: present
        wait: true
        wait_timeout: "{{ wait_timeout }}"
      register: create_cube_response


    - name: Create a second, internal LAN within '{{ datacenter_name }}'
      ionoscloudsdk.ionoscloud.lan:
        datacenter: "{{ datacenter_response.datacenter.properties.name }}"
        name: "internal"
        public: false
      register: create_second_lan_response


    - name: Create a second NIC for the Jumpbox
      ionoscloudsdk.ionoscloud.nic:
        datacenter: "{{ datacenter_name }}"
        name: "{{ jumpbox_name }}.eth1"
        server: "{{ jumpbox_name }}"
        lan: "{{ create_second_lan_response.lan.id }}"
        ips:
          - 192.168.16.16
        dhcp: true

        state: present
        wait: true
        wait_timeout: "{{ wait_timeout }}"




    - name: Create the server '{{ int_server_name }}'
      ionoscloudsdk.ionoscloud.server:
        datacenter: "{{ datacenter_name }}"
        name: "{{ int_server_name }}"
        cores: "1"
        ram: "1024"
        cpu_family: "{{ datacenter_response.datacenter.properties.cpu_architecture[0].cpu_family }}"
        disk_type: HDD
        volume_size: "5"
        image: "{{ image_alias }}"
        image_password: "{{ default_password }}"
        ssh_keys:
          - "{{ ssh_public_key }}"
          - "{{ lookup('file', 'temporary_id_rsa.pub') }}"
        lan: "{{ create_second_lan_response.lan.id }}"
        nic_ips:
          - 192.168.16.17
        user_data: "{{ lookup('file', 'cloud-init.txt') | string | b64encode }}"

        state: present
        wait: true
        wait_timeout: "{{ wait_timeout }}"
      register: create_server_response




    # Create a 'local' ssh_config' file for the hosts in this example using the
    # ansible.builtin.template module and a very simple Jinja template file
    - name: Create a local ssh_config file
      ansible.builtin.template:
        src: templates/ssh_config.j2
        dest: ssh_config


    # There are several ways we could 'create' this file (including by using
    # the ansible.builtin.blockinfile or .copy modules, or just by creating a
    # simple, static .yml file), but we've opted for the following to show
    # how one can use HEREDOCs with the ansible.builtin.shell module
    - name: Create a local / 'nested' Ansible inventory.yml file
      ansible.builtin.shell:
        cmd: |
          (cat <<EOF
          ---
          gateways:
            hosts:
              jumpbox:


          internal_hosts:
            hosts:
              internal:


          all:
            vars:
              ansible_ssh_common_args: "-F ssh_config"
          EOF
          ) > inventory.yml


    - name: Delete any pre-existing ssh_known_hosts_tmp file
      ansible.builtin.shell: rm -f ssh_known_hosts_tmp


    # While one would, ordinarily, use, e.g., ansible.builtin.copy, in _this_ case
    # --- i.e. because we're using 'hosts: localhost, connection: local' rather
    # than connecting to the remote hosts --- it's arguably simpler to just scp
    # the file in question over to the jumpbox
    - name: Copy temporary ssh private key to the jumpbox
      ansible.builtin.shell: scp -F ssh_config temporary_id_rsa jumpbox:/root/.ssh/id_rsa




    # =======================================================================
    - name: Provisioning done, print next steps
      ansible.builtin.debug:
        msg:
          - "Both servers successfully provisioned. To connect to the jumpbox, run:"
          - "    ssh -F ssh_config jumpbox"
          - "To connect to the internal server _via_ the jumpbox, use the command:"
          - "    ssh -F ssh_config internal"
          - "And to run the configure-internal-server.yml on the _internal_ server, run:"
          - "    ansible-playbook -i inventory.yml configure-internal-server.yml"




    # =======================================================================
    - name: Wait for user confirmation
      ansible.builtin.pause:
        prompt: "End of example. Press <Enter> when you are ready for the contents of {{ datacenter_name }} to be deleted..."


    - name: Delete the datacenter '{{ datacenter_name }}' and everything contained therein
      ionoscloudsdk.ionoscloud.datacenter:
        datacenter: "{{ datacenter_response.datacenter.id }}"
        state: absent


    - name: And delete any 'temporary' or run-time files that might cause problems between iterations
      ansible.builtin.file:
        path: "{{ item }}"
        state: absent
      with_items:
        - inventory.yml
        - ssh_config
        - ssh_known_hosts_tmp
        - temporary_id_rsa
        - temporary_id_rsa.pub

```

{% endcode %}


# templates\_ssh\_config.j2.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/03__jumpbox_with_internal_server` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```j2
Host *
User root
StrictHostKeyChecking accept-new
UserKnownHostsFile ssh_known_hosts_tmp

Host jumpbox
Hostname {{ create_cube_response['machines'][0]['entities']['nics']['items'][0]['properties']['ips'][0] }}

Host internal
Hostname {{ create_server_response['machines'][0]['entities']['nics']['items'][0]['properties']['ips'][0] }}
ProxyJump jumpbox
IdentityFile temporary_id_rsa

```

{% endcode %}


# Working with existing resources

## Overview

Thus far, all of our examples have consisted of a single Ansible playbook (at least as far as the provisioning tasks were concerned). While fine in *simple* situations, this approach doesn't scale well with the complexity of the problem you're trying to solve (where, e.g., you might need to split your code over multiple, separate playbooks), or if you're wanting to modify pre-existing resources. (In the latter case, in particular, since they might've been provisioned completely independently of any Ansible playbooks, there might never have been any outputs that could've been saved into a register variable.)

In this example, we will look at three ways in which we can work with pre-existing resources:

1. by using an external tool (in this case, `ionosctl`) to look up the required information, and the `ansible.builtin.shell` and `set_fact` modules to process its output;
2. by using the `ansible.builtin.uri` module and the `community.general.json_query` filter to obtain this information via our [Cloud API](https://api.ionos.com/docs/cloud/v6/); and
3. through the use of `ionoscloudsdk.ionoscloud.*_info` modules (which can be thought of as something of an abstraction of Method 2, wrapped into an Ansible module).

## Before you begin

This example also introduces a few new modules, techniques and 'code snippets' that you might find interesting, including:

1. how the output of 'external' command-line tools can be used within Ansible with help of the `ansible.builtin.shell` module;
2. how the `ansible.builtin.uri` module can be used to 'import' data from arbitrary APIs, and more concretely, from our [Cloud API](https://api.ionos.com/docs/cloud/v6/)
3. how the `community.general.json_query` filter can be used to filter JSON documents and create new objects which can then be used by subsequent tasks; and
4. how the `ionoscloudsdk.ionoscloud.*_info` family of modules can be used to obtain 'read-only' information in a more consistent way (and in a way that resembles [Terraform's Data Sources](https://developer.hashicorp.com/terraform/language/data-sources), for those who are already familiar with Terraform).

### What's in this example?

This example includes and/or depends on the following files:

| File          | Description                                                                                                                                                                                                                                            |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `part-1.yml`  | This playbook provisions a single server and an internal LAN (that is not yet connected to any VM) within a new VDC; it is used to create the 'pre-existing resources' that will be used in the subsequent playbooks                                   |
| `part-2.yml`  | This playbook shows the three different ways to work with existing resources that are mentioned above; it retrieves information about the VDC, LANs and servers created in Part 1, and uses some of this information to add a second NIC to the server |
| `part-3.yml`  | This playbook cleans up all of the resources provisioned in Parts 1 and 2, and should be run once you're done with the earlier parts                                                                                                                   |
| `vars.yml`    | This file contains the variable definitions common to `part-1.yml`, `part-2.yml` and `part-3.yml`                                                                                                                                                      |
| `../vars.yml` | This file is common to all of our Ansible examples and contains a set of more generally-used variable definitions                                                                                                                                      |

## Usage

1. To provision our 'starting' infrastructure, run the following command:

   ```
   ansible-playbook part-1.yml
   ```
2. To execute the 'meat' of this example, run the following command (possilby after enabling `verbose_debugging` — see below):

   ```
   ansible-playbook part-2.yml
   ```
3. Examine the outputs of the previous step; if you'd like to make changes to `part-2.yml`, you can delete the resources that were provisioned in Step 2, and re-run said playbook
4. Execute the following to delete the resources provisioned in the previous steps:

   ```
   ansible-playbook part-3.yml
   ```

To see additional 'debugging' information — in particular, the results of the API call, and the raw and filtered output of the `ionoscloudsdk.ionoscloud.server_info` module — you can set `verbose_debugging` to `true` in `../vars.yml`

### Troubleshooting tips

* As `part-2.yml` depends on having a working installation of `ionosctl`, if the `Retrieve information about '{{ datacenter_name }}' via ionosctl` task fails, you might want to make sure the following command returns the expected information: `ionosctl datacenter list`. (If it doesn't, please refer to [docs.ionos.com/cli-ionosctl](https://docs.ionos.com/cli-ionosctl).)
* If calls to the `ansible.builtin.uri` module throw authentication errors despite, e.g., having a valid `IONOS_TOKEN` environment variable, you might want to remove any entries for the 'machine' `api.ionos.com` from your `~/.netrc` file (as the `uri` module will try to use the authentication information contained there over our explicit use of the `Authorization` header variable).
  * If you still experience problems with the `uri` module, the output of the following 'direct API' call might be helpful:

    ```
    curl -X GET "https://api.ionos.com/cloudapi/v6/datacenters/?pretty=true&depth=0" \
      -H "accept: application/json" \
      -H "Authorization: Bearer ${IONOS_TOKEN}"
    ```

## Summary

In this tutorial, we saw three different ways in which we can work with previously-provisioned resources:

1. using the `ansible.builtin.shell` module and the output of an 'external' command-line tool;
2. using the `ansible.builtin.uri` module together with the `community.general.json_query` filter; and
3. using the `ionoscloudsdk.ionoscloud.*_info` family of 'data source' modules

## Source files

The source files for this tutorial can be downloaded from its [Github repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git`, and changing into the `module-ansible/docs/tutorials/04__working_with_existing_resources` sub-directory.


# part-1.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/04__working_with_existing_resources` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```yml
---
- hosts: localhost
  connection: local
  gather_facts: false

  vars_files:
    - ../vars.yml
    - vars.yml




  tasks:
    # =======================================================================
    - name: Display EULA
      ansible.builtin.pause:
        prompt: "{{ IONOS_UNSUPPORTED_EULA }}"
      register: INTERACTIVE_EULA_ACCEPTED
      when: IONOS_UNSUPPORTED_EULA_ACCEPTED != "yes"


    - name: Confirm acceptance of EULA
      ansible.builtin.assert:
        that:
          - IONOS_UNSUPPORTED_EULA_ACCEPTED == "yes" or INTERACTIVE_EULA_ACCEPTED.user_input == "yes"  




    # =======================================================================
    - name: Create the datacenter '{{ datacenter_name }}' in {{ location }}
      ionoscloudsdk.ionoscloud.datacenter:
        name: "{{ datacenter_name }}"
        location: "{{ location }}"
        state: present
      register: datacenter_response


    - name: Create a second LAN within '{{ datacenter_name }}'
      ionoscloudsdk.ionoscloud.lan:
        datacenter: "{{ datacenter_response.datacenter.properties.name }}"
        name: "internal"
        public: false


    - name: Create the server '{{ server_name }}' --- this may take a while, please don't interrupt this operation...)
      ionoscloudsdk.ionoscloud.server:
        datacenter: "{{ datacenter_response.datacenter.properties.name }}"
        name: "{{ server_name }}"
        cores: "1"
        ram: "1024"
        cpu_family: "{{ datacenter_response.datacenter.properties.cpu_architecture[0].cpu_family }}"
        assign_public_ip: true
        disk_type: HDD
        volume_size: "5"
        image: "{{ image_alias }}"
        image_password: "{{ default_password }}"
        ssh_keys:
          - "{{ ssh_public_key }}"

        state: present
        wait: true
        wait_timeout: "{{ wait_timeout }}"
      # previously we have saved the output of this task in the following 
      # register variable, but since _this_ installment is all about using
      # pre-existing resources, we'll skip this step, and show a few ways
      # to obtain such information module in part-2.yml
      ##register: create_server_response
    

```

{% endcode %}


# part-2.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/04__working_with_existing_resources` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```yml
---
- hosts: localhost
  connection: local
  gather_facts: false

  vars_files:
    - ../vars.yml
    - vars.yml




  tasks:
    # =======================================================================
    # Method 1: Using ansible.builtin.shell, something like `ionosctl` and
    # set_fact to create a new object containing the attributes of interest
    - name: Retrieve information about '{{ datacenter_name }}' via ionosctl
      ansible.builtin.shell: ionosctl datacenter list | grep '{{ datacenter_name }}' | cut -d' ' -f1
      register: ionosctl_datacenter_response


    - name: Print contents of 'ionosctl_datacenter_response'
      ansible.builtin.debug:
        var: ionosctl_datacenter_response
      when: verbose_debugging


    - name: Set ionosctl-derived fact
      ansible.builtin.set_fact:
        datacenter: { 'name': "{{ datacenter_name }}", 'id': "{{ ionosctl_datacenter_response.stdout }}" }




    # =======================================================================
    # Method 2: Using the Cloud API (https://api.ionos.com/docs/cloud/v6/),
    # the ansible.builtin.uri module, Bearer Authorization and json_query
    - name: Get information about the LANs in '{{ datacenter_name }}' via the uri module
      ansible.builtin.uri:
        url: "https://api.ionos.com/cloudapi/v6/datacenters/{{ datacenter.id }}/lans?pretty=true&depth=2&offset=0&limit=1000"
        method: GET
        return_content: true
        headers:
          Authorization: "Bearer {{ lookup('ansible.builtin.env', 'IONOS_TOKEN', default='') }}"
      no_log: true
      register: api__get_lans_response


    - name: Print the contents of 'api__get_lans_response'
      ansible.builtin.debug:
        var: api__get_lans_response
      when: verbose_debugging


    # See https://docs.ansible.com/ansible/latest/collections/community/general/docsite/filter_guide_selecting_json_data.html
    # for insights into how `json_query` can be used. Note that, since the
    # reserved characters in 'content' are actually escaped, we first need
    # to pass it through `from_json` before we can perform the query
    - name: Set a couple of LAN-related facts based on the above
      ansible.builtin.set_fact:
        all_lans: "{{ api__get_lans_response.content | from_json | json_query('items[*].{id: id, properties: properties}') }}"
        secondary_lan: "{{ (api__get_lans_response.content | from_json | json_query(query))[0] }}"
      vars:
        query: "items[?properties.name=='internal'].{id: id, properties: properties}"


    # Add a second NIC to the server by name
    - name: Add a second NIC to the server
      ionoscloudsdk.ionoscloud.nic:
        datacenter: "{{ datacenter_name }}"
        name: "{{ server_name }}.eth1"
        server: "{{ server_name }}"
        lan: "{{ secondary_lan.id }}"
        ips:
          - 192.168.16.16
        dhcp: true

        state: present
        wait: true
        wait_timeout: "{{ wait_timeout }}"




    # =======================================================================
    # Method 3: Using one of the supported `_info` modules --- in this case,
    # `ionoscloudsdk.ionoscloud.server_info` --- to retrieve information 
    # _all_ of the servers contained in the Data Center 'datacenter_name'
    - name: Get information about the server '{{ server_name }}' using the server_info module
      ionoscloudsdk.ionoscloud.server_info:
        datacenter: "{{ datacenter_name }}"
        depth: 5
      register: get_server_response


    # And retrieve the desired 'server information object' by iterating over
    # 'get_server_response.servers' and comparing 'item.properties.name' to
    # the value of 'server_name'. (Note that, as server names do _not_ have
    # to be unique, this approach cannot be used in _every_ conceivable
    #  situation, however as long as server names are unique, it will work
    - name: Retrieve information for the server '{{ server_name }}' by manually iterating through 'get_server_response'
      ansible.builtin.set_fact:
        desired_server_info__iter: "{{ item }}"
      when: item.properties.name == server_name
      with_items: "{{ get_server_response.servers }}"


    # Alternatively, we can create a list of 'server information objects'
    # whose 'properties.name' value matches 'server_name'; in _this_ case,
    # if there are multiple servers with the same name, information about
    # _all_ of them will be returned
    - name: Retrieve information for the server '{{ server_name }}' using `json_query`
      ansible.builtin.set_fact:
        desired_server_info__query: "{{ get_server_response | json_query(query) }}"
      vars:
        query: "servers[?properties.name=='{{ server_name }}']"




    - name: Print the contents of 'desired_server_info__iter'
      ansible.builtin.debug:
        var: desired_server_info__iter
      when: verbose_debugging


    - name: Print the contents of 'desired_server_info__query'
      ansible.builtin.debug:
        var: desired_server_info__query
      when: verbose_debugging

```

{% endcode %}


# part-3.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/04__working_with_existing_resources` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```yml
---
- hosts: localhost
  connection: local
  gather_facts: false

  vars_files:
    - ../vars.yml
    - vars.yml

  


  tasks:
    - name: Get information about the existing data centers
      ansible.builtin.uri:
        url: "https://api.ionos.com/cloudapi/v6/datacenters?pretty=true&depth=1&offset=0&limit=1000"
        method: GET
        return_content: true
        headers:
          Authorization: "Bearer {{ lookup('ansible.builtin.env', 'IONOS_TOKEN', default='') }}"
      no_log: true
      register: api__get_datacenters_response


    - name: Extract the relevant entry from 'api__get_datacenters_response'
      ansible.builtin.set_fact:
        datacenter: "{{ api__get_datacenters_response.content | from_json | json_query(jquery) }}"
      vars:
        jquery: "items[?properties.name=='{{ datacenter_name }}'].{id: id, name: properties.name}"


    - name: Wait for user confirmation
      ansible.builtin.pause:
        prompt: "About to delete '{{ datacenter[0].name }}'' and all of its contents. Press <Enter> to proceed..."


    - name: Delete the datacenter '{{ datacenter[0].name }}' and everything contained therein
      ionoscloudsdk.ionoscloud.datacenter:
        datacenter: "{{ datacenter[0].id }}"
        state: absent

```

{% endcode %}


# vars.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/04__working_with_existing_resources` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```yml
datacenter_name: Ansible Tutorials - Working with existing resources
server_name: Example server

```

{% endcode %}


# Introducing roles

## Overview

In this example, we will take a quick digression to look at [Ansible Roles](https://docs.ansible.com/ansible/latest//playbook_guide/playbooks_reuse_roles.html) and how they can be used to make your code more reusable.

As roles are a core feature of Ansible — i.e. they are completely independent of the IONOS Core Ansible Module — we won't go into any explanation of their structure or how to create them (though a few useful references are mentioned at the bottom of this document); rather, this is more about providing an example that you can look at and (potentially) use as a starting point for some of your own sample projects.

## Before you begin

If you're not already familiar with the concepts of roles, you might want to look at the [Ansible Roles](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_reuse_roles.html) section of the official documentation before continuing with the rest of this tutorial.

### What's in this example?

This example includes and/or depends on the following files:

| File                      | Description                                                                                                                    |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `part-1.yml`              | This playbook provisions a single server and creates a few temporary files that are used by the subsequent playbooks           |
| `part-2.yml`              | This playbook runs *on* the newly-provisioned server and applies a few roles to this VM                                        |
| `part-3.yml`              | This playbook cleans up all of the resources provisioned in Part 1, and should be run, once you're done with the earlier parts |
| `vars.yml`                | This file contains the variable definitions common to `part-1.yml`, `part-2.yml` and `part-3.yml`                              |
| `../vars.yml`             | This file is common to all of our Ansible examples and contains a set of more generally-used variable definitions              |
| `templates/ssh_config.j2` | A simple Jinja template, in this case, to dynamically create the `ssh_config` file mentioned above                             |
| `roles/`                  | A set simple, unofficial but usable roles that will be used in this example, and which you cold look at and/or edit            |

## Usage

1. To provision our 'starting' infrastructure, run the following command:

   ```
   ansible-playbook part-1.yml
   ```
2. To execute the 'meat' of this example, run the following command (possibly after enabling `verbose_debugging` — see below):

   ```
   ansible-playbook -i inventory.yml part-2.yml
   ```
3. Optionally, examine the outputs of the previous step; to ssh into the VM, type the following *from the same directory in another shell*:

   ```
   ssh -F ssh_config example-server
   ```
4. Execute the following to delete the resources provisioned in the previous steps:

   ```
   ansible-playbook part-3.yml
   ```

## Resources and references

* Ansible Documentation. Using Ansible playbooks / Working with playbooks / Roles. Available from [docs.ansible.com/ansible/latest//playbook\_guide/playbooks\_reuse\_roles.html](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_reuse_roles.html)
* Ansible Documentation. Galaxy User Guide / Installing roles from Galaxy. Available from [docs.ansible.com/ansible/latest/galaxy/user\_guide.html#installing-roles-from-galaxy](https://docs.ansible.com/ansible/latest/galaxy/user_guide.html#installing-roles-from-galaxy)
* Red Hat, Enable Sysadmin (April 2021). 8 Steps to developing an Ansible Role in Linux. Retrieved from [https://www.redhat.com/sysadmin/developing-ansible-role](https://github.com/ionos-cloud/module-ansible/blob/master/docs/tutorials/05__introducing_roles/redhat.com/sysadmin/developing-ansible-role/README.md) on 17 May 2023.


# part-1.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/05__introducing_roles` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```yml
---
- hosts: localhost
  connection: local
  gather_facts: false

  vars_files:
    - ../vars.yml
    - vars.yml




  tasks:
    # =======================================================================
    - name: Display EULA
      ansible.builtin.pause:
        prompt: "{{ IONOS_UNSUPPORTED_EULA }}"
      register: INTERACTIVE_EULA_ACCEPTED
      when: IONOS_UNSUPPORTED_EULA_ACCEPTED != "yes"


    - name: Confirm acceptance of EULA
      ansible.builtin.assert:
        that:
          - IONOS_UNSUPPORTED_EULA_ACCEPTED == "yes" or INTERACTIVE_EULA_ACCEPTED.user_input == "yes"  




    # =======================================================================
    - name: Create the datacenter '{{ datacenter_name }}' in {{ location }}
      ionoscloudsdk.ionoscloud.datacenter:
        name: "{{ datacenter_name }}"
        location: "{{ location }}"
        state: present
      register: datacenter_response


    - name: Create the server '{{ server_name }}'
      ionoscloudsdk.ionoscloud.server:
        datacenter: "{{ datacenter_response.datacenter.properties.name }}"
        name: "{{ server_name }}"
        cores: "1"
        ram: "1024"
        cpu_family: "{{ datacenter_response.datacenter.properties.cpu_architecture[0].cpu_family }}"
        assign_public_ip: true
        disk_type: HDD
        volume_size: "10"
        image: "{{ image_alias }}"
        image_password: "{{ default_password }}"
        ssh_keys:
          - "{{ ssh_public_key }}"

        state: present
        wait: true
        wait_timeout: "{{ wait_timeout }}"    
      register: create_server_response


    # Borrowed from 3__jumpbox_with_internal_server
    - name: Create a local ssh_config file
      ansible.builtin.template:
        src: templates/ssh_config.j2
        dest: ssh_config


    - name: Create a local / 'nested' Ansible inventory.yml file
      ansible.builtin.shell:
        cmd: |
          (cat <<EOF
          ---
          servers:
            hosts:
              example-server:


          all:
            vars:
              ansible_ssh_common_args: "-F ssh_config"
          EOF
          ) > inventory.yml


    - name: Delete any pre-existing ssh_known_hosts_tmp file
      ansible.builtin.shell: rm -f ssh_known_hosts_tmp

```

{% endcode %}


# part-2.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/05__introducing_roles` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```yml
---
# Unlike main.yml (which communicates with the IONOS CLOUD Ansible module via
# localhost), _this_ playbook is run on / within the VM
- hosts: example-server


  vars:
    # roles that will be applied iterately at the _end_ of this play --- note
    # that 'common/base-server' is explicitly applied below (e.g. to update
    # the system's packages), while the nfs-server and -client roles are also
    # applied explicitly due to their role-specific parameters
    roles_to_apply:
      - common/fail2ban
      - docker-server




  tasks:
    # Perform some basic / preparatory tasks
    - name: Update repositories cache and upgrade the system
      ansible.builtin.apt:
        upgrade: dist
        update_cache: yes
        cache_valid_time: 3600


    - name: Gather the package facts
      ansible.builtin.package_facts:
        manager: auto




    # An example of the simplest way to include a role
    - name: Apply the common 'base-server' role
      include_role:
        name: common/base-server




    # Examples of how variables can be passed to included roles
    - name: Apply the 'nfs-server' role
      include_role:
        name: nfs-server
      vars:
        - export_root: /export
        - export_specifier: "127.0.0.1(ro,sync,no_subtree_check,no_root_squash)"


    - name: Apply the 'nfs-client' role
      include_role:
        name: nfs-client
      vars:
        nfs_mount_point: /mnt
        nfs_server_path: "127.0.0.1:/export"




    # And finally, an example of how one might apply a list of roles
    - name: And apply the remaining roles to target system
      include_role:
        name: "{{ role }}"
      with_items: "{{ roles_to_apply }}"
      loop_control:
        loop_var: role

```

{% endcode %}


# part-3.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/05__introducing_roles` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```yml
---
- hosts: localhost
  connection: local
  gather_facts: false

  vars_files:
    - ../vars.yml
    - vars.yml

  


  tasks:
    # =======================================================================
    # - name: Get information about the existing data centers
    #   ansible.builtin.uri:
    #     url: "https://api.ionos.com/cloudapi/v6/datacenters?pretty=true&depth=1&offset=0&limit=1000"
    #     method: GET
    #     return_content: true
    #     headers:
    #       Authorization: "Bearer {{ lookup('ansible.builtin.env', 'IONOS_TOKEN', default='') }}"
    #   no_log: true
    #   register: api__get_datacenters_response


    # - name: Extract the relevant entry from 'api__get_datacenters_response'
    #   ansible.builtin.set_fact:
    #     datacenter: "{{ (api__get_datacenters_response.content | from_json | json_query(jquery))[0] }}"
    #   vars:
    #     jquery: "items[?properties.name=='{{ datacenter_name }}'].{id: id, name: properties.name}"
    - name: Get information about the datacenter '{{ datacenter_name }}'
      ionoscloudsdk.ionoscloud.datacenter_info:
        filters: { 'properties.name': '{{ datacenter_name }}' }
      register: datacenter_info_response




    - name: Wait for user confirmation
      ansible.builtin.pause:
        prompt: "About to delete '{{ datacenter_info_response.datacenters[0].properties.name }}'' and all of its contents. Press <Enter> to proceed..."


    - name: Delete the datacenter '{{ datacenter_name }}' and everything contained therein
      ionoscloudsdk.ionoscloud.datacenter:
        datacenter: "{{ datacenter_info_response.datacenters[0].id }}"
        state: absent


    - name: And delete any 'temporary' or run-time files
      ansible.builtin.file:
        path: "{{ item }}"
        state: absent
      with_items:
        - ssh_config
        - ssh_known_hosts_tmp
        - inventory.yml

```

{% endcode %}


# roles\_common\_base-server\_meta\_main.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/05__introducing_roles` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```yml
galaxy_info:
  author: Peter Metz <peter.metz@ionos.com>
  description: Perform basic / role-independent / common server configuration
  company: IONOS CLOUD

  min_ansible_version: 2.1

  platforms:
  - name: Debian
    versions:
      - all
  - name: Ubuntu
    versions:
      - focal
      - jammy

  galaxy_tags: []


dependencies: []
```

{% endcode %}


# roles\_common\_base-server\_tasks\_main.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/05__introducing_roles` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```yml
---
# ==============================================================================
- name: About to execute tasks file for 'common/base server' role
  ansible.builtin.meta: noop




- name: Update repositories cache and upgrade the system
  ansible.builtin.apt:
    upgrade: dist
    update_cache: yes
    cache_valid_time: 3600




- name: Install some more-or-less essential packages
  ansible.builtin.package:
    name:
      - sudo
      - curl
      - wget
      - git
      - screen
      - nmap
      - traceroute
    state: present
```

{% endcode %}


# roles\_common\_fail2ban\_meta\_main.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/05__introducing_roles` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```yml
galaxy_info:
  author: Peter Metz <peter.metz@ionos.com>
  description: Install fail2ban
  company: IONOS CLOUD

  min_ansible_version: 2.1

  platforms:
  - name: Debian
    versions:
      - all
  - name: Ubuntu
    versions:
      - focal
      - jammy

  galaxy_tags: []


dependencies: []
```

{% endcode %}


# roles\_common\_fail2ban\_tasks\_main.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/05__introducing_roles` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```yml
---
# ==============================================================================
- name: About to execute tasks file for role 'fail2ban'
  ansible.builtin.meta: noop



- name: Install fail2ban
  ansible.builtin.package:
    name:
      - fail2ban
    state: present
```

{% endcode %}


# roles\_docker-server\_meta\_main.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/05__introducing_roles` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```yml
galaxy_info:
  author: Peter Metz <peter.metz@ionos.com>
  description: Install and configure Docker CE and friends
  company: IONOS CLOUD

  min_ansible_version: 2.1

  platforms:
  - name: Debian
    versions:
      - all
  - name: Ubuntu
    versions:
      - focal
      - jammy

  galaxy_tags: []


dependencies: []
```

{% endcode %}


# roles\_docker-server\_tasks\_main.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/05__introducing_roles` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```yml
---
# ==============================================================================
- name: About to execute tasks file for role 'docker-server'
  ansible.builtin.meta: noop



- name: Make sure all the dependencies are installed
  ansible.builtin.package:
    name:
      - apt-transport-https
      - ca-certificates
      - curl
      - gnupg
      - lsb-release
    state: present


- name: Add signing key
  ansible.builtin.apt_key:
    url: "https://download.docker.com/linux/{{ ansible_distribution | lower }}/gpg"
    state: present


- name: Add repository into sources list
  ansible.builtin.apt_repository:
#    repo: "deb [arch={{ ansible_architecture }}] https://download.docker.com/linux/{{ ansible_distribution | lower }} {{ ansible_distribution_release }} stable"
    repo: "deb [arch=amd64] https://download.docker.com/linux/{{ ansible_distribution | lower }} {{ ansible_distribution_release }} stable"
    state: present
    filename: docker


- name: Update the repositories cache
  ansible.builtin.apt:
    update_cache: yes


- name: Install Docker
  ansible.builtin.package:
    name:
      - containerd.io
      - docker-ce
      - docker-ce-cli
      - docker-compose-plugin
      - docker-compose
      - docker-registry
    state: present


# See https://docs.ansible.com/ansible/latest/collections/community/docker/docker_container_module.html#examples
- name: Create test containers
  community.docker.docker_container:
    name: "test-{{ test_image }}"
    image: "{{ test_image }}"
    auto_remove: true
    state: present
```

{% endcode %}


# roles\_docker-server\_vars\_main.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/05__introducing_roles` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```yml
---
test_image: hello-world
```

{% endcode %}


# roles\_nfs-client\_meta\_main.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/05__introducing_roles` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```yml
galaxy_info:
  author: Peter Metz <peter.metz@ionos.com>
  description: Install and configure an autofs-managed NFS client
  company: IONOS CLOUD

  min_ansible_version: 2.1

  platforms:
  - name: Debian
    versions:
      - all
  - name: Ubuntu
    versions:
      - focal
      - jammy

  galaxy_tags: []


dependencies: []
```

{% endcode %}


# roles\_nfs-client\_tasks\_main.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/05__introducing_roles` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```yml
---
# ==============================================================================
- name: About to execute tasks file for role 'nfs-client'
  ansible.builtin.meta: noop




- name: Install the NFS client
  ansible.builtin.package:
    name:
      - nfs-common
    state: present


- name: Install autofs
  ansible.builtin.package:
    name:
      - autofs
    state: present


- name: Add an entry to /etc/auto.master
  ansible.builtin.lineinfile:
    path: /etc/auto.master
    line: '/-   /etc/auto.nfs'


- name: Create / add an entry to /etc/auto.nfs
  ansible.builtin.lineinfile:
    path: /etc/auto.nfs
    line: "{{ nfs_mount_point }}    {{ nfs_server_path }}"
    create: yes
  when: nfs_server_path | length > 0


- name: Restart the automounter service so these changes can take effect
  ansible.builtin.service:
    name: autofs
    state: restarted
```

{% endcode %}


# roles\_nfs-client\_vars\_main.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/05__introducing_roles` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```yml
---
nfs_mount_point: /export
nfs_server_path: ""
```

{% endcode %}


# roles\_nfs-server\_meta\_main.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/05__introducing_roles` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```yml
galaxy_info:
  author: Peter Metz <peter.metz@ionos.com>
  description: Install and configure an NFS server
  company: IONOS CLOUD

  min_ansible_version: 2.1

  platforms:
  - name: Debian
    versions:
      - all
  - name: Ubuntu
    versions:
      - focal
      - jammy

  galaxy_tags: []


dependencies: []
```

{% endcode %}


# roles\_nfs-server\_tasks\_main.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/05__introducing_roles` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```yml
---
# ==============================================================================
- name: About to execute tasks file for role 'nfs-server'
  ansible.builtin.meta: noop




- name: Install and setup an NFS server
  ansible.builtin.package:
    name:
      - nfs-kernel-server
    state: present


- name: Create the host-share directory
  ansible.builtin.file:
    path: "{{ export_root }}"
    state: directory
    mode: '1777'


- name: Create entry in /etc/exports
  ansible.builtin.lineinfile:
    path: /etc/exports
    line: "{{ export_root }}    {{ export_specifier }}"


- name: Copying the contents of {{ export_preload_path }} to nfs_server:/{{ export_root }}
  ansible.builtin.copy:
    src: "{{ export_preload_path }}"
    dest: "{{ export_root }}"
  when: export_preload_path | length > 0


- name: Tell nfs-server to reload its config
  ansible.builtin.service:
    name: nfs-server
    state: reloaded
```

{% endcode %}


# roles\_nfs-server\_vars\_main.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/05__introducing_roles` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```yml
---
export_root: /export
export_specifier: 0.0.0.0/0(ro,sync,no_subtree_check)
export_preload_path: ""
```

{% endcode %}


# templates\_ssh\_config.j2.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/05__introducing_roles` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```j2
Host *
User root
StrictHostKeyChecking accept-new
UserKnownHostsFile ssh_known_hosts_tmp

Host example-server
Hostname {{ create_server_response['machines'][0]['entities']['nics']['items'][0]['properties']['ips'][0] }}

```

{% endcode %}


# vars.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/05__introducing_roles` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```yml
datacenter_name: Ansible Tutorials - Introducing roles
server_name: Example server

```

{% endcode %}


# Introducing the NAT Gateway and Network Load Balancer

![alt text](https://860290032-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MUORV1X4hkCRIcUbMs2-3956399747%2Fuploads%2Fgit-blob-e648ef09cb0abc78ef1bc06e51c61f4bee35e54a%2Fnetwork-topology.png?alt=media)

In this installment, we introduce our first 'non-VM' resources: the [NAT Gateway](https://docs.ionos.com/cloud/managed-services/nat-gateway/overview) and the [Network Load Balancer](https://docs.ionos.com/cloud/managed-services/network-load-balancer/outline) (NLB). The former uses [Source NAT](https://en.wikipedia.org/wiki/Network_address_translation#SNAT) to provide a simple way for for VMs without a *direct* Internet connection to reach public sites and endpoints — something that wasn't possible, e.g., in Part 3 of this series; the latter effectively uses [Destination NAT](https://en.wikipedia.org/wiki/Network_address_translation#DNAT) to provide a relatively 'out-of-the-box' way to acheive *Layer 4* load-balancing and/or redundancy. Their corresponding entries in our Ansible Module's documentation can be found [here](https://docs.ionos.com/ansible/api/nat-gateway/nat_gateway) and [here](https://docs.ionos.com/ansible/api/network-load-balancer/network_load_balancer), respectively.

Please note that, as both the NAT Gateway *and* the NLB require their own reserved IP address, your will need to be able to reserve at least two IP addresses (you can see you how many 'reserved IP addresses' your contract is currently using and still able to reerve in the DCD under \[Profile Icon] --> Resource Overview).

> **Also note:** From [docs.ionos.com/cloud/managed-services/network-load-balancer](https://docs.ionos.com/cloud/managed-services/network-load-balancer/outline#limitations):
>
> SNAT Support: Managed NLB is *not* configured to support Source NAT (SNAT); targets cannot initiate network connections through the load balancer.
>
> NLB operates at TCP/IP layer 4 of the Open Systems Interconnection (OSI) model. NLB will distribute any TCP-based network traffic, including upper application layer protocols, such as HTTP and HTTPS. However, rules and health checks are strictly TCP-based, which means that HTTP rules (e.g., routing decisions based on the URL) are not supported.

## What's in this example?

This example consists of the following files:

| File                                 | Description                                                                                                                                                                                                                                                                                                                                                                                                                  |
| ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `01__create_jumpbox_and_nat_gw.yml`  | This playbook builds upon the Cube-related code from Example 3, by adding the necessary calls to reserve an IP address block and create a NAT Gateway with its associated rule                                                                                                                                                                                                                                               |
| `02__create_app_servers_and_nlb.yml` | After retrieving the necessary information via the Cloud API, this playbook provisions one or more 'application servers' and an NLB, along with two rules that will forward incoming `ssh` and `http` requests to said servers in a round-robin fashion. (And whilst it's hardly ground-breaking, this playbook also shows how one might provision multiple 'sister-VMs' given a minimal list of configuration options, too) |
| `03__configure_app_servers.yml`      | This playbook runs on the app servers themselves to (amongst other things) install the NGINX web server and custom, host-specific `index.html` files (which, in turn, show which server you've reached)                                                                                                                                                                                                                      |
| `04__clean_up.yml`                   | This playbook cleans up all of the resources provisioned in the previous parts, and should be run once you're done with the earlier parts                                                                                                                                                                                                                                                                                    |
| `vars.yml`                           | This file contains the variable definitions common to all of this example's individual playbooks                                                                                                                                                                                                                                                                                                                             |
| `../vars.yml`                        | This file is common to all of our Ansible examples and contains a set of more generally-used variable definitions                                                                                                                                                                                                                                                                                                            |

More concretely, this example introduces the following IONOS CLOUD modules:

1. `ionoscloudsdk.ionoscloud.ipblock`
2. `ionoscloudsdk.ionoscloud.nat_gateway` and `nat_gateway_rule`
3. `ionoscloudsdk.ionoscloud.network_load_balancer` and `network_load_balancer_rule`

whilst also showing how one can dynamically create a *list of objects* given a pre-existing list (see the three `set_fact` tasks beginning with the one which defines `target_ips` in `02__create_app_servers_and_nlb.yml`).

## Usage

> **Note:** As with all other 'executable' examples in this repository, an 'End User Licence Agreement'-like statement will be displayed, which must also be accepted before the tasks proper can be executed.
>
> Please note that, while potentially quite minimal, you will incur charges for the resources based upon how long you keep them provisioned; for more information on the actual costs, you can follow the links displayed in the 'EULA' text. Also note that, if you run the following through to completion, the playbook should 'clean up' after itself, but we recommend you verify this, e.g., via the DCD or `ionosctl` to make sure you won't be charged for any unwanted resources.

1. To provision the jumpbox and NAT Gateway, run the following command:

   ```
   ansible-playbook 01__create_jumpbox_and_nat_gw.yml
   ```
2. To provision the application servers and the NLB, run the following command:

   ```
   ansible-playbook 02__create_app_servers_and_nlb.yml
   ```
3. To *configure* the application servers that were provisioned in Step 2, run:

   ```
   ansible-playbook -i inventory.yml 03__configure_app_servers.yml
   ```
4. Optionally, examine the resources that were provisioned in Steps 1 and 2
5. Execute the following to delete the resources provisioned in the previous steps:

   ```
   ansible-playbook 04__clean_up.yml
   ```

Between Steps 3 and 5, you can also run the following commands to access the various resources, directly and via the load balancer:

| Command                            | Description                                                                                                                                                                                                                                       |
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ssh -F ssh_config ${TARGET_HOST}` | ssh into the specified server, where `${TARGET_HOST}` is one of `jumpbox`, `app-server-1` or `app-server-2`                                                                                                                                       |
| `ssh -F ssh_config nlb`            | ssh into *one* of the app servers via the load balancer (in a round-robin fashion); to see, e.g., the internal servers' IP addresses, you could append `ip addr` to the 'base command'                                                            |
| `curl http://${NLB_ADDRESS}`       | retrieve the `index.html` file from one of the app servers via the load balancer, where `${NLB_ADDRESS}` is the public IP address assigned to the NLB (visible either, e.g., via `ionosctl ipblock list` or the DCD, or in the `ssh_config` file) |

## Summary

In this tutorial, we saw examples of:

1. how to use the `ionoscloudsdk.ionoscloud.ipblock` module to reserve an IP address block;
2. how the `ionoscloudsdk.ionoscloud.nat_gateway` and `nat_gateway_rule` modules can be used to provision and configure a NAT Gateway;
3. how the `ionoscloudsdk.ionoscloud.network_load_balancer` and `network_load_balancer_rule` modules can be used to provision and configure an NLB; and
4. how we can verify that an NLB with a round-robin policy is forwarding incoming connections as expected.


# 01\_\_create\_jumpbox\_and\_nat\_gw\.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/06__introducing_the_nat_gateway_and_network_load_balancer` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```yml
---
- hosts: localhost
  connection: local
  gather_facts: false

  vars_files:
    - ../vars.yml
    - vars.yml




  tasks:
    # =======================================================================
    - name: Display EULA
      ansible.builtin.pause:
        prompt: "{{ IONOS_UNSUPPORTED_EULA }}"
      register: INTERACTIVE_EULA_ACCEPTED
      when: IONOS_UNSUPPORTED_EULA_ACCEPTED != "yes"


    - name: Confirm acceptance of EULA
      ansible.builtin.assert:
        that:
          - IONOS_UNSUPPORTED_EULA_ACCEPTED == "yes" or INTERACTIVE_EULA_ACCEPTED.user_input == "yes"  




    # =======================================================================
    - name: Create the datacenter '{{ datacenter_name }}' in {{ location }}
      ionoscloudsdk.ionoscloud.datacenter:
        name: "{{ datacenter_name }}"
        location: "{{ location }}"
        state: present
      register: datacenter_response




    # =======================================================================
    # Provision the jumpbox, heavily borrowed from 03__jumpbox_with_internal_server
    - name: Retrieve Cube templates
      ionoscloudsdk.ionoscloud.cube_template_info:
        filters: "{ 'properties.name': '{{ server_config['jumpbox'].cube_size }}' }"
      register: template_list


    - name: Provision a minimal Cube Jumpbox
      ionoscloudsdk.ionoscloud.cube_server:
        datacenter: "{{ datacenter_name }}"
        name: "{{ server_config['jumpbox'].name }}"
        template_uuid: "{{ template_list.cube_templates[0].id }}"
        disk_type: DAS
        image: "{{ image_alias }}"
        image_password: "{{ default_password }}"
        ssh_keys:
          - "{{ ssh_public_key }}"
        assign_public_ip: true

        state: present
        wait: true
        wait_timeout: "{{ wait_timeout }}"
      register: create_cube_response


    - name: Create a second, internal LAN within '{{ datacenter_name }}'
      ionoscloudsdk.ionoscloud.lan:
        datacenter: "{{ datacenter_name }}"
        name: "{{ lan.name }}"
        public: false
      register: create_second_lan_response


    - name: Create a second NIC for the Jumpbox
      ionoscloudsdk.ionoscloud.nic:
        datacenter: "{{ datacenter_name }}"
        name: "{{ server_config['jumpbox'].name }}.eth1"
        server: "{{ server_config['jumpbox'].name }}"
        lan: "{{ create_second_lan_response.lan.id }}"
        ips:
          - "{{ server_config['jumpbox'].ip }}"
        dhcp: true

        state: present
        wait: true
        wait_timeout: "{{ wait_timeout }}"




    # =======================================================================
    # Reserve a block of two IP addresses (one for the NAT gateway, one for
    # the NLB). See https://docs.ionos.com/ansible/api/compute-engine/ipblock
    - name: Create an IP Block for our datacenter
      ionoscloudsdk.ionoscloud.ipblock:
        name: "IP Block for {{ datacenter_name }}"
        location: "{{ location }}"
        size: "{{ ip_block.size }}"
        state: present
      register: ip_block_response




    # =======================================================================
    # Create (and, where necessary, transfer) the required temporary files
    - name: Create a temporary ssh-key-pair so we can connect to the 'internal server' via the jumpbox
      ansible.builtin.shell:
        cmd: ssh-keygen -t rsa -b 4096 -f temporary_id_rsa -N "" || true


    - name: Create a local ssh_config file
      ansible.builtin.template:
        src: templates/ssh_config.j2
        dest: ssh_config


    - name: Create a local / 'nested' Ansible inventory.yml file
      ansible.builtin.template:
        src: templates/inventory.j2
        dest: inventory.yml


    - name: Delete any pre-existing ssh_known_hosts_tmp file
      ansible.builtin.shell: rm -f ssh_known_hosts_tmp


    - name: Copy temporary ssh private key to the jumpbox
      ansible.builtin.shell: scp -F ssh_config temporary_id_rsa jumpbox:/root/.ssh/id_rsa




    # =======================================================================
    # Create the NAT Gateway --- see https://docs.ionos.com/ansible/api/nat-gateway/nat_gateway
    - name: Create a NAT Gateway --- this can take a little while (typically between 3 and 8 minutes), so please don't interrupt this operation...
      ionoscloudsdk.ionoscloud.nat_gateway:
        datacenter: "{{ datacenter_name }}"    # can be either the name or the UUID of the datacenter
        name: "{{ nat_gateway.name }}"
        public_ips: 
          - "{{ ip_block_response.ipblock.properties.ips[0] }}"
        lans:
          - id: "{{ create_second_lan_response.lan.id }}"
            gateway_ips: "{{ nat_gateway.ip }}"

        wait: true
        wait_timeout: "{{ vnf_wait_timeout }}"
      register: nat_gateway_response


    # See https://docs.ionos.com/ansible/api/nat-gateway/nat_gateway_rule
    - name: Create an SNAT gateway rule
      ionoscloudsdk.ionoscloud.nat_gateway_rule:
        datacenter: "{{ datacenter_name }}"                         # can be either the name or the UUID of the datacenter
        nat_gateway: "{{ nat_gateway_response.nat_gateway.id }}"    # can be either the name or the UUID of the gateway
        name: "SNAT Default Rule"
        type: "SNAT"
        protocol: "ALL"
        source_subnet: "{{ lan.address }}"
        public_ip: "{{ ip_block_response.ipblock.properties.ips[0] }}"

        wait: true
        wait_timeout: "{{ vnf_wait_timeout }}"

```

{% endcode %}


# 02\_\_create\_app\_servers\_and\_nlb.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/06__introducing_the_nat_gateway_and_network_load_balancer` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```yml
---
- hosts: localhost
  connection: local
  gather_facts: false

  vars_files:
    - ../vars.yml
    - vars.yml

  


  tasks:
    # =======================================================================
    - name: Get information about the datacenter '{{ datacenter_name }}'
      ionoscloudsdk.ionoscloud.datacenter_info:
        filters: { 'properties.name': '{{ datacenter_name }}' }
      register: datacenter_info_response


    - name: Get information about the LANs in '{{ datacenter_name }}'
      ionoscloudsdk.ionoscloud.lan_info:
        datacenter: "{{ datacenter_name }}"
      register: lan_info_response


    - name: Set the fact 'public_lan' based on the above
      ansible.builtin.set_fact:
        public_lan: "{{ (lan_info_response | json_query(query))[0] }}"
      vars:
        query: "lans[?properties.name=='public']"


    - name: Set the fact 'secondary_lan' based on the above
      ansible.builtin.set_fact:
        secondary_lan: "{{ (lan_info_response | json_query(query))[0] }}"
      vars:
        query: "lans[?properties.name=='{{ lan.name }}']"




    # =======================================================================
    # Create the 'app servers' defined in 'server_config.app_server'
    - name: Create the cloud-init file for our app servers
      ansible.builtin.template:
        src: templates/cloud-init--app-servers.j2
        dest: cloud-init--app-servers.txt


    - name: Create the app servers specified in server_config.app_server
      ionoscloudsdk.ionoscloud.server:
        datacenter: "{{ datacenter_name }}"
        name: "{{ item.name }}"
        cores: "{{ item.cores }}"
        ram: "{{ item.ram }}"
        cpu_family: "{{ datacenter_info_response.datacenters[0].properties.cpu_architecture[0].cpu_family }}"
        disk_type: HDD
        volume_size: "5"
        image: "{{ image_alias }}"
        image_password: "{{ default_password }}"
        ssh_keys:
          - "{{ ssh_public_key }}"
          - "{{ lookup('file', 'temporary_id_rsa.pub') }}"
        lan: "{{ secondary_lan.id }}"
        nic_ips:
          - "{{ item.ip }}"
        user_data: "{{ lookup('file', item.user_data_file) | string | b64encode }}"

        state: present
        wait: true
        wait_timeout: "{{ wait_timeout }}"
      with_items: "{{ server_config.app_server }}"
      register: create_app_server_response




    # =======================================================================
    # And finally create and minmally-configure a Network Load Balancer
    - name: Get information about our reserved IP Blocks
      ionoscloudsdk.ionoscloud.ipblock_info:
        filters: "{ 'properties.name': 'IP Block for {{ datacenter_name }}' }"
      register: ipblock_info_response


    - name: Set 'ip_block' based on the above
      ansible.builtin.set_fact:
        ip_block: "{{ ipblock_info_response.ipblocks[0].properties.ips }}"




    # see https://docs.ionos.com/ansible/api/network-load-balancer/network_load_balancer
    #   --> the example really needs the lb_private_ips, too
    - name: Create Network Load Balancer --- sometimes, this can take a while (up to 15 or so minutes), so please don't interrupt this operation...
      ionoscloudsdk.ionoscloud.network_load_balancer:
        datacenter: "{{ datacenter_name }}"
        name: "{{ nlb.name }}"
        listener_lan: "{{ public_lan.id }}"
        ips:
          - "{{ ip_block[1] }}"
        target_lan: "{{ secondary_lan.id }}"
        lb_private_ips:
          - "{{ nlb.ip }}"

        # state: present
        wait: true
        wait_timeout: "{{ vnf_wait_timeout }}"
      register: create_nlb_response


    # Before we can create a forwarding rule, we need the list of destination IPs
    - name: Set 'target_ips' based on 'create_app_server_response'
      ansible.builtin.set_fact:
        target_ips: "{{ create_app_server_response | json_query(query) }}"
      vars:
        query: "results[].machines[].entities.nics.items[].properties.ips"


    # we need two separate set_fact calls to guarantee the targets are initialised
    # as an empty list before they are used in the second call...
    - name: Create targets list
      ansible.builtin.set_fact:
        targets_ssh: []
        targets_http: []

    - name: Add new JSON Objects to 'targets'
      ansible.builtin.set_fact:
        targets_ssh: "{{ targets_ssh + 
                      [{ 'ip': item[0],
                          'port': '22',
                          'weight': '100' }] }}"
        targets_http: "{{ targets_http + 
                       [{ 'ip': item[0],
                          'port': '80',
                          'weight': '100' }] }}"
      loop: "{{ target_ips }}"


    - name: Print target objects
      ansible.builtin.debug:
        msg:
          - "targets_ssh: {{ targets_ssh }}"
          - "targets_http: {{ targets_http }}"
      when: verbose_debugging


    # see https://docs.ionos.com/ansible/api/network-load-balancer/network_load_balancer_rule
    - name: Create Network Load Balancer Forwarding Rule for tcp/ssh
      ionoscloudsdk.ionoscloud.network_load_balancer_rule:
        name: "NLB SSH connections"
        algorithm: "ROUND_ROBIN"
        protocol: "TCP"
        listener_ip: "{{ ip_block[1] }}"
        listener_port: "22"
        targets: "{{ targets_ssh }}"
        datacenter: "{{ datacenter_name }}"
        network_load_balancer: "{{ create_nlb_response.network_load_balancer.id }}"

        wait: true
        wait_timeout: "{{ vnf_wait_timeout }}"
      register: nlb_forwarding_rule_response_ssh


    - name: Create Network Load Balancer Forwarding Rule for tcp/http
      ionoscloudsdk.ionoscloud.network_load_balancer_rule:
        name: "NLB HTTP connections"
        algorithm: "ROUND_ROBIN"
        protocol: "TCP"
        listener_ip: "{{ ip_block[1] }}"
        listener_port: "80"
        targets: "{{ targets_http }}"
        datacenter: "{{ datacenter_name }}"
        network_load_balancer: "{{ create_nlb_response.network_load_balancer.id }}"

        wait: true
        wait_timeout: "{{ vnf_wait_timeout }}"
      register: nlb_forwarding_rule_response_http


    - name: Print the newly-provisioned Load Balancer's public IP address
      ansible.builtin.debug:
        msg:
          - "The NLB's IP address is {{ ip_block[1] }}. To see its forwarding rule in action, run the"
          - "command `curl http://{{ ip_block[1] }}` two or more times _after_ you have configured"
          - "the app-servers via `ansible-playbook -i inventory.yml 03__configure_app_servers.yml"

```

{% endcode %}


# 03\_\_configure\_app\_servers.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/06__introducing_the_nat_gateway_and_network_load_balancer` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```
# Arguably not the most robust solution, but while an approach based upon,
# say, https://stackoverflow.com/a/67379573 would guarantee the resulting
# file is always valid, assuming the level of indention doesn't change,
# the following is simpler, and doesn't remove any comments that said file
# might contain
- name: Add our default route to /etc/netplan/50-cloud-init.yaml to make it persistent
  blockinfile:
    path: /etc/netplan/50-cloud-init.yaml
    insertbefore: "match:"
    block: |
      {% filter indent(width=12, first=true) %}
      routes:
        - to: default
          via: 192.168.8.1
      {% endfilter %}


- name: Ensure 'DNS=212.227.123.16 212.227.123.17' is in the '[Resolve]' section of /etc/systemd/resolved.conf
  community.general.ini_file:
    path: /etc/systemd/resolved.conf
    section: Resolve
    option: DNS
    value: 212.227.123.16 212.227.123.17
    state: present


- name: Restart the systemd-resolved service
  ansible.builtin.service:
    name: systemd-resolved
    state: restarted




- name: Update repositories cache and upgrade the system
  ansible.builtin.apt:
    upgrade: dist
    update_cache: yes
    cache_valid_time: 3600


- name: Install patch and nginx
  ansible.builtin.package:
    name:
      - patch
      - nginx
    state: present


# Apply the changes mentioned in https://docs.nginx.com/nginx/admin-guide/load-balancer/using-proxy-protocol/
- name: Patch the NGINX config files to support the Proxy Protocol
  ansible.posix.patch:
    src: nginx-config.patch
    basedir: /
    strip: 1
  when: nlb.proxy_protocol != "none"


- name: And restart NGINX
  ansible.builtin.service:
    name: nginx
    state: restarted
  when: nlb.proxy_protocol != "none"


- name: Need to recreate the NLB HTTP forwarding rule's targets
  ansible.builtin.debug:
    msg:
      - "NGINX has been configured to support (and expect) the PROXY protocol, however"
      - "until support is also added to the corresponding Ansible module, enabling it"
      - "there will need to be done manually, either via the DCD or an API PATCH call ---"
      - "please see https://docs.ionos.com/cloud/managed-services/network-load-balancer/configure-nlb#create-a-target"
      - "or https://api.ionos.com/docs/cloud/v6/#tag/Network-Load-Balancers/operation/datacentersNetworkloadbalancersForwardingrulesPatch"
      - "for more information"
  when: nlb.proxy_protocol != "none"


- name: And create our per-host index.html files on the remote servers
  ansible.builtin.template:
    src: templates/index.html.j2
    dest: /var/www/html/index.html
```

{% endcode %}


# 04\_\_clean\_up.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/06__introducing_the_nat_gateway_and_network_load_balancer` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```yml
---
- hosts: localhost
  connection: local
  gather_facts: false

  vars_files:
    - ../vars.yml
    - vars.yml

  


  tasks:
    # =======================================================================
    - name: Get information about the datacenter '{{ datacenter_name }}'
      ionoscloudsdk.ionoscloud.datacenter_info:
        filters: { 'properties.name': '{{ datacenter_name }}' }
      register: datacenter_info_response


    - name: Wait for user confirmation
      ansible.builtin.pause:
        prompt: "About to delete '{{ datacenter_info_response.datacenters[0].properties.name }}' and all of its contents. Press <Enter> to proceed..."




    - name: Delete the datacenter '{{ datacenter_name }}' and everything contained therein
      ionoscloudsdk.ionoscloud.datacenter:
        datacenter: "{{ datacenter_name }}"
        state: absent


    - name: Delete the IP Block corresponding to this example
      ionoscloudsdk.ionoscloud.ipblock:
        ipblock: "IP Block for {{ datacenter_name }}"
        state: absent


    - name: And finally delete any 'temporary' or run-time files
      ansible.builtin.file:
        path: "{{ item }}"
        state: absent
      with_items:
        - ssh_config
        - ssh_known_hosts_tmp
        - temporary_id_rsa
        - temporary_id_rsa.pub
        - inventory.yml
        - cloud-init--app-servers.txt

```

{% endcode %}


# nginx-config.patch.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/06__introducing_the_nat_gateway_and_network_load_balancer` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```patch
diff -ruN dist/etc/nginx/nginx.conf patched/etc/nginx/nginx.conf
--- dist/etc/nginx/nginx.conf	2023-03-14 16:19:32.000000000 +0100
+++ patched/etc/nginx/nginx.conf	2024-01-03 09:30:58.341522265 +0100
@@ -36,8 +36,14 @@
 	##
 	# Logging Settings
 	##
+        proxy_set_header X-Real-IP       $proxy_protocol_addr;
+        proxy_set_header X-Forwarded-For $proxy_protocol_addr;
 
-	access_log /var/log/nginx/access.log;
+        log_format combined_real_ip '$proxy_protocol_addr - $remote_user [$time_local] '
+                        '"$request" $status $body_bytes_sent '
+                        '"$http_referer" "$http_user_agent"';
+
+	access_log /var/log/nginx/access.log combined_real_ip;
 
 	##
 	# Gzip Settings
diff -ruN dist/etc/nginx/sites-available/default patched/etc/nginx/sites-available/default
--- dist/etc/nginx/sites-available/default	2024-01-03 09:39:08.370834184 +0100
+++ patched/etc/nginx/sites-available/default	2024-01-03 09:37:55.691237318 +0100
@@ -19,8 +19,11 @@
 # Default server configuration
 #
 server {
-	listen 80 default_server;
-	listen [::]:80 default_server;
+	listen 80 default_server proxy_protocol;
+	listen [::]:80 default_server proxy_protocol;
+
+	set_real_ip_from 192.168.8.0/24;
+	real_ip_header proxy_protocol;
 
 	# SSL configuration
 	#

```

{% endcode %}


# templates\_cloud-init--app-servers.j2.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/06__introducing_the_nat_gateway_and_network_load_balancer` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```j2
#!/bin/bash
dd if=/dev/zero of=/swapfile bs=1M count=2048
chmod 0600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile    none    swap    sw    0    0' >> /etc/fstab


ip route add default via {{ nat_gateway.ip }}

```

{% endcode %}


# templates\_index.html.j2.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/06__introducing_the_nat_gateway_and_network_load_balancer` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```j2
<html>
    <body>
        Hello from {{ inventory_hostname }}
    </body>
</html>
```

{% endcode %}


# templates\_inventory.j2.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/06__introducing_the_nat_gateway_and_network_load_balancer` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```

</div>
```

{% endcode %}


# templates\_ssh\_config.j2.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/06__introducing_the_nat_gateway_and_network_load_balancer` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```

</div>
```

{% endcode %}


# vars.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/06__introducing_the_nat_gateway_and_network_load_balancer` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```yml
datacenter_name: Ansible Tutorials - Introducing the NAT Gateway and NLB

ip_block:         { 'size': '2' }

lan:              { 'name': 'Internal LAN', 'address': '192.168.8.0/24',  'gw_ip': '192.168.8.1' }

nat_gateway:      { 'name': 'NAT GW', 'ip': '192.168.8.1' }

nlb:              { 'name': 'NLB', 'ip': '192.168.8.248', 'proxy_protocol': 'none' }

server_config:    { 'jumpbox': { 'name': 'jumpbox',
                                 'cube_size': 'CUBES XS',
                                 'ip': '192.168.8.8' },
                    'app_server': [ { 'name': 'app-server-1',
                                      'ram': '1024',
                                      'cores': '1',
                                      'volume_size': '5',
                                      'user_data_file': 'cloud-init--app-servers.txt',
                                      'ip': '192.168.8.16' },
                                     { 'name': 'app-server-2',
                                       'ram': '1024',
                                       'cores': '1',
                                       'volume_size': '5',
                                       'user_data_file': 'cloud-init--app-servers.txt',
                                       'ip': '192.168.8.17' } ] 
                  }

vnf_wait_timeout: 1800

ENABLE_PROXY_PROTOCOL: false

```

{% endcode %}


# Introducing the Application Load Balancer

![alt text](https://860290032-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MUORV1X4hkCRIcUbMs2-3956399747%2Fuploads%2Fgit-blob-ba12e5fb3cd0be368ea79df362d3e2cff24932bc%2Fnetwork-topology.png?alt=media)

This installment is based largely upon the last, but instead of provisioning a Network Load Balancer, we introduce the Layer-4 [Application Load Balancer](https://docs.ionos.com/cloud/managed-services/application-load-balancer/overview) (ALB), and its associated [Target Groups](https://docs.ionos.com/cloud/managed-services/application-load-balancer/how-tos/create-target-groups) and [Forwarding Rules](https://docs.ionos.com/cloud/managed-services/application-load-balancer/how-tos/setup-alb#adding-forwarding-rules) structures. (Their corresponding entries in our Ansible Module's documentation can be found [here](https://docs.ionos.com/ansible/api/application-load-balancer/application_load_balancer), [here](https://docs.ionos.com/ansible/api/application-load-balancer/target_group) and [here](https://docs.ionos.com/ansible/api/application-load-balancer/application-load-balancer-rule), respectively.)

Please note that, as both the NAT Gateway *and* the ALB require their own reserved IP address, your will need to be able to reserve at least two IP addresses (you can see how many 'reserved IP addresses' your contract is currently using and still able to reserve in the DCD under \[Profile Icon] --> Resource Overview).

> **Also note:** From [docs.ionos.com/cloud/early-access/application-load-balancer](https://docs.ionos.com/cloud/early-access/application-load-balancer/overview#docs-internal-guid-ed9f1857-7fff-b61e-c4da-43e1453073cc):
>
> The ALB is *not* configured to support Source NAT (SNAT). Therefore, targets cannot initiate network connections through the load balancer.
>
> Each Application Load Balancer must have at least one Listener and supports up to 10 Listeners.

## What's in this Example?

This example consists of the following files:

| File                                 | Description                                                                                                                                                                                                                                |
| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `01__create_jumpbox_and_nat_gw.yml`  | This playbook reserves an IP address block and creates a Cubes-based jumpbox and NAT Gateway (as per Example 6)                                                                                                                            |
| `02__create_app_servers_and_alb.yml` | After retrieving the necessary information via the Cloud API, this playbook provisions one or more 'application servers' and an ALB, along with a rule that will forward incoming `http` requests to said servers in a round-robin fashion |
| `03__configure_app_servers.yml`      | This playbook runs on the app servers themselves to (amongst other things) install the NGINX web server and custom, host-specific `index.html` files (which, in turn, show which server you've reached)                                    |
| `04__clean_up.yml`                   | This playbook cleans up all of the resources provisioned in the previous parts, and should be run once you're done with the earlier parts                                                                                                  |
| `vars.yml`                           | This file contains the variable definitions common to all of this example's individual playbooks                                                                                                                                           |
| `../vars.yml`                        | This file is common to all of our Ansible examples and contains a set of more generally-used variable definitions                                                                                                                          |

## Usage

> **Note:** As with all other 'executable' examples in this repository, an 'End User Licence Agreement'-like statement will be displayed, which must also be accepted before the tasks proper can be executed.
>
> Please note that, while potentially quite minimal, you will incur charges for the resources based upon how long you keep them provisioned; for more information on the actual costs, you can follow the links displayed in the 'EULA' text. Also note that, if you run the following through to completion, the playbook should 'clean up' after itself, but we recommend you verify this, e.g., via the DCD or `ionosctl` to make sure you won't be charged for any unwanted resources.

1. To provision the jumpbox and NAT Gateway, run the following command:

   ```
   ansible-playbook 01__create_jumpbox_and_nat_gw.yml
   ```
2. To provision the application servers and the ALB, run the following command:

   ```
   ansible-playbook 02__create_app_servers_and_alb.yml
   ```
3. To *configure* the application servers that were provisioned in Step 2, run:

   ```
   ansible-playbook -i inventory.yml 03__configure_app_servers.yml
   ```
4. Optionally, examine the resources that were provisioned in Steps 1 and 2
5. Execute the following to delete the resources provisioned in the previous steps:

   ```
   ansible-playbook 04__clean_up.yml
   ```

Between Steps 3 and 5, you can also run the following commands to access the various resources, directly and via the load balancer:

| Command                            | Description                                                                                                                                                                                                                                       |
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ssh -F ssh_config ${TARGET_HOST}` | ssh into the specified server, where `${TARGET_HOST}` is one of `jumpbox`, `app-server-1` or `app-server-2`                                                                                                                                       |
| `curl http://${ALB_ADDRESS}`       | retrieve the `index.html` file from one of the app servers via the load balancer, where `${ALB_ADDRESS}` is the public IP address assigned to the ALB (visible either, e.g., via `ionosctl ipblock list` or the DCD, or in the `ssh_config` file) |

### Troubleshooting tips

* If you get a `name 'certificate_manager_sdk_version' is not defined` error message when working with the Application Load Balancer, make sure you have the appropriate module installed (this can be done by running the command `pip install ionoscloud-cert-manager`)
* Due to the way in which browsers tend to keep their TCP connections open for a period of time, you might need to wait for these connections to time out *before* reloading this URL (otherwise the ALB will connect you with the same internal server)...

## Summary

In this tutorial, we saw examples of:

1. how the `ionoscloudsdk.ionoscloud.application_load_balancer`, `target_group` and `application_load_balancer_forwardingrule` modules can be used to provision and configure an ALB; and
2. how we can verify that the ALB is forwarding incoming connections as expected (and how its behaviour differs from the *NLB*)


# 01\_\_create\_jumpbox\_and\_nat\_gw\.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/07__introducing_the_application_load_balancer` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```yml
---
- hosts: localhost
  connection: local
  gather_facts: false

  vars_files:
    - ../vars.yml
    - vars.yml




  tasks:
    # =======================================================================
    - name: Display EULA
      ansible.builtin.pause:
        prompt: "{{ IONOS_UNSUPPORTED_EULA }}"
      register: INTERACTIVE_EULA_ACCEPTED
      when: IONOS_UNSUPPORTED_EULA_ACCEPTED != "yes"


    - name: Confirm acceptance of EULA
      ansible.builtin.assert:
        that:
          - IONOS_UNSUPPORTED_EULA_ACCEPTED == "yes" or INTERACTIVE_EULA_ACCEPTED.user_input == "yes"  




    # =======================================================================
    - name: Create the datacenter '{{ datacenter_name }}' in {{ location }}
      ionoscloudsdk.ionoscloud.datacenter:
        name: "{{ datacenter_name }}"
        location: "{{ location }}"
        state: present
      register: datacenter_response




    # =======================================================================
    # Provision the jumpbox, heavily borrowed from 03__jumpbox_with_internal_server
    - name: Retrieve Cube templates
      ionoscloudsdk.ionoscloud.cube_template_info:
        filters: "{ 'properties.name': '{{ server_config['jumpbox'].cube_size }}' }"
      register: template_list


    - name: Provision a minimal Cube Jumpbox
      ionoscloudsdk.ionoscloud.cube_server:
        datacenter: "{{ datacenter_name }}"
        name: "{{ server_config['jumpbox'].name }}"
        template_uuid: "{{ template_list.cube_templates[0].id }}"
        disk_type: DAS
        image: "{{ image_alias }}"
        image_password: "{{ default_password }}"
        ssh_keys:
          - "{{ ssh_public_key }}"
        assign_public_ip: true

        state: present
        wait: true
        wait_timeout: "{{ wait_timeout }}"
      register: create_cube_response


    - name: Create a second, internal LAN within '{{ datacenter_name }}'
      ionoscloudsdk.ionoscloud.lan:
        datacenter: "{{ datacenter_name }}"
        name: "{{ lan.name }}"
        public: false
      register: create_second_lan_response


    - name: Create a second NIC for the Jumpbox
      ionoscloudsdk.ionoscloud.nic:
        datacenter: "{{ datacenter_name }}"
        name: "{{ server_config['jumpbox'].name }}.eth1"
        server: "{{ server_config['jumpbox'].name }}"
        lan: "{{ create_second_lan_response.lan.id }}"
        ips:
          - "{{ server_config['jumpbox'].ip }}"
        dhcp: true

        state: present
        wait: true
        wait_timeout: "{{ wait_timeout }}"




    # =======================================================================
    # Reserve a block of two IP addresses (one for the NAT gateway, one for
    # the NLB). See https://docs.ionos.com/ansible/api/compute-engine/ipblock
    - name: Create an IP Block for our datacenter
      ionoscloudsdk.ionoscloud.ipblock:
        name: "IP Block for {{ datacenter_name }}"
        location: "{{ location }}"
        size: "{{ ip_block.size }}"
        state: present
      register: ip_block_response




    # =======================================================================
    # Create (and, where necessary, transfer) the required temporary files
    - name: Create a temporary ssh-key-pair so we can connect to the 'internal server' via the jumpbox
      ansible.builtin.shell:
        cmd: ssh-keygen -t rsa -b 4096 -f temporary_id_rsa -N "" || true


    - name: Create a local ssh_config file
      ansible.builtin.template:
        src: templates/ssh_config.j2
        dest: ssh_config


    - name: Create a local / 'nested' Ansible inventory.yml file
      ansible.builtin.template:
        src: templates/inventory.j2
        dest: inventory.yml


    - name: Delete any pre-existing ssh_known_hosts_tmp file
      ansible.builtin.shell: rm -f ssh_known_hosts_tmp


    - name: Copy temporary ssh private key to the jumpbox
      ansible.builtin.shell: scp -F ssh_config temporary_id_rsa jumpbox:/root/.ssh/id_rsa




    # =======================================================================
    # Create the NAT Gateway --- see https://docs.ionos.com/ansible/api/nat-gateway/nat_gateway
    - name: Create a NAT Gateway --- this can take a little while (typically between 3 and 8 minutes), so please don't interrupt this operation...
      ionoscloudsdk.ionoscloud.nat_gateway:
        datacenter: "{{ datacenter_name }}"
        name: "{{ nat_gateway.name }}"
        public_ips: 
          - "{{ ip_block_response.ipblock.properties.ips[0] }}"
        lans:
          - id: "{{ create_second_lan_response.lan.id }}"
            gateway_ips: "{{ nat_gateway.ip }}"

        wait: true
        wait_timeout: "{{ vnf_wait_timeout }}"
      register: nat_gateway_response


    # See https://docs.ionos.com/ansible/api/nat-gateway/nat_gateway_rule
    - name: Create an SNAT gateway rule
      ionoscloudsdk.ionoscloud.nat_gateway_rule:
        datacenter: "{{ datacenter_name }}"
        nat_gateway: "{{ nat_gateway_response.nat_gateway.id }}"
        name: "SNAT Default Rule"
        type: "SNAT"
        protocol: "ALL"
        source_subnet: "{{ lan.address }}"
        public_ip: "{{ ip_block_response.ipblock.properties.ips[0] }}"

        wait: true
        wait_timeout: "{{ vnf_wait_timeout }}"

```

{% endcode %}


# 02\_\_create\_app\_servers\_and\_alb.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/07__introducing_the_application_load_balancer` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```yml
---
- hosts: localhost
  connection: local
  gather_facts: false

  vars_files:
    - ../vars.yml
    - vars.yml

  


  tasks:
    # =======================================================================
    - name: Get information about the datacenter '{{ datacenter_name }}'
      ionoscloudsdk.ionoscloud.datacenter_info:
        filters: { 'properties.name': '{{ datacenter_name }}' }
      register: datacenter_info_response


    - name: Get information about the LANs in '{{ datacenter_name }}'
      ionoscloudsdk.ionoscloud.lan_info:
        datacenter: "{{ datacenter_name }}"
      register: lan_info_response


    - name: Set the fact 'public_lan' based on the above
      ansible.builtin.set_fact:
        public_lan: "{{ (lan_info_response | json_query(query))[0] }}"
      vars:
        query: "lans[?properties.name=='public']"


    - name: Set the fact 'secondary_lan' based on the above
      ansible.builtin.set_fact:
        secondary_lan: "{{ (lan_info_response | json_query(query))[0] }}"
      vars:
        query: "lans[?properties.name=='{{ lan.name }}']"




    # =======================================================================
    # Create the 'app servers' defined in 'server_config.app_server'
    - name: Create the cloud-init file for our app servers
      ansible.builtin.template:
        src: templates/cloud-init--app-servers.j2
        dest: cloud-init--app-servers.txt


    - name: Create the app servers specified in server_config.app_server
      ionoscloudsdk.ionoscloud.server:
        datacenter: "{{ datacenter_name }}"
        name: "{{ item.name }}"
        cores: "{{ item.cores }}"
        ram: "{{ item.ram }}"
        cpu_family: "{{ datacenter_info_response.datacenters[0].properties.cpu_architecture[0].cpu_family }}"
        disk_type: HDD
        volume_size: "5"
        image: "{{ image_alias }}"
        image_password: "{{ default_password }}"
        ssh_keys:
          - "{{ ssh_public_key }}"
          - "{{ lookup('file', 'temporary_id_rsa.pub') }}"
        lan: "{{ secondary_lan.id }}"
        nic_ips:
          - "{{ item.ip }}"
        user_data: "{{ lookup('file', item.user_data_file) | string | b64encode }}"

        state: present
        wait: true
        wait_timeout: "{{ wait_timeout }}"
      with_items: "{{ server_config.app_server }}"
      register: create_app_server_response




    # =======================================================================
    # And finally create and minimally-configure an Application Load Balancer
    - name: Get information about our reserved IP Blocks
      ionoscloudsdk.ionoscloud.ipblock_info:
        filters: "{ 'properties.name': 'IP Block for {{ datacenter_name }}' }"
      register: ipblock_info_response


    - name: Set 'ip_block' based on the above
      ansible.builtin.set_fact:
        ip_block: "{{ ipblock_info_response.ipblocks[0].properties.ips }}"




    # Before we can create a forwarding rule, we need the list of destination IPs
    - name: Set 'target_ips' based on 'create_app_server_response'
      ansible.builtin.set_fact:
        target_ips: "{{ create_app_server_response | json_query(query) }}"
      vars:
        query: "results[].machines[].entities.nics.items[].properties.ips"


    # we need two separate set_fact calls to guarantee targets is initialised
    # as an empty list before it is used in the second call...
    - name: Create targets list
      ansible.builtin.set_fact:
        targets: []

    - name: Add new JSON Objects to 'targets'
      ansible.builtin.set_fact:
        targets: "{{ targets + 
                     [{ 'ip': item[0],
                        'port': '80',
                        'weight': '100',
                        'health_check_enabled': 'false',
                        'maintenance_enabled': 'false' }] }}"
      loop: "{{ target_ips }}"


    - name: Print target objects
      ansible.builtin.debug:
        var: targets
      when: verbose_debugging




    # see https://docs.ionos.com/ansible/api/application-load-balancer/target_group
    - name: Create Target Group
      ionoscloudsdk.ionoscloud.target_group:
        name: "ALB HTTP target group"
        algorithm: "ROUND_ROBIN"
        protocol: "HTTP"
        targets: "{{ targets }}"
        # health_check:
        #   check_timeout: 2000
        #   check_interval: 1000
        #   retries: 3
        # http_health_check:
        #   path: "./"
        #   method: "GET"
        #   match_type: "STATUS_CODE"
        #   response: 200
        #   regex: false
        #   negate: false
        wait: true
      register: target_group_response




    # see https://docs.ionos.com/ansible/api/application-load-balancer
    - name: Create the Application Load Balancer --- sometimes, this can take a while (up to 15 or so minutes), so please don't interrupt this operation...
      ionoscloudsdk.ionoscloud.application_load_balancer:
        datacenter: "{{ datacenter_name }}"
        name: "{{ alb.name }}"
        listener_lan: "{{ public_lan.id }}"
        ips:
          - "{{ ip_block[1] }}"
        target_lan: "{{ secondary_lan.id }}"
        lb_private_ips:
          - "{{ alb.ip }}"

        state: present
        wait: true
        wait_timeout: "{{ vnf_wait_timeout }}"
      register: create_alb_response


    - name: Print create_alb_response
      ansible.builtin.debug:
        var: create_alb_response
      when: verbose_debugging




    # see https://docs.ionos.com/ansible/api/application-load-balancer/application-load-balancer-rule
    - name: Create Application Load Balancer Forwarding Rule for tcp/http
      ionoscloudsdk.ionoscloud.application_load_balancer_forwardingrule:
        name: "ALB HTTP connections"
        algorithm: "ROUND_ROBIN"
        protocol: "HTTP"
        listener_ip: "{{ ip_block[1] }}"
        listener_port: "80"
        http_rules:
          - name: "HTTP Rule"
            type: "FORWARD"
            target_group: "{{ target_group_response.target_group.id }}"

        datacenter: "{{ datacenter_name }}"
        application_load_balancer: "{{ create_alb_response.application_load_balancer.id }}"

        wait: true
        wait_timeout: "{{ vnf_wait_timeout }}"
      register: alb_forwardingrule_response


    - name: Print the newly-provisioned Load Balancer's public IP address
      ansible.builtin.debug:
        msg:
          - "The ALB's IP address is {{ ip_block[1] }}. To see its forwarding rule in action, run the"
          - "command `curl http://{{ ip_block[1] }}` two or more times _after_ you have configured"
          - "the app-servers via `ansible-playbook -i inventory.yml 03__configure_app_servers.yml"

```

{% endcode %}


# 03\_\_configure\_app\_servers.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/07__introducing_the_application_load_balancer` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```
# Arguably not the most robust solution, but while an approach based upon,
# say, https://stackoverflow.com/a/67379573 would guarantee the resulting
# file is always valid, assuming the level of indention doesn't change,
# the following is simpler, and doesn't remove any comments that said file
# might contain
- name: Add our default route to /etc/netplan/50-cloud-init.yaml to make it persistent
  blockinfile:
    path: /etc/netplan/50-cloud-init.yaml
    insertbefore: "match:"
    block: |
      {% filter indent(width=12, first=true) %}
      routes:
        - to: default
          via: 192.168.8.1
      {% endfilter %}


- name: Ensure 'DNS=212.227.123.16 212.227.123.17' is in the '[Resolve]' section of /etc/systemd/resolved.conf
  community.general.ini_file:
    path: /etc/systemd/resolved.conf
    section: Resolve
    option: DNS
    value: 212.227.123.16 212.227.123.17
    state: present


- name: Restart the systemd-resolved service
  ansible.builtin.service:
    name: systemd-resolved
    state: restarted




- name: Update repositories cache and upgrade the system
  ansible.builtin.apt:
    upgrade: dist
    update_cache: yes
    cache_valid_time: 3600


- name: Install nginx
  ansible.builtin.package:
    name:
      - nginx
    state: present


- name: And create our per-host index.html files on the remote servers
  ansible.builtin.template:
    src: templates/index.html.j2
    dest: /var/www/html/index.html
```

{% endcode %}


# 04\_\_clean\_up.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/07__introducing_the_application_load_balancer` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```yml
---
- hosts: localhost
  connection: local
  gather_facts: false

  vars_files:
    - ../vars.yml
    - vars.yml

  


  tasks:
    # =======================================================================
    - name: Get information about the datacenter '{{ datacenter_name }}'
      ionoscloudsdk.ionoscloud.datacenter_info:
        filters: { 'properties.name': '{{ datacenter_name }}' }
      register: datacenter_info_response


    - name: Wait for user confirmation
      ansible.builtin.pause:
        prompt: "About to delete '{{ datacenter_info_response.datacenters[0].properties.name }}' and all of its contents. Press <Enter> to proceed..."




    - name: Delete the datacenter '{{ datacenter_name }}' and everything contained therein
      ionoscloudsdk.ionoscloud.datacenter:
        datacenter: "{{ datacenter_name }}"
        state: absent


    - name: Delete the IP Block corresponding to this example
      ionoscloudsdk.ionoscloud.ipblock:
        ipblock: "IP Block for {{ datacenter_name }}"
        state: absent


    - name: And finally delete any 'temporary' or run-time files
      ansible.builtin.file:
        path: "{{ item }}"
        state: absent
      with_items:
        - ssh_config
        - ssh_known_hosts_tmp
        - temporary_id_rsa
        - temporary_id_rsa.pub
        - inventory.yml
        - cloud-init--app-servers.txt

```

{% endcode %}


# templates\_cloud-init--app-servers.j2.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/07__introducing_the_application_load_balancer` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```j2
#!/bin/bash
dd if=/dev/zero of=/swapfile bs=1M count=2048
chmod 0600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile    none    swap    sw    0    0' >> /etc/fstab


ip route add default via {{ nat_gateway.ip }}

```

{% endcode %}


# templates\_index.html.j2.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/07__introducing_the_application_load_balancer` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```j2
<html>
    <body>
        Hello from {{ inventory_hostname }}
    </body>
</html>
```

{% endcode %}


# templates\_inventory.j2.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/07__introducing_the_application_load_balancer` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```

</div>
```

{% endcode %}


# templates\_ssh\_config.j2.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/07__introducing_the_application_load_balancer` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```

</div>
```

{% endcode %}


# vars.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/07__introducing_the_application_load_balancer` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```yml
datacenter_name: Ansible Tutorials - Introducing the ALB

ip_block:         { 'size': '2' }

lan:              { 'name': 'Internal LAN', 'address': '192.168.8.0/24',  'gw_ip': '192.168.8.1' }

nat_gateway:      { 'name': 'NAT GW', 'ip': '192.168.8.1' }

alb:              { 'name': 'ALB', 'ip': '192.168.8.248' }

server_config:    { 'jumpbox': { 'name': 'jumpbox',
                                 'cube_size': 'CUBES XS',
                                 'ip': '192.168.8.8' },
                    'app_server': [ { 'name': 'app-server-1',
                                      'ram': '1024',
                                      'cores': '1',
                                      'volume_size': '5',
                                      'user_data_file': 'cloud-init--app-servers.txt',
                                      'ip': '192.168.8.16' },
                                     { 'name': 'app-server-2',
                                       'ram': '1024',
                                       'cores': '1',
                                       'volume_size': '5',
                                       'user_data_file': 'cloud-init--app-servers.txt',
                                       'ip': '192.168.8.17' } ] 
                  }

vnf_wait_timeout: 1800

ENABLE_PROXY_PROTOCOL: false

```

{% endcode %}


# A quick introduction to DBaaS

![alt text](https://860290032-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MUORV1X4hkCRIcUbMs2-3956399747%2Fuploads%2Fgit-blob-0e4efd259b3a6ac731e9223248aca76df586629c%2Fnetwork-topology.png?alt=media)

In this, one of our last examples, we introduce two Managed Database / DBaaS products: [PostgreSQL](https://docs.ionos.com/cloud/managed-services/database-as-a-service/postgresql) and [MongoDB](https://docs.ionos.com/cloud/managed-services/database-as-a-service/mongodb) (their corresponding entries in our Ansible Module's documentation can be found [here](https://docs.ionos.com/ansible/api/dbaas-postgres/postgres_cluster) and [here](https://docs.ionos.com/ansible/api/dbaas-mongo/mongo_cluster), respectively).

In addition to creating one or both of the aforementioned DBaaS clusters, we will also create an SSH jumpbox that can be used to access the database clusters from 'the Internet'; given that, for security reasons, our DBaaS products are configured, out of the box, to only allow connections from private LANs within the virtual data center specified at their time of creation, this technique may come in handy for remote development and/or database administration tasks. (This example also comes with a minimal set of PostgreSQL and MongoDB client tools which can be used to connect *directly* to the newly-provisioned database clusters.)

> **Note:** While there are several good reasons why one really *shouldn't* expose a database cluster to the Internet directly, if you *really* want to, you can set the variable `ENABLE_EXPLICITLY_UNSUPPORTED_CONFIGURATIONS` in `vars.yml` to true before running the playbooks in this example... This will then create a Network Load Balancer (NLB), together with the rules required to forward PostgreSQL and MongoDB client connections through to their respective clusters.
>
> **Also note:** unlike the cases where access is mediated via SSH port-forwarding or an actual router- / firewall-appliance, it is *not* possible to restrict access to these ports to specific IP addresses or subnets when using an NLB — i.e. if you enable this feature, you will literally be exposing your database cluster(s) to anyone who happens to discover them during a port scan.

## What's in this example?

This example consists of the following files:

| File                               | Description                                                                                                                                                                                                                                      |
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `01__create_jumpbox_and_nlb.yml`   | This playbook provisions a Cube-based jumpbox, before installing PostgreSQL and MongoDB clients on it. (If `ENABLE_EXPLICITLY_UNSUPPORTED_CONFIGURATIONS==true`, it will also create and configure a Network Load balancer, as described above.) |
| `02a__create_postgres_cluster.yml` | This playbook creates a PostgreSQL cluster; the `dbadmin` user's default password is the same as the one defined in `../vars.yml`                                                                                                                |
| `02b__create_mongodb_cluster.yml`  | This playbook creates a MongoDB cluster; the `dbadmin` user's default password is the same as the one defined in `../vars.yml`                                                                                                                   |
| `03__clean_up.yml`                 | This playbook deletes any DBaaS clusters that were provisioned by the previous playbooks, and then removes the remaining resources, including the IP address block that was reserved in Part 1                                                   |
| `vars.yml`                         | This file contains the variable definitions common to all of this example's individual playbooks                                                                                                                                                 |
| `../vars.yml`                      | This file is common to all of our Ansible examples and contains a set of more generally-used variable definitions                                                                                                                                |

More concretely, this example introduces the following IONOS CLOUD modules:

1. `ionoscloudsdk.ionoscloud.postgres_cluster`
2. `ionoscloudsdk.ionoscloud.mongo_cluster` and `mongo_cluster_user`

It also shows how a host can be added dynamically to the inventory (search for `ansible.builtin.add_host` in `01__create_jumpbox_and_nlb.yml`) — an alternative to generating an `inventory.yml` file and applying it to a separate / standalone playbook.

## Usage

> **Note:** As with all other 'executable' examples in this repository, an 'End User Licence Agreement'-like statement will be displayed, which must also be accepted before the tasks proper can be executed.
>
> Please note that, while potentially quite minimal, you will incur charges for the resources based upon how long you keep them provisioned; for more information on the actual costs, you can follow the links displayed in the 'EULA' text. Also note that, if you run the following through to completion, the playbook should 'clean up' after itself, but we recommend you verify this, e.g., via the DCD or `ionosctl` to make sure you won't be charged for any unwanted resources.

1. To provision the jumpbox and the NLB, run the following command:

   ```
   ansible-playbook 01__create_jumpbox_and_nlb.yml
   ```
2. To provision one or both DBaaS clusters, run one or both of the following commands:

   ```
   ansible-playbook 02a__create_postgres_cluster.yml
   ansible-playbook 02b__create_mongodb_cluster.yml
   ```

   Note that these playbooks can be provisioned independently of each other, and that after each of them are run, they will also give you specific examples of how to connect to your newly-provisioned database clusters (see below).
3. Execute the following to delete the resources provisioned in the previous steps:

   ```
   ansible-playbook 03__clean_up.yml
   ```

Between Steps 2 and 3, you can also run the commands output at the end of the 'create cluster' playbooks to connect to your newly-provisioned database cluster. E.g. after running `ansible-playbook 02a__create_postgres_cluster.yml` with `ENABLE_EXPLICITLY_UNSUPPORTED_CONFIGURATIONS` set to `true`, you will see something of the form:

```
TASK [Print usage information] *******************************************************************************************************************************
ok: [localhost] => {
    "msg": [
        "To access your Postgres Cluster via, e.g., psql, use one of the following commands:",
        "    From the jumpbox:",
        "        psql -h 192.168.8.16 -U dbadmin postgres",
        "    Externally via the jumpbox:",
        "        In one shell:     ssh -L 5432:pg-pi567l15bgolgtkt.postgresql.de-txl.ionos.com:5432 root@W.X.Y.Z_0",
        "        In another shell: psql -h localhost -U dbadmin postgres",
        "    Externally via the NLB:",
        "        psql -h W.X.Y.Z_1 -U dbadmin postgres"
    ]
}
```

## Summary

In this tutorial, we saw examples of:

1. how the `ionoscloudsdk.ionoscloud.postgres_cluster`, `ionoscloudsdk.ionoscloud.mongo_cluster` and `mongo_cluster_user` modules can be used to provision Postgres and MongoDB database clusters;
2. how hosts can be added dynamically to the inventory, as an alternative to generating an `inventory.yml` file and using it with a separate / standalone playbook; and
3. how we can connect to said database clusters, both via a common, private LAN; via a jumpbox using an SSH key-pair; and optionally, via an open form of port-forwarding.


# 01\_\_create\_jumpbox\_and\_nlb.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/09__a_quick_introduction_to_dbaas` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```yml
---
- hosts: localhost
  connection: local
  gather_facts: false

  vars_files:
    - ../vars.yml
    - vars.yml




  tasks:
    # =======================================================================
    - name: Display EULA
      ansible.builtin.pause:
        prompt: "{{ IONOS_UNSUPPORTED_EULA }}"
      register: INTERACTIVE_EULA_ACCEPTED
      when: IONOS_UNSUPPORTED_EULA_ACCEPTED != "yes"


    - name: Confirm acceptance of EULA
      ansible.builtin.assert:
        that:
          - IONOS_UNSUPPORTED_EULA_ACCEPTED == "yes" or INTERACTIVE_EULA_ACCEPTED.user_input == "yes"  




    # =======================================================================
    - name: Create the datacenter '{{ datacenter_name }}' in {{ location }}
      ionoscloudsdk.ionoscloud.datacenter:
        name: "{{ datacenter_name }}"
        location: "{{ location }}"
        state: present
      register: datacenter_response




    # =======================================================================
    # Provision the jumpbox, heavily borrowed from 3__jumpbox_with_internal_server
    - name: Retrieve Cube templates
      ionoscloudsdk.ionoscloud.cube_template_info:
        filters: "{ 'properties.name': '{{ server_config['jumpbox'].cube_size }}' }"
      register: template_list


    - name: Provision a minimal Cube Jumpbox
      ionoscloudsdk.ionoscloud.cube_server:
        datacenter: "{{ datacenter_name }}"
        name: "{{ server_config['jumpbox'].name }}"
        template_uuid: "{{ template_list.cube_templates[0].id }}"
        disk_type: DAS
        image: "{{ image_alias }}"
        image_password: "{{ default_password }}"
        ssh_keys:
          - "{{ ssh_public_key }}"
        assign_public_ip: true

        state: present
        wait: true
        wait_timeout: "{{ wait_timeout }}"
      register: create_cube_response


    - name: Create a second, internal LAN within '{{ datacenter_name }}'
      ionoscloudsdk.ionoscloud.lan:
        datacenter: "{{ datacenter_name }}"
        name: "{{ lan.name }}"
        public: false
      register: create_second_lan_response


    - name: Create a second NIC for the Jumpbox
      ionoscloudsdk.ionoscloud.nic:
        datacenter: "{{ datacenter_name }}"
        name: "{{ server_config['jumpbox'].name }}.eth1"
        server: "{{ server_config['jumpbox'].name }}"
        lan: "{{ create_second_lan_response.lan.id }}"
        ips:
          - "{{ server_config['jumpbox'].ip }}"
        dhcp: true

        state: present
        wait: true
        wait_timeout: "{{ wait_timeout }}"




    # =======================================================================
    # Create (and, where necessary, transfer) the required temporary files
    - name: Create a temporary ssh-key-pair so we can connect to the 'internal server' via the jumpbox
      ansible.builtin.shell:
        cmd: ssh-keygen -t rsa -b 4096 -f temporary_id_rsa -N "" || true


    - name: Create a local ssh_config file
      ansible.builtin.template:
        src: templates/ssh_config.j2
        dest: ssh_config


    - name: Delete any pre-existing ssh_known_hosts_tmp file
      ansible.builtin.shell: rm -f ssh_known_hosts_tmp


    - name: Copy temporary ssh private key to the jumpbox
      ansible.builtin.shell: scp -F ssh_config temporary_id_rsa jumpbox:/root/.ssh/id_rsa
      when: false


    - name: Add an Ansible host entry for the jumpbox
      ansible.builtin.add_host:
        hostname: "jumpbox"
        ansible_host: "{{ create_cube_response['machines'][0]['entities']['nics']['items'][0]['properties']['ips'][0] }}"
        remote_user: root
        group: vms-to-be-configured




    # =======================================================================
    # Reserve a one-IP-address block for the NLB
    - name: Create an IP Block for our datacenter
      ionoscloudsdk.ionoscloud.ipblock:
        name: "IP Block for {{ datacenter_name }}"
        location: "{{ location }}"
        size: "{{ ip_block.size }}"
        state: present
      register: ip_block_response
      when: ENABLE_EXPLICITLY_UNSUPPORTED_CONFIGURATIONS




    # =======================================================================
    # see https://docs.ionos.com/ansible/api/network-load-balancer/network_load_balancer
    - name: Create Network Load Balancer --- sometimes, this can take a while (up to 15 or so minutes), so please don't interrupt this operation...
      ionoscloudsdk.ionoscloud.network_load_balancer:
        datacenter: "{{ datacenter_name }}"
        name: "{{ nlb.name }}"
        listener_lan: "{{ create_cube_response.machines[0]['entities']['nics']['items'][0]['properties']['lan'] }}"
        ips:
          - "{{ ip_block_response.ipblock.properties.ips[0] }}"
        target_lan: "{{ create_second_lan_response.lan.id }}"
        lb_private_ips:
          - "{{ nlb.ip }}"

        state: present
        wait: true
        wait_timeout: "{{ vnf_wait_timeout }}"
      register: create_nlb_response
      when: ENABLE_EXPLICITLY_UNSUPPORTED_CONFIGURATIONS




    # see https://docs.ionos.com/ansible/api/network-load-balancer/network_load_balancer_rule
    - name: Create Network Load Balancer Forwarding Rule for psql
      ionoscloudsdk.ionoscloud.network_load_balancer_rule:
        name: "NLB PSQL connections"
        algorithm: "ROUND_ROBIN"
        protocol: "TCP"
        listener_ip: "{{ ip_block_response.ipblock.properties.ips[0] }}"
        listener_port: "5432"
        targets:
          - ip: "{{ dbaas_config.postgres_cluster.ip }}"
            port: "5432"
            weight: "100"
        datacenter: "{{ datacenter_name }}"
        network_load_balancer: "{{ create_nlb_response.network_load_balancer.id }}"

        wait: true
        wait_timeout: "{{ vnf_wait_timeout }}"
      register: nlb_forwarding_rule_response_psql
      when: ENABLE_EXPLICITLY_UNSUPPORTED_CONFIGURATIONS


    - name: Create Network Load Balancer Forwarding Rule for mongo
      ionoscloudsdk.ionoscloud.network_load_balancer_rule:
        name: "NLB MONGO connections"
        algorithm: "ROUND_ROBIN"
        protocol: "TCP"
        listener_ip: "{{ ip_block_response.ipblock.properties.ips[0] }}"
        listener_port: "27017"
        targets:
          - ip: "{{ dbaas_config.mongodb_cluster.ip }}"
            port: "27017"
            weight: "100"
        datacenter: "{{ datacenter_name }}"
        network_load_balancer: "{{ create_nlb_response.network_load_balancer.id }}"

        wait: true
        wait_timeout: "{{ vnf_wait_timeout }}"
      register: nlb_forwarding_rule_response_mongo
      when: ENABLE_EXPLICITLY_UNSUPPORTED_CONFIGURATIONS






# =======================================================================
# And in our second play, go ahead and configure the jumpbox (which was
# added, dynamically, to our inventory above using the add_host module)
- hosts: vms-to-be-configured
  gather_facts: false


  tasks:
    - name: Set ansible_ssh_common_args
      set_fact:
        ansible_ssh_common_args: "-F ssh_config"


    - name: Update repositories cache and upgrade the system
      ansible.builtin.apt:
        upgrade: dist
        update_cache: yes
        cache_valid_time: 3600


    - name: Install required packages
      ansible.builtin.package:
        name:
          - gnupg
          - postgresql-client-common
          - postgresql-client
        state: present


    - name: Add the MongoDB 6.0 signing key
      ansible.builtin.apt_key:
        url: https://www.mongodb.org/static/pgp/server-6.0.asc
        state: present


    - name: Add the MongoDB 6.0 Linux repository
      ansible.builtin.apt_repository:
        repo: deb [arch=amd64] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/6.0 multiverse
        filename: mongodb-org-6.0
        state: present


    - name: Install MongoSH
      ansible.builtin.apt:
        name:
          - mongodb-mongosh
        update_cache: yes
        state: present

```

{% endcode %}


# 02a\_\_create\_postgres\_cluster.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/09__a_quick_introduction_to_dbaas` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```
- name: Set the fact 'internal_lan' based on the above
  ansible.builtin.set_fact:
    internal_lan: "{{ (lan_info_response | json_query(query))[0] }}"
  vars:
    query: "lans[?properties.name=='{{ lan.name }}']"


- name: Get information about our reserved IP Blocks
  ionoscloudsdk.ionoscloud.ipblock_info:
    filters: "{ 'properties.name': 'IP Block for {{ datacenter_name }}' }"
  register: ipblock_info_response
  when: ENABLE_EXPLICITLY_UNSUPPORTED_CONFIGURATIONS


- name: Set 'ip_block' based on the above
  ansible.builtin.set_fact:
    ip_block: "{{ ipblock_info_response.ipblocks[0].properties.ips }}"
  when: ENABLE_EXPLICITLY_UNSUPPORTED_CONFIGURATIONS


- name: Get information about the servers in our data center
  ionoscloudsdk.ionoscloud.server_info:
    datacenter: "{{ datacenter_name }}"
    depth: 5
  register: get_server_response


- name: Retrieve the object describing the jumpbox
  ansible.builtin.set_fact:
    desired_server_info__query: "{{ get_server_response | json_query(query) }}"
  vars:
    query: "servers[?properties.name=='{{ server_config['jumpbox'].name }}']"


- name: Retrieve the jumpbox's public IP
  ansible.builtin.set_fact:
    jumpbox_ip: "{{ (desired_server_info__query[0] | json_query(query))[0] }}"
  vars:
    query: "entities.nics.items[?properties.name!='{{ server_config['jumpbox'].name }}.eth1'].properties.ips[]"




# =======================================================================
# See https://docs.ionos.com/ansible/api/dbaas-postgres/postgres_cluster
- name: Create Postgres Cluster
  ionoscloudsdk.ionoscloud.postgres_cluster:
    postgres_version: 12
    instances: 1
    cores: "{{ dbaas_config.postgres_cluster.cores }}"
    ram: "{{ dbaas_config.postgres_cluster.ram }}"
    storage_size: "{{ dbaas_config.postgres_cluster.volume_size }}"
    storage_type: "{{ dbaas_config.postgres_cluster.storage_type }}"
    location: "{{ location }}"
    connections:
      - cidr: "{{ dbaas_config.postgres_cluster.ip }}/24"
        datacenter: "{{ datacenter_name }}"
        lan: "{{ internal_lan.id }}"
    display_name: "Postgres Cluster for {{ datacenter_name }}"
    synchronization_mode: ASYNCHRONOUS
    db_username: dbadmin
    db_password: "{{ default_password }}"

    wait: true
    wait_timeout: "{{ wait_timeout }}"
  register: postgres_cluster_response    




# =======================================================================
- name: Print usage information
  ansible.builtin.debug:
    msg:
      - "To access your Postgres Cluster via, e.g., psql, use one of the following commands:"
      - "    From the jumpbox:"
      - "        psql -h {{ dbaas_config.postgres_cluster.ip }} -U dbadmin postgres"
      - "    Externally via the jumpbox:"
      - "        In one shell:     ssh -L 5432:{{ postgres_cluster_response.postgres_cluster.properties.dns_name }}:5432 root@{{ jumpbox_ip }}"
      - "        In another shell: psql -h localhost -U dbadmin postgres"
      - "{% if ENABLE_EXPLICITLY_UNSUPPORTED_CONFIGURATIONS %}    Externally via the NLB:{% endif %}"
      - "{% if ENABLE_EXPLICITLY_UNSUPPORTED_CONFIGURATIONS %}        psql -h {{ ip_block[0] }} -U dbadmin postgres{% endif %}"
```

{% endcode %}


# 02b\_\_create\_mongodb\_cluster.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/09__a_quick_introduction_to_dbaas` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```
- name: Set the fact 'internal_lan' based on the above
  ansible.builtin.set_fact:
    internal_lan: "{{ (lan_info_response | json_query(query))[0] }}"
  vars:
    query: "lans[?properties.name=='{{ lan.name }}']"


- name: Get information about our reserved IP Blocks
  ionoscloudsdk.ionoscloud.ipblock_info:
    filters: "{ 'properties.name': 'IP Block for {{ datacenter_name }}' }"
  register: ipblock_info_response
  when: ENABLE_EXPLICITLY_UNSUPPORTED_CONFIGURATIONS


- name: Set 'ip_block' based on the above
  ansible.builtin.set_fact:
    ip_block: "{{ ipblock_info_response.ipblocks[0].properties.ips }}"
  when: ENABLE_EXPLICITLY_UNSUPPORTED_CONFIGURATIONS


- name: Get information about the servers in our data center
  ionoscloudsdk.ionoscloud.server_info:
    datacenter: "{{ datacenter_name }}"
    depth: 5
  register: get_server_response


- name: Retrieve the object describing the jumpbox
  ansible.builtin.set_fact:
    desired_server_info__query: "{{ get_server_response | json_query(query) }}"
  vars:
    query: "servers[?properties.name=='{{ server_config['jumpbox'].name }}']"


- name: Retrieve the jumpbox's public IP
  ansible.builtin.set_fact:
    jumpbox_ip: "{{ (desired_server_info__query[0] | json_query(query))[0] }}"
  vars:
    query: "entities.nics.items[?properties.name!='{{ server_config['jumpbox'].name }}.eth1'].properties.ips[]"




# =======================================================================
# See https://docs.ionos.com/ansible/api/compute-engine/cube_template
- name: Retrieve the cluster template for '{{ dbaas_config.mongodb_cluster.template }}'
  ionoscloudsdk.ionoscloud.mongo_cluster_template_info:
    filters: "{ 'properties.name': '{{ dbaas_config.mongodb_cluster.template }}' }"
  register: template_list




# =======================================================================
# See https://docs.ionos.com/ansible/api/dbaas-mongo/mongo_cluster_template_info
- name: Create MongoDB Cluster
  ionoscloudsdk.ionoscloud.mongo_cluster:
    mongo_db_version: "{{ dbaas_config.mongodb_cluster.version }}"
    instances: 1
    template_id: "{{ template_list.mongo_cluster_templates[0].id }}"
    location: "{{ location }}"
    connections:
      - cidr_list: 
          - "{{ dbaas_config.mongodb_cluster.ip }}/24"
        datacenter: "{{ datacenter_name }}"
        lan: "{{ internal_lan.id }}"
    display_name: "MongoDB Cluster for {{ datacenter_name }}"

    wait: true
    wait_timeout: "{{ wait_timeout }}"
  register: mongodb_cluster_response    


- name: Extract MongoDB Cluster hostname
  ansible.builtin.set_fact:
    cluster_hostname: "{{ mongodb_cluster_response.mongo_cluster.properties.connection_string | regex_replace('^(.*)://(.*)$', '\\2') }}"


- name: Create Cluster User
  ionoscloudsdk.ionoscloud.mongo_cluster_user:
    mongo_cluster: "{{ mongodb_cluster_response.mongo_cluster.id }}"
    mongo_username: dbadmin
    mongo_password: "{{ default_password }}"
    user_roles:
      - role: readWrite
        database: test
  register: mongo_user_response




# =======================================================================
# Note that, instead of {{ dbaas_config.mongodb_cluster.ip }} in the SSH
# command below, one _could_ try to use the hostname contained in
# {{ mongodb_cluster_response.mongo_cluster.properties.connection_string }}
# but given that this uses the mongodb+srv protocol, one would need to
# first query the corresponding SRV record, then the hostname returned
# by said query. E.g.
# $ dig +short _mongodb._tcp.m-hq5v594hxxxxxxxx.mongodb.gb-lhr.ionos.com srv
# 10 1 27017 r1.m-hq5v594hxxxxxxxx.mongodb.gb-lhr.ionos.com.
# $ dig +short r1.m-hq5v594hxxxxxxxx.mongodb.gb-lhr.ionos.com
# 192.168.8.17
- name: Print usage information
  ansible.builtin.debug:
    msg:
      - "The MongoDB cluster {{ cluster_hostname }} has been created"
      - "To access it, use one of the following commands:"
      - "    From the jumpbox:"
      - "        mongosh {{ mongodb_cluster_response.mongo_cluster.properties.connection_string }} --username dbadmin"
      - "    Externally via the jumpbox:"
      - "        In one shell:     ssh -L 27017:{{ dbaas_config.mongodb_cluster.ip }}:27017 root@{{ jumpbox_ip }}"
      - "        In another shell: mongosh 'mongodb://dbadmin@localhost?tls=true&tlsAllowInvalidHostnames=true'"
      - "{% if ENABLE_EXPLICITLY_UNSUPPORTED_CONFIGURATIONS %}    Externally via the NLB:{% endif %}"
      - "{% if ENABLE_EXPLICITLY_UNSUPPORTED_CONFIGURATIONS %}        mongosh 'mongodb://dbadmin@{{ ip_block[0] }}?tls=true&tlsAllowInvalidHostnames=true'{% endif %}"
```

{% endcode %}


# 03\_\_clean\_up.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/09__a_quick_introduction_to_dbaas` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```yml
---
- hosts: localhost
  connection: local
  gather_facts: false

  vars_files:
    - ../vars.yml
    - vars.yml

  


  tasks:
    # =======================================================================
    - name: Get information about 'Postgres Cluster for {{ datacenter_name }}'
      ionoscloudsdk.ionoscloud.postgres_cluster_info:
        filters: "{ 'properties.display_name': 'Postgres Cluster for {{ datacenter_name }}' }"
      register: postgres_clusters_response


    - name: Get information about 'MongoDB Cluster for {{ datacenter_name }}'
      ionoscloudsdk.ionoscloud.mongo_cluster_info:
        filters: "{ 'properties.display_name': 'MongoDB Cluster for {{ datacenter_name }}' }"
      register: mongo_clusters_response




    # =======================================================================
    - name: Wait for user confirmation
      ansible.builtin.pause:
        prompt: "About to delete '{{ datacenter_name }}' and all of its contents. Press <Enter> to proceed..."


    - name: Delete Postgres Cluster
      ionoscloudsdk.ionoscloud.postgres_cluster:
        postgres_cluster: "{{ postgres_clusters_response.postgres_clusters[0].id }}"
        state: absent

        wait: true
        wait_timeout: "{{ wait_timeout }}"
      when: postgres_clusters_response.postgres_clusters | length > 0


    - name: Delete MongoDB Cluster
      ionoscloudsdk.ionoscloud.mongo_cluster:
        mongo_cluster: "{{ mongo_clusters_response.mongo_clusters[0].id }}"
        state: absent

        wait: true
        wait_timeout: "{{ wait_timeout }}"
      when: mongo_clusters_response.mongo_clusters | length > 0




    - name: Pause for an additional 15 seconds
      ansible.builtin.pause:
        seconds: 15
        

    - name: Delete the datacenter '{{ datacenter_name }}' and everything contained therein
      ionoscloudsdk.ionoscloud.datacenter:
        datacenter: "{{ datacenter_name }}"
        state: absent


    - name: Delete the IP Block corresponding to this example
      ionoscloudsdk.ionoscloud.ipblock:
        name: "IP Block for {{ datacenter_name }}"
        state: absent
      when: ENABLE_EXPLICITLY_UNSUPPORTED_CONFIGURATIONS


    - name: And finally delete any 'temporary' or run-time files
      ansible.builtin.file:
        path: "{{ item }}"
        state: absent
      with_items:
        - ssh_config
        - ssh_known_hosts_tmp
        - temporary_id_rsa
        - temporary_id_rsa.pub

```

{% endcode %}


# templates\_ssh\_config.j2.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/09__a_quick_introduction_to_dbaas` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```j2
Host *
User root
StrictHostKeyChecking accept-new
UserKnownHostsFile ssh_known_hosts_tmp
IdentityFile temporary_id_rsa

Host {{ server_config['jumpbox'].name }}
Hostname {{ create_cube_response['machines'][0]['entities']['nics']['items'][0]['properties']['ips'][0] }}

```

{% endcode %}


# vars.yml.md

The source files for this tutorial can be downloaded from its [GitHub repository](https://github.com/ionos-cloud/module-ansible/tree/master/docs/), or cloned into your current working directory using the command `git clone https://github.com/ionos-cloud/module-ansible.git` before changing into the `module-ansible/docs/tutorials/09__a_quick_introduction_to_dbaas` sub-directory.

{% code title="01\_\_create\_jumpbox\_and\_nlb.yml" overflow="wrap" lineNumbers="true" %}

```yml
# If ENABLE_EXPLICITLY_UNSUPPORTED_CONFIGURATIONS is set to true, a Network
# Load Balancer (and its corresponding rules) will also be provisioned; as
# its name suggests, this is an _unsupported_ configuration (which also offers
# less security and security options than, e.g., using internal hosts and/or
# a jumpbox), but it shows you how an NLB can be used to access your DBaaS
# cluster(s) from _any_ public IP address
ENABLE_EXPLICITLY_UNSUPPORTED_CONFIGURATIONS: false


datacenter_name: Ansible Tutorials - Introducing DBaaS

ip_block:         { 'size': '1' }

lan:              { 'name': 'Internal LAN', 'address': '192.168.8.0/24',  'gw_ip': '192.168.8.1' }

nlb:              { 'name': 'NLB', 'ip': '192.168.8.248' }

server_config:    { 'jumpbox': { 'name': 'jumpbox',
                                 'cube_size': 'CUBES XS',
                                 'ip': '192.168.8.8' } }

dbaas_config:     { 'postgres_cluster': { 'ram': '2048',    # must be 2048 or greater
                                 'cores': '1',
                                 'volume_size': '10240',    # in MB, must be 2048 or greater
                                 'storage_type': 'HDD',
                                 'ip': '192.168.8.16' },
                    'mongodb_cluster':  { 'template': 'MongoDB Playground',
                                 'version': '6.0',
                                 'ip': '192.168.8.17' } }

vnf_wait_timeout: 1800

```

{% endcode %}


# Application Load Balancer


# Modules


# Flowlog

## application\_load\_balancer\_flowlog

This is a simple module that supports creating or removing Application Loadbalancer Flowlogs.

### Example Syntax

```yaml

name: Create Application Load Balancer Flowlog
ionoscloudsdk.ionoscloud.application_load_balancer_flowlog:
  name: 'AnsibleAutoTestALB'
  action: ACCEPTED
  direction: INGRESS
  bucket: sdktest
  datacenter: ''
  application_load_balancer: ''
  wait: true
  wait_timeout: 2000
register: alb_flowlog_response


name: Update Application Load Balancer Flowlog
ionoscloudsdk.ionoscloud.application_load_balancer_flowlog:
  datacenter: ''
  application_load_balancer: ''
  flowlog: ''
  name: 'AnsibleAutoTestALB'
  action: ALL
  direction: INGRESS
  bucket: sdktest
  wait: true
  state: update
register: alb_flowlog_update_response


name: Delete Application Load Balancer Flowlog
ionoscloudsdk.ionoscloud.application_load_balancer_flowlog:
  datacenter: ''
  application_load_balancer: ''
  flowlog: ''
  state: absent

```

&#x20; &#x20;

### Returned object

```json
{
    "changed": true,
    "failed": false,
    "action": "create",
    "flowlog": {
        "href": "https://api.ionos.com/cloudapi/v6/datacenters/d5b16e3b-d162-441b-9567-d9cca96fb191/applicationloadbalancers/ac62eabb-38da-4d1e-b2c6-4711ce86cfda/flowlogs/48cfe165-18f0-417c-a1ee-4ef0d22167c8",
        "id": "48cfe165-18f0-417c-a1ee-4ef0d22167c8",
        "metadata": {
            "created_by": "<USER_EMAIL>",
            "created_by_user_id": "<USER_ID>",
            "created_date": "2023-05-29T13:34:06+00:00",
            "etag": "c1ded9c35b5f413afd00360eb9daa807",
            "last_modified_by": "<USER_EMAIL>",
            "last_modified_by_user_id": "<USER_ID>",
            "last_modified_date": "2023-05-29T13:34:06+00:00",
            "state": "BUSY"
        },
        "properties": {
            "action": "ACCEPTED",
            "bucket": "sdktest",
            "direction": "INGRESS",
            "name": "AnsibleAutoTestALB"
        },
        "type": "flow-log"
    }
}

```

#### For more examples please check out the tests [here](https://github.com/ionos-cloud/module-ansible/tree/master/tests/applicationloadbalancer).

&#x20;

&#x20;

## state: **present**

```yaml
  
name: Create Application Load Balancer Flowlog
ionoscloudsdk.ionoscloud.application_load_balancer_flowlog:
  name: 'AnsibleAutoTestALB'
  action: ACCEPTED
  direction: INGRESS
  bucket: sdktest
  datacenter: ''
  application_load_balancer: ''
  wait: true
  wait_timeout: 2000
register: alb_flowlog_response

```

#### Available parameters for state **present**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>name<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The resource name.</td></tr><tr><td>action<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>Specifies the traffic action pattern.</td></tr><tr><td>direction<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>Specifies the traffic direction pattern.</td></tr><tr><td>bucket<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The bucket name of an existing IONOS CLOUD Object storage bucket.</td></tr><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of the datacenter.</td></tr><tr><td>application_load_balancer<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of the Application Loadbalancer.</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['present', 'absent', 'update']</td></tr></tbody></table>

&#x20;

&#x20;

## state: **absent**

```yaml
  
name: Delete Application Load Balancer Flowlog
ionoscloudsdk.ionoscloud.application_load_balancer_flowlog:
  datacenter: ''
  application_load_balancer: ''
  flowlog: ''
  state: absent

```

#### Available parameters for state **absent**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>name<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The resource name.</td></tr><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of the datacenter.</td></tr><tr><td>application_load_balancer<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of the Application Loadbalancer.</td></tr><tr><td>flowlog<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of the Flowlog.</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['present', 'absent', 'update']</td></tr></tbody></table>

&#x20;

&#x20;

## state: **update**

```yaml
  
name: Update Application Load Balancer Flowlog
ionoscloudsdk.ionoscloud.application_load_balancer_flowlog:
  datacenter: ''
  application_load_balancer: ''
  flowlog: ''
  name: 'AnsibleAutoTestALB'
  action: ALL
  direction: INGRESS
  bucket: sdktest
  wait: true
  state: update
register: alb_flowlog_update_response

```

#### Available parameters for state **update**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>name<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The resource name.</td></tr><tr><td>action<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Specifies the traffic action pattern.</td></tr><tr><td>direction<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Specifies the traffic direction pattern.</td></tr><tr><td>bucket<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The bucket name of an existing IONOS CLOUD Object storage bucket.</td></tr><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of the datacenter.</td></tr><tr><td>application_load_balancer<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of the Application Loadbalancer.</td></tr><tr><td>flowlog<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of the Flowlog.</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['present', 'absent', 'update']</td></tr></tbody></table>

&#x20;

&#x20;


# Application Load Balancer Forwarding Rule

## application\_load\_balancer\_forwardingrule

This is a simple module that supports creating or removing Application Loadbalancer Forwarding rules.

### Example Syntax

```yaml

name: Create Application Load Balancer Forwarding Rule
ionoscloudsdk.ionoscloud.application_load_balancer_forwardingrule:
  datacenter: ''
  application_load_balancer: ''
  name: 'AnsibleAutoTestALB'
  protocol: HTTP
  listener_ip: 10.12.118.224
  listener_port: '8081'
  http_rules:
  - name: Ansible HTTP Rule
    type: static
    response_message: <>
    content_type: application/json
    conditions:
    - type: HEADER
      condition: STARTS_WITH
      value: Friday
  wait: true
register: alb_forwarding_rule_response


name: Update Application Load Balancer Forwarding Rule
ionoscloudsdk.ionoscloud.application_load_balancer_forwardingrule:
  datacenter: ''
  application_load_balancer: ''
  forwarding_rule: ''
  name: 'AnsibleAutoTestALB - UPDATED'
  protocol: HTTP
  wait: true
  state: update
register: alb_forwarding_rule_update_response


name: Delete Application Load Balancer Forwarding Rule
ionoscloudsdk.ionoscloud.application_load_balancer_forwardingrule:
  datacenter: ''
  application_load_balancer: ''
  forwarding_rule: ''
  state: absent

```

&#x20; &#x20;

### Returned object

```json
{
    "changed": true,
    "failed": false,
    "action": "create",
    "forwarding_rule": {
        "href": "https://api.ionos.com/cloudapi/v6/datacenters/0c0e3049-ebbd-4465-a766-62f6950c109e/applicationloadbalancers/5c0b9b00-ae36-4626-bff6-e6c30e6d2809/forwardingrules/e64fb339-1a81-4828-83b1-5e72c238f0a5",
        "id": "e64fb339-1a81-4828-83b1-5e72c238f0a5",
        "metadata": {
            "created_by": "<USER_EMAIL>",
            "created_by_user_id": "<USER_ID>",
            "created_date": "2023-05-29T13:12:17+00:00",
            "etag": "7d16bc2be7483c6544330b4b3ecdbf8f",
            "last_modified_by": "<USER_EMAIL>",
            "last_modified_by_user_id": "<USER_ID>",
            "last_modified_date": "2023-05-29T13:12:17+00:00",
            "state": "BUSY"
        },
        "properties": {
            "client_timeout": null,
            "http_rules": [
                {
                    "conditions": [
                        {
                            "condition": "STARTS_WITH",
                            "key": null,
                            "negate": false,
                            "type": "HEADER",
                            "value": "Friday"
                        }
                    ],
                    "content_type": "application/json",
                    "drop_query": null,
                    "location": null,
                    "name": "Ansible HTTP Rule",
                    "response_message": "<>",
                    "status_code": null,
                    "target_group": null,
                    "type": "static"
                }
            ],
            "listener_ip": "10.12.118.224",
            "listener_port": 8081,
            "name": "AnsibleAutoTestALB",
            "protocol": "HTTP",
            "server_certificates": []
        },
        "type": "forwarding-rule"
    }
}

```

#### For more examples please check out the tests [here](https://github.com/ionos-cloud/module-ansible/tree/master/tests/applicationloadbalancer).

&#x20;

&#x20;

## state: **present**

```yaml
  
name: Create Application Load Balancer Forwarding Rule
ionoscloudsdk.ionoscloud.application_load_balancer_forwardingrule:
  datacenter: ''
  application_load_balancer: ''
  name: 'AnsibleAutoTestALB'
  protocol: HTTP
  listener_ip: 10.12.118.224
  listener_port: '8081'
  http_rules:
  - name: Ansible HTTP Rule
    type: static
    response_message: <>
    content_type: application/json
    conditions:
    - type: HEADER
      condition: STARTS_WITH
      value: Friday
  wait: true
register: alb_forwarding_rule_response

```

#### Available parameters for state **present**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>name<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The name of the Application Load Balancer forwarding rule.</td></tr><tr><td>algorithm<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Balancing algorithm.</td></tr><tr><td>protocol<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The balancing protocol.</td></tr><tr><td>listener_ip<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The listening (inbound) IP.</td></tr><tr><td>listener_port<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The listening (inbound) port number; the valid range is 1 to 65535.</td></tr><tr><td>client_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>The maximum time in milliseconds to wait for the client to acknowledge or send data; default is 50,000 (50 seconds).</td></tr><tr><td>http_rules<br><mark style="color:blue;">list</mark></td><td align="center">False</td><td>An array of items in the collection. The original order of rules is preserved during processing, except that rules of the 'FORWARD' type are processed after the rules with other defined actions. The relative order of the 'FORWARD' type rules is also preserved during the processing.</td></tr><tr><td>server_certificates<br><mark style="color:blue;">list</mark></td><td align="center">False</td><td>Array of items in the collection.</td></tr><tr><td>new_server_certificates<br><mark style="color:blue;">list</mark></td><td align="center">False</td><td>An array of dict with information used to uploade new certificates and add them to the forwarding rule.A dict should contain 'certificate_file', 'private_key_file', 'certificate_chain_file'(optional), 'certificate_name' as keys.File paths should be absolute.</td></tr><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of the datacenter.</td></tr><tr><td>application_load_balancer<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of the Application Loadbalancer.</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['present', 'absent', 'update']</td></tr></tbody></table>

&#x20;

&#x20;

## state: **absent**

```yaml
  
name: Delete Application Load Balancer Forwarding Rule
ionoscloudsdk.ionoscloud.application_load_balancer_forwardingrule:
  datacenter: ''
  application_load_balancer: ''
  forwarding_rule: ''
  state: absent

```

#### Available parameters for state **absent**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>name<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The name of the Application Load Balancer forwarding rule.</td></tr><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of the datacenter.</td></tr><tr><td>application_load_balancer<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of the Application Loadbalancer.</td></tr><tr><td>forwarding_rule<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of the Application Loadbalancer forwarding rule.</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['present', 'absent', 'update']</td></tr></tbody></table>

&#x20;

&#x20;

## state: **update**

```yaml
  
name: Update Application Load Balancer Forwarding Rule
ionoscloudsdk.ionoscloud.application_load_balancer_forwardingrule:
  datacenter: ''
  application_load_balancer: ''
  forwarding_rule: ''
  name: 'AnsibleAutoTestALB - UPDATED'
  protocol: HTTP
  wait: true
  state: update
register: alb_forwarding_rule_update_response

```

#### Available parameters for state **update**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>name<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The name of the Application Load Balancer forwarding rule.</td></tr><tr><td>algorithm<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Balancing algorithm.</td></tr><tr><td>protocol<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The balancing protocol.</td></tr><tr><td>listener_ip<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The listening (inbound) IP.</td></tr><tr><td>listener_port<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The listening (inbound) port number; the valid range is 1 to 65535.</td></tr><tr><td>client_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>The maximum time in milliseconds to wait for the client to acknowledge or send data; default is 50,000 (50 seconds).</td></tr><tr><td>http_rules<br><mark style="color:blue;">list</mark></td><td align="center">False</td><td>An array of items in the collection. The original order of rules is preserved during processing, except that rules of the 'FORWARD' type are processed after the rules with other defined actions. The relative order of the 'FORWARD' type rules is also preserved during the processing.</td></tr><tr><td>server_certificates<br><mark style="color:blue;">list</mark></td><td align="center">False</td><td>Array of items in the collection.</td></tr><tr><td>new_server_certificates<br><mark style="color:blue;">list</mark></td><td align="center">False</td><td>An array of dict with information used to uploade new certificates and add them to the forwarding rule.A dict should contain 'certificate_file', 'private_key_file', 'certificate_chain_file'(optional), 'certificate_name' as keys.File paths should be absolute.</td></tr><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of the datacenter.</td></tr><tr><td>application_load_balancer<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of the Application Loadbalancer.</td></tr><tr><td>forwarding_rule<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of the Application Loadbalancer forwarding rule.</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['present', 'absent', 'update']</td></tr></tbody></table>

&#x20;

&#x20;


# Application Load Balancer

## application\_load\_balancer

This is a simple module that supports creating or removing Application Loadbalancers.

### Example Syntax

```yaml

name: Create Application Load Balancer
ionoscloudsdk.ionoscloud.application_load_balancer:
  datacenter: ''
  name: 'AnsibleAutoTestALB'
  ips:
  - 10.12.118.224
  listener_lan: ''
  target_lan: ''
  wait: true
  wait_timeout: 2000
register: alb_response


name: Update Application Load Balancer
ionoscloudsdk.ionoscloud.application_load_balancer:
  datacenter: 'AnsibleAutoTestALB'
  application_load_balancer: ''
  name: 'AnsibleAutoTestALB - UPDATE'
  listener_lan: ''
  target_lan: ''
  wait: true
  state: update
  wait_timeout: 2000
register: alb_response_update


name: Remove Application Load Balancer
ionoscloudsdk.ionoscloud.application_load_balancer:
  application_load_balancer: 'AnsibleAutoTestALB - UPDATE'
  datacenter: ''
  wait: true
  wait_timeout: 2000
  state: absent

```

&#x20; &#x20;

### Returned object

```json
{
    "changed": true,
    "failed": false,
    "action": "create",
    "application_load_balancer": {
        "entities": null,
        "href": "https://api.ionos.com/cloudapi/v6/datacenters/0c0e3049-ebbd-4465-a766-62f6950c109e/applicationloadbalancers/5c0b9b00-ae36-4626-bff6-e6c30e6d2809",
        "id": "5c0b9b00-ae36-4626-bff6-e6c30e6d2809",
        "metadata": {
            "created_by": "<USER_EMAIL>",
            "created_by_user_id": "<USER_ID>",
            "created_date": "2023-05-29T13:08:28+00:00",
            "etag": "45f17e1cad28dd4973ab127082018599",
            "last_modified_by": "<USER_EMAIL>",
            "last_modified_by_user_id": "<USER_ID>",
            "last_modified_date": "2023-05-29T13:08:28+00:00",
            "state": "BUSY"
        },
        "properties": {
            "ips": [
                "<IP>"
            ],
            "lb_private_ips": null,
            "listener_lan": 1,
            "name": "AnsibleAutoTestALB",
            "target_lan": 2
        },
        "type": "applicationloadbalancer"
    }
}

```

#### For more examples please check out the tests [here](https://github.com/ionos-cloud/module-ansible/tree/master/tests/applicationloadbalancer).

&#x20;

&#x20;

## state: **present**

```yaml
  
name: Create Application Load Balancer
ionoscloudsdk.ionoscloud.application_load_balancer:
  datacenter: ''
  name: 'AnsibleAutoTestALB'
  ips:
  - 10.12.118.224
  listener_lan: ''
  target_lan: ''
  wait: true
  wait_timeout: 2000
register: alb_response

```

#### Available parameters for state **present**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>name<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The Application Load Balancer name.</td></tr><tr><td>listener_lan<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID of the listening (inbound) LAN.</td></tr><tr><td>ips<br><mark style="color:blue;">list</mark></td><td align="center">False</td><td>Collection of the Application Load Balancer IP addresses. (Inbound and outbound) IPs of the 'listenerLan' are customer-reserved public IPs for the public load balancers, and private IPs for the private load balancers.</td></tr><tr><td>target_lan<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID of the balanced private target LAN (outbound).</td></tr><tr><td>lb_private_ips<br><mark style="color:blue;">list</mark></td><td align="center">False</td><td>Collection of private IP addresses with the subnet mask of the Application Load Balancer. IPs must contain valid a subnet mask. If no IP is provided, the system will generate an IP with /24 subnet.</td></tr><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of the datacenter.</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['present', 'absent', 'update']</td></tr></tbody></table>

&#x20;

&#x20;

## state: **absent**

```yaml
  
name: Remove Application Load Balancer
ionoscloudsdk.ionoscloud.application_load_balancer:
  application_load_balancer: 'AnsibleAutoTestALB - UPDATE'
  datacenter: ''
  wait: true
  wait_timeout: 2000
  state: absent

```

#### Available parameters for state **absent**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>name<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Application Load Balancer name.</td></tr><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of the datacenter.</td></tr><tr><td>application_load_balancer<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of the Application Loadbalancer.</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['present', 'absent', 'update']</td></tr></tbody></table>

&#x20;

&#x20;

## state: **update**

```yaml
  
name: Update Application Load Balancer
ionoscloudsdk.ionoscloud.application_load_balancer:
  datacenter: 'AnsibleAutoTestALB'
  application_load_balancer: ''
  name: 'AnsibleAutoTestALB - UPDATE'
  listener_lan: ''
  target_lan: ''
  wait: true
  state: update
  wait_timeout: 2000
register: alb_response_update

```

#### Available parameters for state **update**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>name<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The Application Load Balancer name.</td></tr><tr><td>listener_lan<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID of the listening (inbound) LAN.</td></tr><tr><td>ips<br><mark style="color:blue;">list</mark></td><td align="center">False</td><td>Collection of the Application Load Balancer IP addresses. (Inbound and outbound) IPs of the 'listenerLan' are customer-reserved public IPs for the public load balancers, and private IPs for the private load balancers.</td></tr><tr><td>target_lan<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID of the balanced private target LAN (outbound).</td></tr><tr><td>lb_private_ips<br><mark style="color:blue;">list</mark></td><td align="center">False</td><td>Collection of private IP addresses with the subnet mask of the Application Load Balancer. IPs must contain valid a subnet mask. If no IP is provided, the system will generate an IP with /24 subnet.</td></tr><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of the datacenter.</td></tr><tr><td>application_load_balancer<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of the Application Loadbalancer.</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['present', 'absent', 'update']</td></tr></tbody></table>

&#x20;

&#x20;


# Target Group

## target\_group

This is a simple module that supports creating or removing Target Groups.

### Example Syntax

```yaml

name: Create Target Group
ionoscloudsdk.ionoscloud.target_group:
  name: 'AnsibleAutoTestALB'
  algorithm: ROUND_ROBIN
  protocol: HTTP
  targets:
  - ip: 22.231.2.2
    port: 8080
    weight: 123
    health_check_enabled: true
    maintenance_enabled: false
  health_check:
    check_timeout: 2000
    check_interval: 1000
    retries: 3
  http_health_check:
    path: ./
    method: GET
    match_type: STATUS_CODE
    response: '200'
    regex: false
    negate: false
  wait: true
register: target_group_response


name: Update Target Group
ionoscloudsdk.ionoscloud.target_group:
  name: 'AnsibleAutoTestALB - UPDATED'
  algorithm: ROUND_ROBIN
  protocol: HTTP
  target_group: ''
  wait: true
  state: update
register: target_group_response_update


name: Remove Target Group
ionoscloudsdk.ionoscloud.target_group:
  target_group: ''
  wait: true
  wait_timeout: 2000
  state: absent

```

&#x20; &#x20;

### Returned object

```json
{
    "changed": true,
    "failed": false,
    "action": "create",
    "target_group": {
        "href": "https://api.ionos.com/cloudapi/v6/targetgroups/5f757b12-776b-4ac0-befb-56499db09baf",
        "id": "5f757b12-776b-4ac0-befb-56499db09baf",
        "metadata": {
            "created_by": "<USER_EMAIL>",
            "created_by_user_id": "<USER_ID>",
            "created_date": "2023-06-06T10:01:58+00:00",
            "etag": "8f3a5c9d9ddd3ef6312b02d3bc9c319e",
            "last_modified_by": "<USER_EMAIL>",
            "last_modified_by_user_id": "<USER_ID>",
            "last_modified_date": "2023-06-06T10:01:58+00:00",
            "state": "BUSY"
        },
        "properties": {
            "algorithm": "ROUND_ROBIN",
            "health_check": {
                "check_interval": 1000,
                "check_timeout": 2000,
                "retries": 3
            },
            "http_health_check": {
                "match_type": "STATUS_CODE",
                "method": "GET",
                "negate": false,
                "path": "./",
                "regex": false,
                "response": "200"
            },
            "name": "AnsibleAutoTestALB",
            "protocol": "HTTP",
            "targets": [
                {
                    "health_check_enabled": true,
                    "ip": "<IP>",
                    "maintenance_enabled": null,
                    "port": 8080,
                    "weight": 123
                }
            ]
        },
        "type": "target-group"
    }
}

```

#### For more examples please check out the tests [here](https://github.com/ionos-cloud/module-ansible/tree/master/tests/applicationloadbalancer).

&#x20;

&#x20;

## state: **present**

```yaml
  
name: Create Target Group
ionoscloudsdk.ionoscloud.target_group:
  name: 'AnsibleAutoTestALB'
  algorithm: ROUND_ROBIN
  protocol: HTTP
  targets:
  - ip: 22.231.2.2
    port: 8080
    weight: 123
    health_check_enabled: true
    maintenance_enabled: false
  health_check:
    check_timeout: 2000
    check_interval: 1000
    retries: 3
  http_health_check:
    path: ./
    method: GET
    match_type: STATUS_CODE
    response: '200'
    regex: false
    negate: false
  wait: true
register: target_group_response

```

#### Available parameters for state **present**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>name<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The target group name.</td></tr><tr><td>algorithm<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The balancing algorithm. A balancing algorithm consists of predefined rules with the logic that a load balancer uses to distribute network traffic between servers. - **Round Robin**: Targets are served alternately according to their weighting. - **Least Connection**: The target with the least active connection is served. - **Random**: The targets are served based on a consistent pseudorandom algorithm. - **Source IP**: It is ensured that the same client IP address reaches the same target.</td></tr><tr><td>protocol<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The forwarding protocol. Only the value 'HTTP' is allowed.</td></tr><tr><td>health_check<br><mark style="color:blue;">dict</mark></td><td align="center">False</td><td>Health check properties for target group.</td></tr><tr><td>http_health_check<br><mark style="color:blue;">dict</mark></td><td align="center">False</td><td>HTTP health check properties for target group.</td></tr><tr><td>targets<br><mark style="color:blue;">list</mark></td><td align="center">False</td><td>Array of items in the collection.</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['present', 'absent', 'update']</td></tr></tbody></table>

&#x20;

&#x20;

## state: **absent**

```yaml
  
name: Remove Target Group
ionoscloudsdk.ionoscloud.target_group:
  target_group: ''
  wait: true
  wait_timeout: 2000
  state: absent

```

#### Available parameters for state **absent**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>name<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The target group name.</td></tr><tr><td>target_group<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of the Target Group.</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['present', 'absent', 'update']</td></tr></tbody></table>

&#x20;

&#x20;

## state: **update**

```yaml
  
name: Update Target Group
ionoscloudsdk.ionoscloud.target_group:
  name: 'AnsibleAutoTestALB - UPDATED'
  algorithm: ROUND_ROBIN
  protocol: HTTP
  target_group: ''
  wait: true
  state: update
register: target_group_response_update

```

#### Available parameters for state **update**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>name<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The target group name.</td></tr><tr><td>algorithm<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The balancing algorithm. A balancing algorithm consists of predefined rules with the logic that a load balancer uses to distribute network traffic between servers. - **Round Robin**: Targets are served alternately according to their weighting. - **Least Connection**: The target with the least active connection is served. - **Random**: The targets are served based on a consistent pseudorandom algorithm. - **Source IP**: It is ensured that the same client IP address reaches the same target.</td></tr><tr><td>protocol<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The forwarding protocol. Only the value 'HTTP' is allowed.</td></tr><tr><td>health_check<br><mark style="color:blue;">dict</mark></td><td align="center">False</td><td>Health check properties for target group.</td></tr><tr><td>http_health_check<br><mark style="color:blue;">dict</mark></td><td align="center">False</td><td>HTTP health check properties for target group.</td></tr><tr><td>targets<br><mark style="color:blue;">list</mark></td><td align="center">False</td><td>Array of items in the collection.</td></tr><tr><td>target_group<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of the Target Group.</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['present', 'absent', 'update']</td></tr></tbody></table>

&#x20;

&#x20;


# Info Modules


# Flowlogs

This is a simple module that supports listing Flowlogs.

## Example Syntax

```yaml

name: List Application Load Balancer Flowlogs
ionoscloudsdk.ionoscloud.application_load_balancer_flowlog_info:
  datacenter: ''
  application_load_balancer: ''
register: alb_flowlog_list_response

```

&#x20;

### For more examples please check out the tests [here](https://github.com/ionos-cloud/module-ansible/tree/master/tests/applicationloadbalancer).

&#x20;

### Available parameters:

&#x20;

<table data-full-width="true"><thead><tr><th>Name</th><th align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of the datacenter.</td></tr><tr><td>application_load_balancer<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of the Application Loadbalancer.</td></tr><tr><td>depth<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>The depth used when retrieving the items.<br>Default: 1</td></tr><tr><td>filters<br><mark style="color:blue;">dict</mark></td><td align="center">False</td><td>Filter that can be used to list only objects which have a certain set of properties. Filters should be a dict with a key containing keys and value pair in the following format: 'properties.name': 'server_name'</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr></tbody></table>


# Application Load Balancer Forwarding Rules

This is a simple module that supports listing Forwarding Rules.

## Example Syntax

```yaml

name: List Application Load Balancer Forwarding rules
ionoscloudsdk.ionoscloud.application_load_balancer_forwardingrule_info:
  datacenter: ''
  application_load_balancer: ''
register: alb_forwardingrule_list_response

```

&#x20;

### For more examples please check out the tests [here](https://github.com/ionos-cloud/module-ansible/tree/master/tests/applicationloadbalancer).

&#x20;

### Available parameters:

&#x20;

<table data-full-width="true"><thead><tr><th>Name</th><th align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of the datacenter.</td></tr><tr><td>application_load_balancer<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of the Application Loadbalancer.</td></tr><tr><td>depth<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>The depth used when retrieving the items.<br>Default: 1</td></tr><tr><td>filters<br><mark style="color:blue;">dict</mark></td><td align="center">False</td><td>Filter that can be used to list only objects which have a certain set of properties. Filters should be a dict with a key containing keys and value pair in the following format: 'properties.name': 'server_name'</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr></tbody></table>


# Application Load Balancers

This is a simple module that supports listing Application Load Balancers.

## Example Syntax

```yaml

name: List Application Load Balancers
ionoscloudsdk.ionoscloud.application_load_balancer_info:
  datacenter: ''
register: alb_list_response

```

&#x20;

### For more examples please check out the tests [here](https://github.com/ionos-cloud/module-ansible/tree/master/tests/applicationloadbalancer).

&#x20;

### Available parameters:

&#x20;

<table data-full-width="true"><thead><tr><th>Name</th><th align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of the datacenter.</td></tr><tr><td>depth<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>The depth used when retrieving the items.<br>Default: 1</td></tr><tr><td>filters<br><mark style="color:blue;">dict</mark></td><td align="center">False</td><td>Filter that can be used to list only objects which have a certain set of properties. Filters should be a dict with a key containing keys and value pair in the following format: 'properties.name': 'server_name'</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr></tbody></table>


# Target Groups

This is a simple module that supports listing Target Groups.

## Example Syntax

```yaml

name: List Target Groups
ionoscloudsdk.ionoscloud.target_group_info: null
register: target_groups_response

```

&#x20;

### For more examples please check out the tests [here](https://github.com/ionos-cloud/module-ansible/tree/master/tests/applicationloadbalancer).

&#x20;

### Available parameters:

&#x20;

<table data-full-width="true"><thead><tr><th>Name</th><th align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>depth<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>The depth used when retrieving the items.<br>Default: 1</td></tr><tr><td>filters<br><mark style="color:blue;">dict</mark></td><td align="center">False</td><td>Filter that can be used to list only objects which have a certain set of properties. Filters should be a dict with a key containing keys and value pair in the following format: 'properties.name': 'server_name'</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr></tbody></table>


# Compute Engine


# Modules


# CUBE Server

## cube\_server

Create, update, destroy, update, resume, suspend, and reboot a Ionos CUBE virtual machine. When the virtual machine is created it can optionally wait for it to be 'running' before returning.

### Example Syntax

```yaml

name: Provision a server
ionoscloudsdk.ionoscloud.cube_server:
  datacenter: 'AnsibleAutoTestCompute'
  name: 'AnsibleAutoTestCompute 01'
  disk_type: DAS
  image: 'ubuntu:latest'
  image_password: '{{ lookup('ansible.builtin.password', '/dev/null chars=ascii_letters,digits') }}'
  location: de/txl
  count: 1
  assign_public_ip: true
  remove_boot_volume: true
  template_uuid: '72e73b81-8551-4e74-b398-fc63b39994af'
  availability_zone: AUTO
  wait: true
  wait_timeout: '500'
  state: present
register: server_cube


name: Update server
ionoscloudsdk.ionoscloud.cube_server:
  datacenter: 'AnsibleAutoTestCompute'
  name: 'AnsibleAutoTestCompute - UPDATED'
  instance_ids:
  - 'AnsibleAutoTestCompute 01'
  wait: true
  wait_timeout: '500'
  state: update


name: Remove server
ionoscloudsdk.ionoscloud.cube_server:
  datacenter: 'AnsibleAutoTestCompute'
  instance_ids:
  - 'AnsibleAutoTestCompute - UPDATED'
  remove_boot_volume: true
  wait_timeout: '500'
  state: absent


name: Resume server
ionoscloudsdk.ionoscloud.cube_server:
  datacenter: 'AnsibleAutoTestCompute'
  instance_ids:
  - 'AnsibleAutoTestCompute - UPDATED'
  wait_timeout: '500'
  state: resume


name: Suspend server
ionoscloudsdk.ionoscloud.cube_server:
  datacenter: 'AnsibleAutoTestCompute'
  instance_ids:
  - 'AnsibleAutoTestCompute - UPDATED'
  wait_timeout: '500'
  state: suspend

```

&#x20; &#x20;

### Returned object

```json
{
    "changed": true,
    "failed": false,
    "machines": [
        {
            "entities": {
                "cdroms": {
                    "links": null,
                    "href": "https://api.ionos.com/cloudapi/v6/datacenters/fb6c7a8d-ab0a-434d-9507-7bb83835751a/servers/595d4dcb-8872-4b70-b757-071106809c11/cdroms",
                    "id": "595d4dcb-8872-4b70-b757-071106809c11/cdroms",
                    "items": [],
                    "limit": null,
                    "offset": null,
                    "type": "collection"
                },
                "nics": {
                    "links": null,
                    "href": "https://api.ionos.com/cloudapi/v6/datacenters/fb6c7a8d-ab0a-434d-9507-7bb83835751a/servers/595d4dcb-8872-4b70-b757-071106809c11/nics",
                    "id": "595d4dcb-8872-4b70-b757-071106809c11/nics",
                    "items": [
                        {
                            "entities": {
                                "firewallrules": {
                                    "links": null,
                                    "href": "https://api.ionos.com/cloudapi/v6/datacenters/fb6c7a8d-ab0a-434d-9507-7bb83835751a/servers/595d4dcb-8872-4b70-b757-071106809c11/nics/f3d10c9a-f27f-4c0e-911e-57116bfd6b5f/firewallrules",
                                    "id": "f3d10c9a-f27f-4c0e-911e-57116bfd6b5f/firewallrules",
                                    "items": null,
                                    "limit": null,
                                    "offset": null,
                                    "type": "collection"
                                },
                                "flowlogs": {
                                    "links": null,
                                    "href": "https://api.ionos.com/cloudapi/v6/datacenters/fb6c7a8d-ab0a-434d-9507-7bb83835751a/servers/595d4dcb-8872-4b70-b757-071106809c11/nics/f3d10c9a-f27f-4c0e-911e-57116bfd6b5f/flowlogs",
                                    "id": "f3d10c9a-f27f-4c0e-911e-57116bfd6b5f/flowlogs",
                                    "items": null,
                                    "limit": null,
                                    "offset": null,
                                    "type": "collection"
                                }
                            },
                            "href": "https://api.ionos.com/cloudapi/v6/datacenters/fb6c7a8d-ab0a-434d-9507-7bb83835751a/servers/595d4dcb-8872-4b70-b757-071106809c11/nics/f3d10c9a-f27f-4c0e-911e-57116bfd6b5f",
                            "id": "f3d10c9a-f27f-4c0e-911e-57116bfd6b5f",
                            "metadata": {
                                "created_by": "<USER_EMAIL>",
                                "created_by_user_id": "<USER_ID>",
                                "created_date": "2023-06-06T13:38:37+00:00",
                                "etag": "b5741a67e66f02d91468c1f1420c1fcf",
                                "last_modified_by": "<USER_EMAIL>",
                                "last_modified_by_user_id": "<USER_ID>",
                                "last_modified_date": "2023-06-06T13:38:37+00:00",
                                "state": "AVAILABLE"
                            },
                            "properties": {
                                "device_number": null,
                                "dhcp": true,
                                "firewall_active": false,
                                "firewall_type": "INGRESS",
                                "ips": [
                                    "<IP>"
                                ],
                                "lan": 1,
                                "mac": "02:01:ed:b1:3d:98",
                                "name": "90aaee2d0c",
                                "pci_slot": 6
                            },
                            "type": "nic"
                        }
                    ],
                    "limit": null,
                    "offset": null,
                    "type": "collection"
                },
                "volumes": {
                    "links": null,
                    "href": "https://api.ionos.com/cloudapi/v6/datacenters/fb6c7a8d-ab0a-434d-9507-7bb83835751a/servers/595d4dcb-8872-4b70-b757-071106809c11/volumes",
                    "id": "595d4dcb-8872-4b70-b757-071106809c11/volumes",
                    "items": [
                        {
                            "href": "https://api.ionos.com/cloudapi/v6/datacenters/fb6c7a8d-ab0a-434d-9507-7bb83835751a/volumes/52f55625-5fa3-4d9c-b244-6db1609c5918",
                            "id": "52f55625-5fa3-4d9c-b244-6db1609c5918",
                            "metadata": {
                                "created_by": "<USER_EMAIL>",
                                "created_by_user_id": "<USER_ID>",
                                "created_date": "2023-06-06T13:38:37+00:00",
                                "etag": "b5741a67e66f02d91468c1f1420c1fcf",
                                "last_modified_by": "<USER_EMAIL>",
                                "last_modified_by_user_id": "<USER_ID>",
                                "last_modified_date": "2023-06-06T13:38:37+00:00",
                                "state": "AVAILABLE"
                            },
                            "properties": {
                                "availability_zone": "AUTO",
                                "backupunit_id": null,
                                "boot_order": "AUTO",
                                "boot_server": "595d4dcb-8872-4b70-b757-071106809c11",
                                "bus": "VIRTIO",
                                "cpu_hot_plug": true,
                                "device_number": 1,
                                "disc_virtio_hot_plug": true,
                                "disc_virtio_hot_unplug": true,
                                "image": "48150141-a6b9-11ed-9e9f-e60bb43016ef",
                                "image_alias": null,
                                "image_password": null,
                                "licence_type": "LINUX",
                                "name": "ada2931874",
                                "nic_hot_plug": true,
                                "nic_hot_unplug": true,
                                "pci_slot": 5,
                                "ram_hot_plug": true,
                                "size": 30.0,
                                "ssh_keys": null,
                                "type": "DAS",
                                "user_data": null
                            },
                            "type": "volume"
                        }
                    ],
                    "limit": null,
                    "offset": null,
                    "type": "collection"
                }
            },
            "href": "https://api.ionos.com/cloudapi/v6/datacenters/fb6c7a8d-ab0a-434d-9507-7bb83835751a/servers/595d4dcb-8872-4b70-b757-071106809c11",
            "id": "595d4dcb-8872-4b70-b757-071106809c11",
            "metadata": {
                "created_by": "<USER_EMAIL>",
                "created_by_user_id": "<USER_ID>",
                "created_date": "2023-06-06T13:38:37+00:00",
                "etag": "b5741a67e66f02d91468c1f1420c1fcf",
                "last_modified_by": "<USER_EMAIL>",
                "last_modified_by_user_id": "<USER_ID>",
                "last_modified_date": "2023-06-06T13:38:37+00:00",
                "state": "AVAILABLE"
            },
            "properties": {
                "availability_zone": "AUTO",
                "boot_cdrom": null,
                "boot_volume": {
                    "href": "https://api.ionos.com/cloudapi/v6/datacenters/fb6c7a8d-ab0a-434d-9507-7bb83835751a/volumes/52f55625-5fa3-4d9c-b244-6db1609c5918",
                    "id": "52f55625-5fa3-4d9c-b244-6db1609c5918",
                    "type": "volume"
                },
                "cores": 1,
                "cpu_family": "AMD_EPYC",
                "name": "AnsibleAutoTestCompute 01",
                "ram": 1024,
                "template_uuid": "15c6dd2f-02d2-4987-b439-9a58dd59ecc3",
                "type": "CUBE",
                "vm_state": "RUNNING"
            },
            "type": "server"
        }
    ],
    "action": "create"
}

```

#### For more examples please check out the tests [here](https://github.com/ionos-cloud/module-ansible/tree/master/tests/compute-engine/README.md).

&#x20;

***NOTE:*** **If you are using a versions 7.0.0 and up**: modules can replace resources if certain set parameters differ from the results found in the API!

### Parameters that can trigger a resource replacement:

* template\_uuid
* availability\_zone &#x20;

## state: **resume**

```yaml
  
name: Resume server
ionoscloudsdk.ionoscloud.cube_server:
  datacenter: 'AnsibleAutoTestCompute'
  instance_ids:
  - 'AnsibleAutoTestCompute - UPDATED'
  wait_timeout: '500'
  state: resume

```

#### Available parameters for state **resume**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The datacenter to provision this virtual machine.</td></tr><tr><td>instance_ids<br><mark style="color:blue;">list</mark></td><td align="center">False</td><td>list of instance ids. Should only contain one ID if renaming in update state<br>Default:</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['resume', 'suspend', 'absent', 'present', 'update']</td></tr></tbody></table>

&#x20;

&#x20;

## state: **suspend**

```yaml
  
name: Suspend server
ionoscloudsdk.ionoscloud.cube_server:
  datacenter: 'AnsibleAutoTestCompute'
  instance_ids:
  - 'AnsibleAutoTestCompute - UPDATED'
  wait_timeout: '500'
  state: suspend

```

#### Available parameters for state **suspend**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The datacenter to provision this virtual machine.</td></tr><tr><td>instance_ids<br><mark style="color:blue;">list</mark></td><td align="center">False</td><td>list of instance ids. Should only contain one ID if renaming in update state<br>Default:</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['resume', 'suspend', 'absent', 'present', 'update']</td></tr></tbody></table>

&#x20;

&#x20;

## state: **absent**

```yaml
  
name: Remove server
ionoscloudsdk.ionoscloud.cube_server:
  datacenter: 'AnsibleAutoTestCompute'
  instance_ids:
  - 'AnsibleAutoTestCompute - UPDATED'
  remove_boot_volume: true
  wait_timeout: '500'
  state: absent

```

#### Available parameters for state **absent**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>name<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The name of the resource.</td></tr><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The datacenter to provision this virtual machine.</td></tr><tr><td>instance_ids<br><mark style="color:blue;">list</mark></td><td align="center">False</td><td>list of instance ids. Should only contain one ID if renaming in update state<br>Default:</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['resume', 'suspend', 'absent', 'present', 'update']</td></tr></tbody></table>

&#x20;

&#x20;

## state: **present**

```yaml
  
name: Provision a server
ionoscloudsdk.ionoscloud.cube_server:
  datacenter: 'AnsibleAutoTestCompute'
  name: 'AnsibleAutoTestCompute 01'
  disk_type: DAS
  image: 'ubuntu:latest'
  image_password: '{{ lookup('ansible.builtin.password', '/dev/null chars=ascii_letters,digits') }}'
  location: de/txl
  count: 1
  assign_public_ip: true
  remove_boot_volume: true
  template_uuid: '72e73b81-8551-4e74-b398-fc63b39994af'
  availability_zone: AUTO
  wait: true
  wait_timeout: '500'
  state: present
register: server_cube

```

#### Available parameters for state **present**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>name<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The name of the resource.</td></tr><tr><td>assign_public_ip<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>This will assign the machine to the public LAN. If no LAN exists with public Internet access it is created.<br>Default: False<br>Options: [True, False]</td></tr><tr><td>image<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The image alias or ID for creating the virtual machine.</td></tr><tr><td>image_password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Password set for the administrative user.</td></tr><tr><td>ssh_keys<br><mark style="color:blue;">list</mark></td><td align="center">False</td><td>Public SSH keys allowing access to the virtual machine.<br>Default:</td></tr><tr><td>user_data<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The cloud-init configuration for the volume as base64 encoded string.</td></tr><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The datacenter to provision this virtual machine.</td></tr><tr><td>availability_zone<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The availability zone in which the server should be provisioned. For CUBE and GPU servers, the only value accepted is 'AUTO'. For servers with Confidential Computing enabled, this field is immutable once the server has been created — update requests attempting to change it will be rejected.<br>Options: ['AUTO', 'ZONE_1', 'ZONE_2']</td></tr><tr><td>bus<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The bus type for the volume.<br>Default: VIRTIO<br>Options: ['IDE', 'VIRTIO']</td></tr><tr><td>count<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>The number of virtual machines to create.<br>Default: 1</td></tr><tr><td>location<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The datacenter location. Use only if you want to create the Datacenter or else this value is ignored.<br>Default: us/las<br>Options: ['us/las', 'us/ewr', 'de/fra', 'de/fkb', 'de/txl', 'gb/lhr']</td></tr><tr><td>lan<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The ID or name of the LAN you wish to add the servers to (can be a string or a number).</td></tr><tr><td>nat<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Boolean value indicating if the private IP address has outbound access to the public Internet.<br>Default: False<br>Options: [True, False]</td></tr><tr><td>remove_boot_volume<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Remove the bootVolume of the virtual machine you're destroying.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>disk_type<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The disk type for the volume.<br>Default: DAS<br>Options: ['HDD', 'SSD', 'SSD Standard', 'SSD Premium', 'DAS', 'ESSENTIAL', 'BALANCED', 'PERFORMANCE']</td></tr><tr><td>nic_ips<br><mark style="color:blue;">list</mark></td><td align="center">False</td><td>The list of IPS for the NIC.</td></tr><tr><td>template_uuid<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The ID of the template for creating CUBE or GPU servers. If a template has GPU cards assigned, then it can only be used to create GPU servers, otherwise it can only be used for CUBE servers. The available templates can be found on the templates resource.</td></tr><tr><td>boot_volume<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Reference to a volume used as boot device. If the server has a volume with a Confidential Computing image, that volume — and only that volume — is eligible as the boot volume. Setting `bootVolume` to any other volume is rejected. If `bootVolume` is not provided on a server that has a Confidential Computing volume, that volume is automatically selected as the boot device. On servers with Confidential Computing enabled this field is immutable once the server has been created — update requests attempting to change it will be rejected.</td></tr><tr><td>boot_cdrom<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Reference to a CD-ROM used as boot device. Forbidden when the server has a volume whose image is a Confidential Computing image: such a server must boot from that volume and cannot boot from a CD-ROM. On servers with Confidential Computing enabled this field is immutable — update requests attempting to change it will be rejected.</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['resume', 'suspend', 'absent', 'present', 'update']</td></tr></tbody></table>

&#x20;

&#x20;

## state: **update**

```yaml
  
name: Update server
ionoscloudsdk.ionoscloud.cube_server:
  datacenter: 'AnsibleAutoTestCompute'
  name: 'AnsibleAutoTestCompute - UPDATED'
  instance_ids:
  - 'AnsibleAutoTestCompute 01'
  wait: true
  wait_timeout: '500'
  state: update

```

#### Available parameters for state **update**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>name<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The name of the resource.</td></tr><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The datacenter to provision this virtual machine.</td></tr><tr><td>instance_ids<br><mark style="color:blue;">list</mark></td><td align="center">False</td><td>list of instance ids. Should only contain one ID if renaming in update state<br>Default:</td></tr><tr><td>boot_volume<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Reference to a volume used as boot device. If the server has a volume with a Confidential Computing image, that volume — and only that volume — is eligible as the boot volume. Setting `bootVolume` to any other volume is rejected. If `bootVolume` is not provided on a server that has a Confidential Computing volume, that volume is automatically selected as the boot device. On servers with Confidential Computing enabled this field is immutable once the server has been created — update requests attempting to change it will be rejected.</td></tr><tr><td>boot_cdrom<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Reference to a CD-ROM used as boot device. Forbidden when the server has a volume whose image is a Confidential Computing image: such a server must boot from that volume and cannot boot from a CD-ROM. On servers with Confidential Computing enabled this field is immutable — update requests attempting to change it will be rejected.</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['resume', 'suspend', 'absent', 'present', 'update']</td></tr></tbody></table>

&#x20;

&#x20;


# Datacenter

## datacenter

This is a simple module that supports creating or removing datacenters. A datacenter is required before you can create servers. This module has a dependency on ionoscloud >= 6.0.2

### Example Syntax

```yaml

name: Create datacenter
ionoscloudsdk.ionoscloud.datacenter:
  name: 'AnsibleAutoTestCompute'
  description: 'Ansible Compute test description'
  location: 'gb/lhr'
  wait: true
register: datacenter_response


name: Update datacenter no change 1
ionoscloudsdk.ionoscloud.datacenter:
  datacenter: 'AnsibleAutoTestCompute'
  name: 'AnsibleAutoTestCompute'
  description: 'Ansible Compute test description CHANGED'
  state: update
  allow_replace: false
register: datacenter_response_no_change2


name: Remove datacenter
ionoscloudsdk.ionoscloud.datacenter:
  datacenter: ''
  name: 'AnsibleAutoTestCompute'
  state: absent
  wait: true
register: deleted_datacenter

```

&#x20; &#x20;

### Returned object

```json
{
    "changed": false,
    "failed": false,
    "action": "create",
    "datacenter": {
        "entities": {
            "lans": {
                "links": null,
                "href": "https://api.ionos.com/cloudapi/v6/datacenters/9683f0c0-e311-4194-bddc-a99bb2babf82/lans",
                "id": "9683f0c0-e311-4194-bddc-a99bb2babf82/lans",
                "items": null,
                "limit": null,
                "offset": null,
                "type": "collection"
            },
            "loadbalancers": {
                "links": null,
                "href": "https://api.ionos.com/cloudapi/v6/datacenters/9683f0c0-e311-4194-bddc-a99bb2babf82/loadbalancers",
                "id": "9683f0c0-e311-4194-bddc-a99bb2babf82/loadbalancers",
                "items": null,
                "limit": null,
                "offset": null,
                "type": "collection"
            },
            "natgateways": {
                "links": null,
                "href": "https://api.ionos.com/cloudapi/v6/datacenters/9683f0c0-e311-4194-bddc-a99bb2babf82/natgateways",
                "id": "9683f0c0-e311-4194-bddc-a99bb2babf82/natgateways",
                "items": null,
                "limit": null,
                "offset": null,
                "type": "collection"
            },
            "networkloadbalancers": {
                "links": null,
                "href": "https://api.ionos.com/cloudapi/v6/datacenters/9683f0c0-e311-4194-bddc-a99bb2babf82/networkloadbalancers",
                "id": "9683f0c0-e311-4194-bddc-a99bb2babf82/networkloadbalancers",
                "items": null,
                "limit": null,
                "offset": null,
                "type": "collection"
            },
            "servers": {
                "links": null,
                "href": "https://api.ionos.com/cloudapi/v6/datacenters/9683f0c0-e311-4194-bddc-a99bb2babf82/servers",
                "id": "9683f0c0-e311-4194-bddc-a99bb2babf82/servers",
                "items": null,
                "limit": null,
                "offset": null,
                "type": "collection"
            },
            "volumes": {
                "links": null,
                "href": "https://api.ionos.com/cloudapi/v6/datacenters/9683f0c0-e311-4194-bddc-a99bb2babf82/volumes",
                "id": "9683f0c0-e311-4194-bddc-a99bb2babf82/volumes",
                "items": null,
                "limit": null,
                "offset": null,
                "type": "collection"
            }
        },
        "href": "https://api.ionos.com/cloudapi/v6/datacenters/9683f0c0-e311-4194-bddc-a99bb2babf82",
        "id": "9683f0c0-e311-4194-bddc-a99bb2babf82",
        "metadata": {
            "created_by": "<USER_EMAIL>",
            "created_by_user_id": "<USER_ID>",
            "created_date": "2023-05-30T11:24:38+00:00",
            "etag": "f157640f8bc27aba358aed5cfbd74bf2",
            "last_modified_by": "<USER_EMAIL>",
            "last_modified_by_user_id": "<USER_ID>",
            "last_modified_date": "2023-05-30T11:24:38+00:00",
            "state": "AVAILABLE"
        },
        "properties": {
            "cpu_architecture": [
                {
                    "cpu_family": "INTEL_SKYLAKE",
                    "max_cores": 4,
                    "max_ram": 20480,
                    "vendor": "GenuineIntel"
                }
            ],
            "description": "Ansible Compute test description",
            "features": [
                "cloud-init-private-image",
                "vm-autoscaling",
                "ssd",
                "vnf-nat",
                "k8s",
                "ssd-storage-zoning",
                "nic-hot-plug",
                "vnf-lb",
                "monitoring",
                "nic-hot-unplug",
                "pcc",
                "contract-identities",
                "disk-vio-hot-unplug",
                "disk-vio-hot-plug",
                "cloud-init",
                "flow-logs",
                "cpu-hot-plug",
                "core-vps",
                "k8s-cidr-s3-support",
                "private-loadbalancer",
                "mem-hot-plug",
                "vnf-alb"
            ],
            "location": "gb/lhr",
            "name": "AnsibleAutoTestCompute",
            "sec_auth_protection": false,
            "version": 2
        },
        "type": "datacenter"
    }
}

```

#### For more examples please check out the tests [here](https://github.com/ionos-cloud/module-ansible/tree/master/tests/compute-engine/README.md).

&#x20;

***NOTE:*** **If you are using a versions 7.0.0 and up**: modules can replace resources if certain set parameters differ from the results found in the API!

### Parameters that can trigger a resource replacement:

* location &#x20;

## state: **present**

```yaml
  
name: Create datacenter
ionoscloudsdk.ionoscloud.datacenter:
  name: 'AnsibleAutoTestCompute'
  description: 'Ansible Compute test description'
  location: 'gb/lhr'
  wait: true
register: datacenter_response

```

#### Available parameters for state **present**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>name<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The name of the resource.</td></tr><tr><td>description<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>A description for the datacenter, such as staging, production.</td></tr><tr><td>location<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The physical location where the datacenter will be created. This will be where all of your servers live. Property cannot be modified after datacenter creation (disallowed in update requests).<br>Options: ['us/las', 'us/ewr', 'de/fra', 'de/fra/1', 'de/fra/2', 'de/fkb', 'de/txl', 'gb/lhr', 'es/vit', 'fr/par', 'us/mci']</td></tr><tr><td>allow_replace<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Boolean indicating if the resource should be recreated when the state cannot be reached in another way. This may be used to prevent resources from being deleted from specifying a different value to an immutable property. An error will be thrown instead<br>Default: False</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['present', 'absent', 'update']</td></tr></tbody></table>

&#x20;

&#x20;

## state: **absent**

```yaml
  
name: Remove datacenter
ionoscloudsdk.ionoscloud.datacenter:
  datacenter: ''
  name: 'AnsibleAutoTestCompute'
  state: absent
  wait: true
register: deleted_datacenter

```

#### Available parameters for state **absent**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of the virtual datacenter.</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['present', 'absent', 'update']</td></tr></tbody></table>

&#x20;

&#x20;

## state: **update**

```yaml
  
name: Update datacenter no change 1
ionoscloudsdk.ionoscloud.datacenter:
  datacenter: 'AnsibleAutoTestCompute'
  name: 'AnsibleAutoTestCompute'
  description: 'Ansible Compute test description CHANGED'
  state: update
  allow_replace: false
register: datacenter_response_no_change2

```

#### Available parameters for state **update**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>name<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The name of the resource.</td></tr><tr><td>description<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>A description for the datacenter, such as staging, production.</td></tr><tr><td>location<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The physical location where the datacenter will be created. This will be where all of your servers live. Property cannot be modified after datacenter creation (disallowed in update requests).<br>Options: ['us/las', 'us/ewr', 'de/fra', 'de/fra/1', 'de/fra/2', 'de/fkb', 'de/txl', 'gb/lhr', 'es/vit', 'fr/par', 'us/mci']</td></tr><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of the virtual datacenter.</td></tr><tr><td>allow_replace<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Boolean indicating if the resource should be recreated when the state cannot be reached in another way. This may be used to prevent resources from being deleted from specifying a different value to an immutable property. An error will be thrown instead<br>Default: False</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['present', 'absent', 'update']</td></tr></tbody></table>

&#x20;

&#x20;


# Firewall Rule

## firewall\_rule

This module allows you to create, update or remove a firewall rule.

### Example Syntax

```yaml

name: Create a firewall rule
ionoscloudsdk.ionoscloud.firewall_rule:
  datacenter: 'AnsibleAutoTestCompute'
  server: 'AnsibleAutoTestCompute'
  nic: 'AnsibleAutoTestCompute'
  name: SSH
  protocol: ICMPv6
  source_mac: 01:23:45:67:89:00
  ip_version: IPv6
  state: present


name: Update firewall rule
ionoscloudsdk.ionoscloud.firewall_rule:
  datacenter: 'AnsibleAutoTestCompute'
  server: 'AnsibleAutoTestCompute'
  nic: 'AnsibleAutoTestCompute'
  firewall_rule: SSH
  port_range_start: 22
  port_range_end: 23
  state: update


name: Remove firewall rule
ionoscloudsdk.ionoscloud.firewall_rule:
  datacenter: 'AnsibleAutoTestCompute'
  server: 'AnsibleAutoTestCompute'
  nic: 'AnsibleAutoTestCompute'
  firewall_rule: SSH
  wait: true
  wait_timeout: '500'
  state: absent

```

&#x20; &#x20;

### Returned object

```json
{
    "changed": true,
    "failed": false,
    "action": "create",
    "firewall_rule": {
        "href": "https://api.ionos.com/cloudapi/v6/datacenters/f6e15460-e5eb-451a-9da7-08c9da65a179/servers/78ce195d-147b-48d8-a20e-57104b99badd/nics/6e9dd9af-5132-4f8d-a285-62c86956a5da/firewallrules/d48500c7-3483-455b-9f63-9c091a9c73a2",
        "id": "d48500c7-3483-455b-9f63-9c091a9c73a2",
        "metadata": {
            "created_by": "<USER_EMAIL>",
            "created_by_user_id": "<USER_ID>",
            "created_date": "2023-05-29T09:29:40+00:00",
            "etag": "de89018f9d0664828d9170c632db291a",
            "last_modified_by": "<USER_EMAIL>",
            "last_modified_by_user_id": "<USER_ID>",
            "last_modified_date": "2023-05-29T09:29:40+00:00",
            "state": "BUSY"
        },
        "properties": {
            "icmp_code": null,
            "icmp_type": null,
            "ip_version": null,
            "name": "SSH",
            "port_range_end": 24,
            "port_range_start": 22,
            "protocol": "TCP",
            "source_ip": null,
            "source_mac": "<MAC>",
            "target_ip": null,
            "type": null
        },
        "type": "firewall-rule"
    }
}

```

#### For more examples please check out the tests [here](https://github.com/ionos-cloud/module-ansible/tree/master/tests/compute-engine).

&#x20;

&#x20;

## state: **present**

```yaml
  
name: Create a firewall rule
ionoscloudsdk.ionoscloud.firewall_rule:
  datacenter: 'AnsibleAutoTestCompute'
  server: 'AnsibleAutoTestCompute'
  nic: 'AnsibleAutoTestCompute'
  name: SSH
  protocol: ICMPv6
  source_mac: 01:23:45:67:89:00
  ip_version: IPv6
  state: present

```

#### Available parameters for state **present**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The datacenter name or UUID in which to operate.</td></tr><tr><td>server<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The server name or UUID.</td></tr><tr><td>nic<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The NIC name or UUID.</td></tr><tr><td>name<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The name of the resource.</td></tr><tr><td>protocol<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The protocol for the rule. Property cannot be modified after it is created (disallowed in update requests).<br>Options: ['TCP', 'UDP', 'ICMP', 'ICMPv6', 'GRE', 'VRRP', 'ESP', 'AH', 'ANY']</td></tr><tr><td>source_mac<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Only traffic originating from the respective MAC address is allowed. Valid format: aa:bb:cc:dd:ee:ff. Value null allows traffic from any MAC address.</td></tr><tr><td>source_ip<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Only traffic originating from the respective IP address (or CIDR block) is allowed. Value null allows traffic from any IP address (according to the selected ipVersion).</td></tr><tr><td>target_ip<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>If the target NIC has multiple IP addresses, only the traffic directed to the respective IP address (or CIDR block) of the NIC is allowed. Value null allows traffic to any target IP address (according to the selected ipVersion).</td></tr><tr><td>port_range_start<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>Defines the start range of the allowed port (from 1 to 65535) if protocol TCP or UDP is chosen. Leave portRangeStart and portRangeEnd value null to allow all ports.</td></tr><tr><td>port_range_end<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>Defines the end range of the allowed port (from 1 to 65535) if the protocol TCP or UDP is chosen. Leave portRangeStart and portRangeEnd null to allow all ports.</td></tr><tr><td>icmp_type<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>Defines the allowed type (from 0 to 254) if the protocol ICMP or ICMPv6 is chosen. Value null allows all types.</td></tr><tr><td>icmp_code<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>Defines the allowed code (from 0 to 254) if protocol ICMP or ICMPv6 is chosen. Value null allows all codes.</td></tr><tr><td>ip_version<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The IP version for this rule. If sourceIp or targetIp are specified, you can omit this value - the IP version will then be deduced from the IP address(es) used; if you specify it anyway, it must match the specified IP address(es). If neither sourceIp nor targetIp are specified, this rule allows traffic only for the specified IP version. If neither sourceIp, targetIp nor ipVersion are specified, this rule will only allow IPv4 traffic.<br>Options: ['IPv4', 'IPv6']</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['present', 'absent', 'update']</td></tr></tbody></table>

&#x20;

&#x20;

## state: **absent**

```yaml
  
name: Remove firewall rule
ionoscloudsdk.ionoscloud.firewall_rule:
  datacenter: 'AnsibleAutoTestCompute'
  server: 'AnsibleAutoTestCompute'
  nic: 'AnsibleAutoTestCompute'
  firewall_rule: SSH
  wait: true
  wait_timeout: '500'
  state: absent

```

#### Available parameters for state **absent**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The datacenter name or UUID in which to operate.</td></tr><tr><td>server<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The server name or UUID.</td></tr><tr><td>nic<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The NIC name or UUID.</td></tr><tr><td>firewall_rule<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The Firewall Rule name or UUID.</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['present', 'absent', 'update']</td></tr></tbody></table>

&#x20;

&#x20;

## state: **update**

```yaml
  
name: Update firewall rule
ionoscloudsdk.ionoscloud.firewall_rule:
  datacenter: 'AnsibleAutoTestCompute'
  server: 'AnsibleAutoTestCompute'
  nic: 'AnsibleAutoTestCompute'
  firewall_rule: SSH
  port_range_start: 22
  port_range_end: 23
  state: update

```

#### Available parameters for state **update**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The datacenter name or UUID in which to operate.</td></tr><tr><td>server<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The server name or UUID.</td></tr><tr><td>nic<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The NIC name or UUID.</td></tr><tr><td>firewall_rule<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The Firewall Rule name or UUID.</td></tr><tr><td>name<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The name of the resource.</td></tr><tr><td>protocol<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The protocol for the rule. Property cannot be modified after it is created (disallowed in update requests).<br>Options: ['TCP', 'UDP', 'ICMP', 'ICMPv6', 'GRE', 'VRRP', 'ESP', 'AH', 'ANY']</td></tr><tr><td>source_mac<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Only traffic originating from the respective MAC address is allowed. Valid format: aa:bb:cc:dd:ee:ff. Value null allows traffic from any MAC address.</td></tr><tr><td>source_ip<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Only traffic originating from the respective IP address (or CIDR block) is allowed. Value null allows traffic from any IP address (according to the selected ipVersion).</td></tr><tr><td>target_ip<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>If the target NIC has multiple IP addresses, only the traffic directed to the respective IP address (or CIDR block) of the NIC is allowed. Value null allows traffic to any target IP address (according to the selected ipVersion).</td></tr><tr><td>port_range_start<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>Defines the start range of the allowed port (from 1 to 65535) if protocol TCP or UDP is chosen. Leave portRangeStart and portRangeEnd value null to allow all ports.</td></tr><tr><td>port_range_end<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>Defines the end range of the allowed port (from 1 to 65535) if the protocol TCP or UDP is chosen. Leave portRangeStart and portRangeEnd null to allow all ports.</td></tr><tr><td>icmp_type<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>Defines the allowed type (from 0 to 254) if the protocol ICMP or ICMPv6 is chosen. Value null allows all types.</td></tr><tr><td>icmp_code<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>Defines the allowed code (from 0 to 254) if protocol ICMP or ICMPv6 is chosen. Value null allows all codes.</td></tr><tr><td>ip_version<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The IP version for this rule. If sourceIp or targetIp are specified, you can omit this value - the IP version will then be deduced from the IP address(es) used; if you specify it anyway, it must match the specified IP address(es). If neither sourceIp nor targetIp are specified, this rule allows traffic only for the specified IP version. If neither sourceIp, targetIp nor ipVersion are specified, this rule will only allow IPv4 traffic.<br>Options: ['IPv4', 'IPv6']</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['present', 'absent', 'update']</td></tr></tbody></table>

&#x20;

&#x20;


# Image

## image

This is a simple module that supports updating or removing Images. This module has a dependency on ionoscloud >= 6.0.2

### Example Syntax

```yaml
name: Update image
ionoscloudsdk.ionoscloud.image:
  image_id: 87fe5b95-05e4-11ee-a7cb-028794406dc9
  name: debian-11.7.0-amd64-netinst-renamed.iso
  description: An image used for testing the Ansible Module
  cpu_hot_plug: true
  cpu_hot_unplug: false
  ram_hot_plug: true
  ram_hot_unplug: true
  nic_hot_plug: true
  nic_hot_unplug: true
  disc_virtio_hot_plug: true
  disc_virtio_hot_unplug: true
  disc_scsi_hot_plug: true
  disc_scsi_hot_unplug: false
  licence_type: LINUX
  cloud_init: V1
  state: update
register: image_output

name: Delete image
ionoscloudsdk.ionoscloud.image:
  image_id: 916b10ea-be31-11eb-b909-c608708a73fa
  state: absent

```

&#x20; &#x20;

### Returned object

```json
{
    "changed": true,
    "failed": false,
    "action": "update",
    "image": {
        "href": "https://api.ionos.com/cloudapi/v6/images/87fe5b95-05e4-11ee-a7cb-028794406dc9",
        "id": "87fe5b95-05e4-11ee-a7cb-028794406dc9",
        "metadata": {
            "created_by": "<USER_EMAIL>",
            "created_by_user_id": "<USER_ID>",
            "created_date": "2023-06-08T10:09:18+00:00",
            "etag": "1a305d1a2beaabd6027d5ad4fe5940a8",
            "last_modified_by": "<USER_EMAIL>",
            "last_modified_by_user_id": "<USER_ID>",
            "last_modified_date": "2023-06-08T10:15:32+00:00",
            "state": "BUSY"
        },
        "properties": {
            "cloud_init": "V1",
            "cpu_hot_plug": true,
            "cpu_hot_unplug": false,
            "description": "An image used for testing the Ansible Module",
            "disc_scsi_hot_plug": true,
            "disc_scsi_hot_unplug": false,
            "disc_virtio_hot_plug": true,
            "disc_virtio_hot_unplug": true,
            "image_aliases": [],
            "image_type": "CDROM",
            "licence_type": "LINUX",
            "location": "de/fra",
            "name": "debian-11.7.0-amd64-netinst-renamed.iso",
            "nic_hot_plug": true,
            "nic_hot_unplug": true,
            "public": false,
            "ram_hot_plug": true,
            "ram_hot_unplug": true,
            "size": 0.39
        },
        "type": "image"
    }
}

```

#### For more examples please check out the tests [here](https://github.com/ionos-cloud/module-ansible/tree/master/tests/compute-engine).

&#x20;

&#x20;

## state: **absent**

```yaml
  name: Delete image
ionoscloudsdk.ionoscloud.image:
  image_id: 916b10ea-be31-11eb-b909-c608708a73fa
  state: absent

```

#### Available parameters for state **absent**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>image_id<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID of the image.</td></tr><tr><td>name<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The resource name.</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['absent', 'update']</td></tr></tbody></table>

&#x20;

&#x20;

## state: **update**

```yaml
  name: Update image
ionoscloudsdk.ionoscloud.image:
  image_id: 87fe5b95-05e4-11ee-a7cb-028794406dc9
  name: debian-11.7.0-amd64-netinst-renamed.iso
  description: An image used for testing the Ansible Module
  cpu_hot_plug: true
  cpu_hot_unplug: false
  ram_hot_plug: true
  ram_hot_unplug: true
  nic_hot_plug: true
  nic_hot_unplug: true
  disc_virtio_hot_plug: true
  disc_virtio_hot_unplug: true
  disc_scsi_hot_plug: true
  disc_scsi_hot_unplug: false
  licence_type: LINUX
  cloud_init: V1
  state: update
register: image_output

```

#### Available parameters for state **update**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>image_id<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID of the image.</td></tr><tr><td>name<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The resource name.</td></tr><tr><td>description<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Human-readable description.</td></tr><tr><td>cpu_hot_plug<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Hot-plug capable CPU (no reboot required).</td></tr><tr><td>cpu_hot_unplug<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Hot-unplug capable CPU (no reboot required).</td></tr><tr><td>ram_hot_plug<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Hot-plug capable RAM (no reboot required).</td></tr><tr><td>ram_hot_unplug<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Hot-unplug capable RAM (no reboot required).</td></tr><tr><td>nic_hot_plug<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Hot-plug capable NIC (no reboot required).</td></tr><tr><td>nic_hot_unplug<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Hot-unplug capable NIC (no reboot required).</td></tr><tr><td>disc_scsi_hot_plug<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Hot-plug capable SCSI drive (no reboot required).</td></tr><tr><td>disc_scsi_hot_unplug<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Hot-unplug capable SCSI drive (no reboot required). Not supported with Windows VMs.</td></tr><tr><td>disc_virtio_hot_plug<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Hot-plug capable Virt-IO drive (no reboot required).</td></tr><tr><td>disc_virtio_hot_unplug<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Hot-unplug capable Virt-IO drive (no reboot required). Not supported with Windows VMs.</td></tr><tr><td>licence_type<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The OS type of this image.</td></tr><tr><td>cloud_init<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Cloud init compatibility.</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['absent', 'update']</td></tr></tbody></table>

&#x20;

&#x20;


# IP Block

## ipblock

This module allows you to create or remove an IPBlock.

### Example Syntax

```yaml

name: Create ipblock
ionoscloudsdk.ionoscloud.ipblock:
  name: 'AnsibleAutoTestCompute'
  location: 'gb/lhr'
  size: 2
  state: present
register: response


name: Remove ipblock
ionoscloudsdk.ionoscloud.ipblock:
  ipblock: 'AnsibleAutoTestCompute'
  state: absent
register: delete_result

```

&#x20; &#x20;

### Returned object

```json
{
    "changed": true,
    "failed": false,
    "action": "create",
    "ipblock": {
        "href": "https://api.ionos.com/cloudapi/v6/ipblocks/0bce3fe3-67fd-4d7e-ba86-2e734ad2a79b",
        "id": "0bce3fe3-67fd-4d7e-ba86-2e734ad2a79b",
        "metadata": {
            "created_by": "<USER_EMAIL>",
            "created_by_user_id": "<USER_ID>",
            "created_date": "2023-05-29T11:45:10+00:00",
            "etag": "59558fb22d91e9d6d7a9750aba57fa47",
            "last_modified_by": "<USER_EMAIL>",
            "last_modified_by_user_id": "<USER_ID>",
            "last_modified_date": "2023-05-29T11:45:10+00:00",
            "state": "BUSY"
        },
        "properties": {
            "ip_consumers": [],
            "ips": [
                "<IP1>",
                "<IP2>"
            ],
            "location": "gb/lhr",
            "name": "AnsibleAutoTestCompute",
            "size": 2
        },
        "type": "ipblock"
    }
}

```

#### For more examples please check out the tests [here](https://github.com/ionos-cloud/module-ansible/tree/master/tests/compute-engine).

&#x20;

***NOTE:*** **If you are using a versions 7.0.0 and up**: modules can replace resources if certain set parameters differ from the results found in the API!

### Parameters that can trigger a resource replacement:

* size
* location &#x20;

## state: **present**

```yaml
  
name: Create ipblock
ionoscloudsdk.ionoscloud.ipblock:
  name: 'AnsibleAutoTestCompute'
  location: 'gb/lhr'
  size: 2
  state: present
register: response

```

#### Available parameters for state **present**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>name<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The name of the resource.</td></tr><tr><td>location<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>Location of that IP block. Property cannot be modified after it is created (disallowed in update requests).<br>Options: ['us/las', 'us/ewr', 'de/fra', 'de/fkb', 'de/txl', 'gb/lhr']</td></tr><tr><td>size<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>The size of the IP block.</td></tr><tr><td>allow_replace<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Boolean indicating if the resource should be recreated when the state cannot be reached in another way. This may be used to prevent resources from being deleted from specifying a different value to an immutable property. An error will be thrown instead<br>Default: False</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['present', 'absent']</td></tr></tbody></table>

&#x20;

&#x20;

## state: **absent**

```yaml
  
name: Remove ipblock
ionoscloudsdk.ionoscloud.ipblock:
  ipblock: 'AnsibleAutoTestCompute'
  state: absent
register: delete_result

```

#### Available parameters for state **absent**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>ipblock<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The name or ID of an existing IPBlock.</td></tr><tr><td>name<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The name of the resource.</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['present', 'absent']</td></tr></tbody></table>

&#x20;

&#x20;


# LAN

## lan

This module allows you to create or remove a LAN.

### Example Syntax

```yaml

name: Create LAN
ionoscloudsdk.ionoscloud.lan:
  datacenter: 'AnsibleAutoTestCompute'
  name: 'AnsibleAutoTestCompute'
  public: false
register: ionos_cloud_lan


name: Update LAN
ionoscloudsdk.ionoscloud.lan:
  datacenter: 'AnsibleAutoTestCompute'
  lan: 'AnsibleAutoTestCompute'
  pcc: ''
  state: update


name: Remove LAN
ionoscloudsdk.ionoscloud.lan:
  datacenter: 'AnsibleAutoTestCompute'
  lan: 'AnsibleAutoTestCompute'
  state: absent
  wait: true

```

&#x20; &#x20;

### Returned object

```json
{
    "changed": true,
    "failed": false,
    "action": "create",
    "lan": {
        "entities": null,
        "href": "https://api.ionos.com/cloudapi/v6/datacenters/f6e15460-e5eb-451a-9da7-08c9da65a179/lans/1",
        "id": "1",
        "metadata": {
            "created_by": "<USER_EMAIL>",
            "created_by_user_id": "<USER_ID>",
            "created_date": "2023-05-29T09:26:00+00:00",
            "etag": "5200f351d90b89ae0282b81a8da77efe",
            "last_modified_by": "<USER_EMAIL>",
            "last_modified_by_user_id": "<USER_ID>",
            "last_modified_date": "2023-05-29T09:26:00+00:00",
            "state": "BUSY"
        },
        "properties": {
            "ip_failover": null,
            "name": "AnsibleAutoTestCompute",
            "pcc": null,
            "public": true
        },
        "type": "lan"
    }
}

```

#### For more examples please check out the tests [here](https://github.com/ionos-cloud/module-ansible/tree/master/tests/compute-engine).

&#x20;

&#x20;

## state: **present**

```yaml
  
name: Create LAN
ionoscloudsdk.ionoscloud.lan:
  datacenter: 'AnsibleAutoTestCompute'
  name: 'AnsibleAutoTestCompute'
  public: false
register: ionos_cloud_lan

```

#### Available parameters for state **present**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The datacenter name or UUID in which to operate.</td></tr><tr><td>name<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The name of the resource.</td></tr><tr><td>pcc<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The unique identifier of the Cross Connect the LAN is connected to, if any. It needs to be ensured that IP addresses of the NICs of all LANs connected to a given Cross Connect is not duplicated and belongs to the same subnet range.</td></tr><tr><td>public<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Indicates if the LAN is connected to the internet or not.<br>Default: False</td></tr><tr><td>ipv6_cidr<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>For a GET request, this value is either 'null' or contains the LAN's /64 IPv6 CIDR block if this LAN is IPv6 enabled. For POST/PUT/PATCH requests, 'AUTO' will result in enabling this LAN for IPv6 and automatically assign a /64 IPv6 CIDR block to this LAN and /80 IPv6 CIDR blocks to the NICs and one /128 IPv6 address to each connected NIC. If you choose the IPv6 CIDR block for the LAN on your own, then you must provide a /64 block, which is inside the IPv6 CIDR block of the virtual datacenter and unique inside all LANs from this virtual datacenter. If you enable IPv6 on a LAN with NICs, those NICs will get a /80 IPv6 CIDR block and one IPv6 address assigned to each automatically, unless you specify them explicitly on the LAN and on the NICs. A virtual data center is limited to a maximum of 256 IPv6-enabled LANs.</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['present', 'absent', 'update']</td></tr></tbody></table>

&#x20;

&#x20;

## state: **absent**

```yaml
  
name: Remove LAN
ionoscloudsdk.ionoscloud.lan:
  datacenter: 'AnsibleAutoTestCompute'
  lan: 'AnsibleAutoTestCompute'
  state: absent
  wait: true

```

#### Available parameters for state **absent**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The datacenter name or UUID in which to operate.</td></tr><tr><td>lan<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The LAN name or UUID.</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['present', 'absent', 'update']</td></tr></tbody></table>

&#x20;

&#x20;

## state: **update**

```yaml
  
name: Update LAN
ionoscloudsdk.ionoscloud.lan:
  datacenter: 'AnsibleAutoTestCompute'
  lan: 'AnsibleAutoTestCompute'
  pcc: ''
  state: update

```

#### Available parameters for state **update**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The datacenter name or UUID in which to operate.</td></tr><tr><td>lan<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The LAN name or UUID.</td></tr><tr><td>name<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The name of the resource.</td></tr><tr><td>pcc<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The unique identifier of the Cross Connect the LAN is connected to, if any. It needs to be ensured that IP addresses of the NICs of all LANs connected to a given Cross Connect is not duplicated and belongs to the same subnet range.</td></tr><tr><td>ip_failover<br><mark style="color:blue;">list</mark></td><td align="center">False</td><td>IP failover configurations for lan</td></tr><tr><td>public<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Indicates if the LAN is connected to the internet or not.<br>Default: False</td></tr><tr><td>ipv6_cidr<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>For a GET request, this value is either 'null' or contains the LAN's /64 IPv6 CIDR block if this LAN is IPv6 enabled. For POST/PUT/PATCH requests, 'AUTO' will result in enabling this LAN for IPv6 and automatically assign a /64 IPv6 CIDR block to this LAN and /80 IPv6 CIDR blocks to the NICs and one /128 IPv6 address to each connected NIC. If you choose the IPv6 CIDR block for the LAN on your own, then you must provide a /64 block, which is inside the IPv6 CIDR block of the virtual datacenter and unique inside all LANs from this virtual datacenter. If you enable IPv6 on a LAN with NICs, those NICs will get a /80 IPv6 CIDR block and one IPv6 address assigned to each automatically, unless you specify them explicitly on the LAN and on the NICs. A virtual data center is limited to a maximum of 256 IPv6-enabled LANs.</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['present', 'absent', 'update']</td></tr></tbody></table>

&#x20;

&#x20;


# Flowlog

## nic\_flowlog

This is a simple module that supports creating or removing NIC Flowlogs. This module has a dependency on ionoscloud >= 6.0.2

### Example Syntax

```yaml

name: Create a nic flowlog
ionoscloudsdk.ionoscloud.nic_flowlog:
  name: 'AnsibleAutoTestCompute'
  action: ACCEPTED
  direction: INGRESS
  bucket: sdktest
  datacenter: ''
  server: ''
  nic: ''
register: flowlog_response


name: Update a nic flowlog
ionoscloudsdk.ionoscloud.nic_flowlog:
  name: 'AnsibleAutoTestCompute'
  action: ALL
  direction: INGRESS
  bucket: sdktest
  datacenter: ''
  server: ''
  nic: ''
  flowlog: ''
  state: update
register: flowlog_update_response


name: Delete a nic flowlog
ionoscloudsdk.ionoscloud.nic_flowlog:
  datacenter: ''
  server: ''
  nic: ''
  flowlog: ''
  name: 'AnsibleAutoTestCompute'
  state: absent
  wait: true
register: flowlog_delete_response

```

&#x20; &#x20;

### Returned object

```json
{
    "changed": true,
    "failed": false,
    "action": "create",
    "flowlog": {
        "href": "https://api.ionos.com/cloudapi/v6/datacenters/47724f5f-625d-46e3-8187-0fce19c74e5c/servers/4e55f7f3-78f2-46c0-9c61-8de00d7cd484/nics/c386eede-b756-441e-97a7-5de4da8518ed/flowlogs/37a775b2-4dad-418a-8cbd-0499ad34d713",
        "id": "37a775b2-4dad-418a-8cbd-0499ad34d713",
        "metadata": {
            "created_by": "<USER_EMAIL>",
            "created_by_user_id": "<USER_ID>",
            "created_date": "2023-06-06T14:06:00+00:00",
            "etag": "043560db87ade8f005d69efbec1eedea",
            "last_modified_by": "<USER_EMAIL>",
            "last_modified_by_user_id": "<USER_ID>",
            "last_modified_date": "2023-06-06T14:06:00+00:00",
            "state": "BUSY"
        },
        "properties": {
            "action": "ACCEPTED",
            "bucket": "sdktest",
            "direction": "INGRESS",
            "name": "AnsibleAutoTestCompute"
        },
        "type": "flow-log"
    }
}

```

#### For more examples please check out the tests [here](https://github.com/ionos-cloud/module-ansible/tree/master/tests/compute-engine).

&#x20;

&#x20;

## state: **present**

```yaml
  
name: Create a nic flowlog
ionoscloudsdk.ionoscloud.nic_flowlog:
  name: 'AnsibleAutoTestCompute'
  action: ACCEPTED
  direction: INGRESS
  bucket: sdktest
  datacenter: ''
  server: ''
  nic: ''
register: flowlog_response

```

#### Available parameters for state **present**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>name<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The resource name.</td></tr><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of the virtual datacenter.</td></tr><tr><td>server<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of the Server.</td></tr><tr><td>nic<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of the NIC.</td></tr><tr><td>action<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>Specifies the traffic action pattern.</td></tr><tr><td>direction<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>Specifies the traffic direction pattern.</td></tr><tr><td>bucket<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The bucket name of an existing IONOS CLOUD Object storage bucket.</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['present', 'absent', 'update']</td></tr></tbody></table>

&#x20;

&#x20;

## state: **absent**

```yaml
  
name: Delete a nic flowlog
ionoscloudsdk.ionoscloud.nic_flowlog:
  datacenter: ''
  server: ''
  nic: ''
  flowlog: ''
  name: 'AnsibleAutoTestCompute'
  state: absent
  wait: true
register: flowlog_delete_response

```

#### Available parameters for state **absent**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>flowlog<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of an existing Flowlog.</td></tr><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of the virtual datacenter.</td></tr><tr><td>server<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of the Server.</td></tr><tr><td>nic<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of the NIC.</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['present', 'absent', 'update']</td></tr></tbody></table>

&#x20;

&#x20;

## state: **update**

```yaml
  
name: Update a nic flowlog
ionoscloudsdk.ionoscloud.nic_flowlog:
  name: 'AnsibleAutoTestCompute'
  action: ALL
  direction: INGRESS
  bucket: sdktest
  datacenter: ''
  server: ''
  nic: ''
  flowlog: ''
  state: update
register: flowlog_update_response

```

#### Available parameters for state **update**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>name<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The resource name.</td></tr><tr><td>flowlog<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of an existing Flowlog.</td></tr><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of the virtual datacenter.</td></tr><tr><td>server<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of the Server.</td></tr><tr><td>nic<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of the NIC.</td></tr><tr><td>action<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Specifies the traffic action pattern.</td></tr><tr><td>direction<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Specifies the traffic direction pattern.</td></tr><tr><td>bucket<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The bucket name of an existing IONOS CLOUD Object storage bucket.</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['present', 'absent', 'update']</td></tr></tbody></table>

&#x20;

&#x20;


# NIC

## nic

This module allows you to create, update or remove a NIC.

### Example Syntax

```yaml

name: Create NIC
ionoscloudsdk.ionoscloud.nic:
  name: 'AnsibleAutoTestCompute'
  datacenter: 'AnsibleAutoTestCompute'
  server: 'AnsibleAutoTestCompute'
  lan: 2
  dhcp: true
  firewall_active: true
  ips:
  - 10.0.0.1
  wait: true
  wait_timeout: '500'
  state: present
register: ionos_cloud_nic


name: Update NIC
ionoscloudsdk.ionoscloud.nic:
  datacenter: 'AnsibleAutoTestCompute'
  server: 'AnsibleAutoTestCompute'
  name: new-nic
  nic: ''
  dhcp: false
  wait: true
  wait_timeout: '500'
  state: update
register: updated_nic


name: Remove NIC
ionoscloudsdk.ionoscloud.nic:
  nic: ''
  datacenter: 'AnsibleAutoTestCompute'
  server: 'AnsibleAutoTestCompute'
  wait: true
  wait_timeout: '500'
  state: absent

```

&#x20; &#x20;

### Returned object

```json
{
    "changed": true,
    "failed": false,
    "action": "create",
    "nic": {
        "entities": {
            "firewallrules": {
                "links": null,
                "href": "https://api.ionos.com/cloudapi/v6/datacenters/f6e15460-e5eb-451a-9da7-08c9da65a179/servers/78ce195d-147b-48d8-a20e-57104b99badd/nics/6e9dd9af-5132-4f8d-a285-62c86956a5da/firewallrules",
                "id": "6e9dd9af-5132-4f8d-a285-62c86956a5da/firewallrules",
                "items": null,
                "limit": null,
                "offset": null,
                "type": "collection"
            },
            "flowlogs": {
                "links": null,
                "href": "https://api.ionos.com/cloudapi/v6/datacenters/f6e15460-e5eb-451a-9da7-08c9da65a179/servers/78ce195d-147b-48d8-a20e-57104b99badd/nics/6e9dd9af-5132-4f8d-a285-62c86956a5da/flowlogs",
                "id": "6e9dd9af-5132-4f8d-a285-62c86956a5da/flowlogs",
                "items": null,
                "limit": null,
                "offset": null,
                "type": "collection"
            }
        },
        "href": "https://api.ionos.com/cloudapi/v6/datacenters/f6e15460-e5eb-451a-9da7-08c9da65a179/servers/78ce195d-147b-48d8-a20e-57104b99badd/nics/6e9dd9af-5132-4f8d-a285-62c86956a5da",
        "id": "6e9dd9af-5132-4f8d-a285-62c86956a5da",
        "metadata": {
            "created_by": "<USER_EMAIL>",
            "created_by_user_id": "<USER_ID>",
            "created_date": "2023-05-29T09:27:48+00:00",
            "etag": "758f25397e05ac5dace2c18fa851879e",
            "last_modified_by": "<USER_EMAIL>",
            "last_modified_by_user_id": "<USER_ID>",
            "last_modified_date": "2023-05-29T09:27:48+00:00",
            "state": "AVAILABLE"
        },
        "properties": {
            "device_number": null,
            "dhcp": true,
            "firewall_active": true,
            "firewall_type": "INGRESS",
            "ips": [
                "<IP>"
            ],
            "lan": 1,
            "mac": "<MAC>",
            "name": "AnsibleAutoTestCompute",
            "pci_slot": 6
        },
        "type": "nic"
    }
}

```

#### For more examples please check out the tests [here](https://github.com/ionos-cloud/module-ansible/tree/master/tests/compute-engine).

&#x20;

&#x20;

## state: **present**

```yaml
  
name: Create NIC
ionoscloudsdk.ionoscloud.nic:
  name: 'AnsibleAutoTestCompute'
  datacenter: 'AnsibleAutoTestCompute'
  server: 'AnsibleAutoTestCompute'
  lan: 2
  dhcp: true
  firewall_active: true
  ips:
  - 10.0.0.1
  wait: true
  wait_timeout: '500'
  state: present
register: ionos_cloud_nic

```

#### Available parameters for state **present**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>name<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The name of the resource.</td></tr><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The datacenter name or UUID in which to operate.</td></tr><tr><td>server<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The server name or UUID.</td></tr><tr><td>lan<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The LAN ID the NIC will be on. If the LAN ID does not exist, it will be implicitly created.</td></tr><tr><td>dhcp<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Indicates if the NIC will reserve an IP using DHCP.</td></tr><tr><td>dhcpv6<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Indicates if the NIC will receive an IPv6 using DHCP. It can be set to 'true' or 'false' only if this NIC is connected to an IPv6 enabled LAN.</td></tr><tr><td>firewall_active<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Activate or deactivate the firewall. By default, an active firewall without any defined rules will block all incoming network traffic except for the firewall rules that explicitly allows certain protocols, IP addresses and ports.</td></tr><tr><td>ips<br><mark style="color:blue;">list</mark></td><td align="center">False</td><td>Collection of IP addresses, assigned to the NIC. Explicitly assigned public IPs need to come from reserved IP blocks. Passing value null or empty array will assign an IP address automatically.</td></tr><tr><td>ipv6_ips<br><mark style="color:blue;">list</mark></td><td align="center">False</td><td>If this NIC is connected to an IPv6 enabled LAN then this property contains the IPv6 IP addresses of the NIC. The maximum number of IPv6 IP addresses per NIC is 50, if you need more, contact support. If you leave this property 'null' when adding a NIC, when changing the NIC's IPv6 CIDR block, when changing the LAN's IPv6 CIDR block or when moving the NIC to a different IPv6 enabled LAN, then we will automatically assign the same number of IPv6 addresses which you had before from the NICs new CIDR block. If you leave this property 'null' while not changing the CIDR block, the IPv6 IP addresses won't be changed either. You can also provide your own self choosen IPv6 addresses, which then must be inside the IPv6 CIDR block of this NIC.</td></tr><tr><td>ipv6_cidr<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>If this NIC is connected to an IPv6 enabled LAN then this property contains the /80 IPv6 CIDR block of the NIC. If you leave this property 'null' when adding a NIC to an IPv6-enabled LAN, then an IPv6 CIDR block will automatically be assigned to the NIC, but you can also specify an /80 IPv6 CIDR block for the NIC on your own, which must be inside the /64 IPv6 CIDR block of the LAN and unique. This value can only be set, if the LAN already has an IPv6 CIDR block assigned. An IPv6-enabled LAN is limited to a maximum of 65,536 NICs.</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['present', 'absent', 'update']</td></tr></tbody></table>

&#x20;

&#x20;

## state: **absent**

```yaml
  
name: Remove NIC
ionoscloudsdk.ionoscloud.nic:
  nic: ''
  datacenter: 'AnsibleAutoTestCompute'
  server: 'AnsibleAutoTestCompute'
  wait: true
  wait_timeout: '500'
  state: absent

```

#### Available parameters for state **absent**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>nic<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of an existing NIC.</td></tr><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The datacenter name or UUID in which to operate.</td></tr><tr><td>server<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The server name or UUID.</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['present', 'absent', 'update']</td></tr></tbody></table>

&#x20;

&#x20;

## state: **update**

```yaml
  
name: Update NIC
ionoscloudsdk.ionoscloud.nic:
  datacenter: 'AnsibleAutoTestCompute'
  server: 'AnsibleAutoTestCompute'
  name: new-nic
  nic: ''
  dhcp: false
  wait: true
  wait_timeout: '500'
  state: update
register: updated_nic

```

#### Available parameters for state **update**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>name<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The name of the resource.</td></tr><tr><td>nic<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of an existing NIC.</td></tr><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The datacenter name or UUID in which to operate.</td></tr><tr><td>server<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The server name or UUID.</td></tr><tr><td>lan<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The LAN ID the NIC will be on. If the LAN ID does not exist, it will be implicitly created.</td></tr><tr><td>dhcp<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Indicates if the NIC will reserve an IP using DHCP.</td></tr><tr><td>dhcpv6<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Indicates if the NIC will receive an IPv6 using DHCP. It can be set to 'true' or 'false' only if this NIC is connected to an IPv6 enabled LAN.</td></tr><tr><td>firewall_active<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Activate or deactivate the firewall. By default, an active firewall without any defined rules will block all incoming network traffic except for the firewall rules that explicitly allows certain protocols, IP addresses and ports.</td></tr><tr><td>ips<br><mark style="color:blue;">list</mark></td><td align="center">False</td><td>Collection of IP addresses, assigned to the NIC. Explicitly assigned public IPs need to come from reserved IP blocks. Passing value null or empty array will assign an IP address automatically.</td></tr><tr><td>ipv6_ips<br><mark style="color:blue;">list</mark></td><td align="center">False</td><td>If this NIC is connected to an IPv6 enabled LAN then this property contains the IPv6 IP addresses of the NIC. The maximum number of IPv6 IP addresses per NIC is 50, if you need more, contact support. If you leave this property 'null' when adding a NIC, when changing the NIC's IPv6 CIDR block, when changing the LAN's IPv6 CIDR block or when moving the NIC to a different IPv6 enabled LAN, then we will automatically assign the same number of IPv6 addresses which you had before from the NICs new CIDR block. If you leave this property 'null' while not changing the CIDR block, the IPv6 IP addresses won't be changed either. You can also provide your own self choosen IPv6 addresses, which then must be inside the IPv6 CIDR block of this NIC.</td></tr><tr><td>ipv6_cidr<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>If this NIC is connected to an IPv6 enabled LAN then this property contains the /80 IPv6 CIDR block of the NIC. If you leave this property 'null' when adding a NIC to an IPv6-enabled LAN, then an IPv6 CIDR block will automatically be assigned to the NIC, but you can also specify an /80 IPv6 CIDR block for the NIC on your own, which must be inside the /64 IPv6 CIDR block of the LAN and unique. This value can only be set, if the LAN already has an IPv6 CIDR block assigned. An IPv6-enabled LAN is limited to a maximum of 65,536 NICs.</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['present', 'absent', 'update']</td></tr></tbody></table>

&#x20;

&#x20;


# PCC

## pcc

This is a simple module that supports creating or removing Cross Connects. This module has a dependency on ionoscloud >= 6.0.2

### Example Syntax

```yaml

name: Create pcc
ionoscloudsdk.ionoscloud.pcc:
  name: 'AnsibleAutoTestCompute'
  description: 'Ansible Compute test description'
register: result


name: Update pcc
ionoscloudsdk.ionoscloud.pcc:
  pcc: 'AnsibleAutoTestCompute'
  name: RENAMED AnsibleAutoTestCompute
  description: 'Ansible Compute test description - RENAME'
  state: update


name: Remove pcc
ionoscloudsdk.ionoscloud.pcc:
  pcc: ''
  state: absent

```

&#x20; &#x20;

### Returned object

```json
{
    "changed": true,
    "failed": false,
    "action": "create",
    "pcc": {
        "href": "https://api.ionos.com/cloudapi/v6/pccs/9574d5dd-14be-4e4c-b9fb-962bdadc954d",
        "id": "9574d5dd-14be-4e4c-b9fb-962bdadc954d",
        "metadata": {
            "created_by": "<USER_EMAIL>",
            "created_by_user_id": null,
            "created_date": "2023-05-29T12:52:28+00:00",
            "etag": "90244ee1b3bb5db489f5e25999ee177d",
            "last_modified_by": "<USER_EMAIL>",
            "last_modified_by_user_id": null,
            "last_modified_date": "2023-05-29T12:52:28+00:00",
            "state": "BUSY"
        },
        "properties": {
            "connectable_datacenters": [],
            "description": "Ansible Compute test description",
            "name": "AnsibleAutoTestCompute",
            "peers": []
        },
        "type": "pcc"
    }
}

```

#### For more examples please check out the tests [here](https://github.com/ionos-cloud/module-ansible/tree/master/tests/compute-engine).

&#x20;

&#x20;

## state: **present**

```yaml
  
name: Create pcc
ionoscloudsdk.ionoscloud.pcc:
  name: 'AnsibleAutoTestCompute'
  description: 'Ansible Compute test description'
register: result

```

#### Available parameters for state **present**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>name<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The name of the Cross Connect.</td></tr><tr><td>description<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>Human-readable description of the Cross Connect.</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['present', 'absent', 'update']</td></tr></tbody></table>

&#x20;

&#x20;

## state: **absent**

```yaml
  
name: Remove pcc
ionoscloudsdk.ionoscloud.pcc:
  pcc: ''
  state: absent

```

#### Available parameters for state **absent**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>pcc<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of an existing PCC.</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['present', 'absent', 'update']</td></tr></tbody></table>

&#x20;

&#x20;

## state: **update**

```yaml
  
name: Update pcc
ionoscloudsdk.ionoscloud.pcc:
  pcc: 'AnsibleAutoTestCompute'
  name: RENAMED AnsibleAutoTestCompute
  description: 'Ansible Compute test description - RENAME'
  state: update

```

#### Available parameters for state **update**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>name<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The name of the Cross Connect.</td></tr><tr><td>pcc<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of an existing PCC.</td></tr><tr><td>description<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Human-readable description of the Cross Connect.</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['present', 'absent', 'update']</td></tr></tbody></table>

&#x20;

&#x20;


# Server

## server

Create, update, destroy, update, start, stop, and reboot a Ionos virtual machine. When the virtual machine is created it can optionally wait for it to be 'running' before returning. The CUBE functionality of the server module is DEPRECATED. Please use the new cube\_server module for operations with CUBE servers.

### Example Syntax

```yaml

name: Provision two servers
ionoscloudsdk.ionoscloud.server:
  datacenter: 'AnsibleAutoTestCompute'
  name: 'AnsibleAutoTestCompute %02d'
  cores: 1
  ram: 1024
  availability_zone: ZONE_1
  lan: 'AnsibleAutoTestCompute'
  volume_availability_zone: ZONE_3
  volume_size: 20
  cpu_family: INTEL_SKYLAKE
  disk_type: SSD Standard
  image: 'ubuntu:latest'
  image_password: '{{ lookup('ansible.builtin.password', '/dev/null chars=ascii_letters,digits') }}'
  location: 'gb/lhr'
  user_data: ''
  count: 2
  remove_boot_volume: true
  wait: true
  wait_timeout: '500'
  state: present
register: server_create_result


name: Update servers
ionoscloudsdk.ionoscloud.server:
  datacenter: 'AnsibleAutoTestCompute'
  instance_ids:
  - 'AnsibleAutoTestCompute 01'
  - 'AnsibleAutoTestCompute 02'
  cores: 2
  cpu_family: INTEL_SKYLAKE
  ram: 2048
  wait_timeout: '500'
  state: update


name: Remove servers
ionoscloudsdk.ionoscloud.server:
  datacenter: 'AnsibleAutoTestCompute'
  instance_ids:
  - 'AnsibleAutoTestCompute'
  - 'AnsibleAutoTestCompute 02'
  remove_boot_volume: true
  wait_timeout: '500'
  state: absent


name: Start servers
ionoscloudsdk.ionoscloud.server:
  datacenter: 'AnsibleAutoTestCompute'
  instance_ids:
  - 'AnsibleAutoTestCompute'
  - 'AnsibleAutoTestCompute 02'
  wait_timeout: '500'
  state: running


name: Stop servers
ionoscloudsdk.ionoscloud.server:
  datacenter: 'AnsibleAutoTestCompute'
  instance_ids:
  - 'AnsibleAutoTestCompute'
  - 'AnsibleAutoTestCompute 02'
  wait_timeout: '500'
  state: stopped

```

&#x20; &#x20;

### Returned object

```json
{
    "changed": false,
    "failed": false,
    "machines": [
        {
            "entities": {
                "cdroms": {
                    "links": null,
                    "href": "https://api.ionos.com/cloudapi/v6/datacenters/f6e15460-e5eb-451a-9da7-08c9da65a179/servers/78ce195d-147b-48d8-a20e-57104b99badd/cdroms",
                    "id": "78ce195d-147b-48d8-a20e-57104b99badd/cdroms",
                    "items": null,
                    "limit": null,
                    "offset": null,
                    "type": "collection"
                },
                "nics": {
                    "links": null,
                    "href": "https://api.ionos.com/cloudapi/v6/datacenters/f6e15460-e5eb-451a-9da7-08c9da65a179/servers/78ce195d-147b-48d8-a20e-57104b99badd/nics",
                    "id": "78ce195d-147b-48d8-a20e-57104b99badd/nics",
                    "items": null,
                    "limit": null,
                    "offset": null,
                    "type": "collection"
                },
                "volumes": {
                    "links": null,
                    "href": "https://api.ionos.com/cloudapi/v6/datacenters/f6e15460-e5eb-451a-9da7-08c9da65a179/servers/78ce195d-147b-48d8-a20e-57104b99badd/volumes",
                    "id": "78ce195d-147b-48d8-a20e-57104b99badd/volumes",
                    "items": null,
                    "limit": null,
                    "offset": null,
                    "type": "collection"
                }
            },
            "href": "https://api.ionos.com/cloudapi/v6/datacenters/f6e15460-e5eb-451a-9da7-08c9da65a179/servers/78ce195d-147b-48d8-a20e-57104b99badd",
            "id": "78ce195d-147b-48d8-a20e-57104b99badd",
            "metadata": {
                "created_by": "<USER_EMAIL>",
                "created_by_user_id": "<USER_ID>",
                "created_date": "2023-05-29T09:17:01+00:00",
                "etag": "f9b2094caee723ec45475a17c223ddd2",
                "last_modified_by": "<USER_EMAIL>",
                "last_modified_by_user_id": "<USER_ID>",
                "last_modified_date": "2023-05-29T09:17:01+00:00",
                "state": "AVAILABLE"
            },
            "properties": {
                "availability_zone": "AUTO",
                "boot_cdrom": null,
                "boot_volume": {
                    "href": "https://api.ionos.com/cloudapi/v6/datacenters/f6e15460-e5eb-451a-9da7-08c9da65a179/volumes/4e9d988c-d4d8-4de1-a325-7f1a7b0ea77f",
                    "id": "4e9d988c-d4d8-4de1-a325-7f1a7b0ea77f",
                    "type": "volume"
                },
                "cores": 1,
                "cpu_family": "INTEL_SKYLAKE",
                "name": "AnsibleAutoTestCompute",
                "ram": 2048,
                "template_uuid": null,
                "type": "ENTERPRISE",
                "vm_state": "RUNNING"
            },
            "type": "server"
        }
    ],
    "action": "create"
}

```

#### For more examples please check out the tests [here](https://github.com/ionos-cloud/module-ansible/tree/master/tests/compute-engine/README.md).

&#x20;

&#x20;

## state: **running**

```yaml
  
name: Start servers
ionoscloudsdk.ionoscloud.server:
  datacenter: 'AnsibleAutoTestCompute'
  instance_ids:
  - 'AnsibleAutoTestCompute'
  - 'AnsibleAutoTestCompute 02'
  wait_timeout: '500'
  state: running

```

#### Available parameters for state **running**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The datacenter to provision this virtual machine.</td></tr><tr><td>instance_ids<br><mark style="color:blue;">list</mark></td><td align="center">False</td><td>list of instance ids. Should only contain one ID if renaming in update state<br>Default:</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['running', 'stopped', 'absent', 'present', 'update']</td></tr></tbody></table>

&#x20;

&#x20;

## state: **stopped**

```yaml
  
name: Stop servers
ionoscloudsdk.ionoscloud.server:
  datacenter: 'AnsibleAutoTestCompute'
  instance_ids:
  - 'AnsibleAutoTestCompute'
  - 'AnsibleAutoTestCompute 02'
  wait_timeout: '500'
  state: stopped

```

#### Available parameters for state **stopped**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The datacenter to provision this virtual machine.</td></tr><tr><td>instance_ids<br><mark style="color:blue;">list</mark></td><td align="center">False</td><td>list of instance ids. Should only contain one ID if renaming in update state<br>Default:</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['running', 'stopped', 'absent', 'present', 'update']</td></tr></tbody></table>

&#x20;

&#x20;

## state: **absent**

```yaml
  
name: Remove servers
ionoscloudsdk.ionoscloud.server:
  datacenter: 'AnsibleAutoTestCompute'
  instance_ids:
  - 'AnsibleAutoTestCompute'
  - 'AnsibleAutoTestCompute 02'
  remove_boot_volume: true
  wait_timeout: '500'
  state: absent

```

#### Available parameters for state **absent**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>name<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The name of the resource.</td></tr><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The datacenter to provision this virtual machine.</td></tr><tr><td>instance_ids<br><mark style="color:blue;">list</mark></td><td align="center">False</td><td>list of instance ids. Should only contain one ID if renaming in update state<br>Default:</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['running', 'stopped', 'absent', 'present', 'update']</td></tr></tbody></table>

&#x20;

&#x20;

## state: **present**

```yaml
  
name: Provision two servers
ionoscloudsdk.ionoscloud.server:
  datacenter: 'AnsibleAutoTestCompute'
  name: 'AnsibleAutoTestCompute %02d'
  cores: 1
  ram: 1024
  availability_zone: ZONE_1
  lan: 'AnsibleAutoTestCompute'
  volume_availability_zone: ZONE_3
  volume_size: 20
  cpu_family: INTEL_SKYLAKE
  disk_type: SSD Standard
  image: 'ubuntu:latest'
  image_password: '{{ lookup('ansible.builtin.password', '/dev/null chars=ascii_letters,digits') }}'
  location: 'gb/lhr'
  user_data: ''
  count: 2
  remove_boot_volume: true
  wait: true
  wait_timeout: '500'
  state: present
register: server_create_result

```

#### Available parameters for state **present**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>name<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The name of the resource.</td></tr><tr><td>assign_public_ip<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>This will assign the machine to the public LAN. If no LAN exists with public Internet access it is created.<br>Default: False<br>Options: [True, False]</td></tr><tr><td>image<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The image alias or ID for creating the virtual machine.</td></tr><tr><td>image_password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Password set for the administrative user.</td></tr><tr><td>ssh_keys<br><mark style="color:blue;">list</mark></td><td align="center">False</td><td>Public SSH keys allowing access to the virtual machine.<br>Default:</td></tr><tr><td>user_data<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The cloud-init configuration for the volume as base64 encoded string.</td></tr><tr><td>volume_availability_zone<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The storage availability zone assigned to the volume.<br>Options: ['AUTO', 'ZONE_1', 'ZONE_2', 'ZONE_3']</td></tr><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The datacenter to provision this virtual machine.</td></tr><tr><td>cores<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>The total number of cores for the server. It can not be supplied for the VMs that have to be created based on templates. For servers with Confidential Computing enabled, the number of cores must match the amount of cores required by the Confidential Computing image, and this field is immutable once the server has been created — update requests attempting to change it will be rejected.<br>Default: 2</td></tr><tr><td>ram<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>The memory size for the server in MB, such as 2048. Size must be specified in multiples of 256 MB with a minimum of 256 MB; however, if you set ramHotPlug to TRUE then you must use a minimum of 1024 MB. If you set the RAM size more than 240GB, then ramHotPlug will be set to FALSE and can not be set to TRUE unless RAM size not set to less than 240GB. It can not be supplied for the VMs that have to be created based on templates. For servers with Confidential Computing enabled, this field is immutable once the server has been created — update requests attempting to change it will be rejected.<br>Default: 2048</td></tr><tr><td>cpu_family<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>CPU architecture on which server gets provisioned; not all CPU architectures are available in all datacenter regions; available CPU architectures can be retrieved from the datacenter resource; must not be provided for CUBE and VCPU servers. If the field is omitted from the request or the value is empty or null, an available CPU architecture will be automatically selected. This field must not be supplied when creating a server with Confidential Computing enabled (i.e. when one of the attached volumes uses a confidential computing image); in that case the CPU family is determined by the image and is selected automatically. On servers with Confidential Computing enabled this field is also immutable — update requests attempting to change it will be rejected.<br>Options: ['INTEL_XEON', 'INTEL_SKYLAKE', 'INTEL_ICELAKE', 'AMD_EPYC', 'INTEL_SIERRAFOREST']</td></tr><tr><td>nic_multi_queue<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Activate or deactivate the Multi Queue feature on all NICs of this server. This feature is beneficial to enable when the NICs are experiencing performance issues (e.g. low throughput). Toggling this feature will also initiate a restart of the server. If the specified value is `true`, the feature will be activated; if it is not specified or set to `false`, the feature will be deactivated. It is not allowed for servers of type Cube.</td></tr><tr><td>availability_zone<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The availability zone in which the server should be provisioned. For CUBE and GPU servers, the only value accepted is 'AUTO'. For servers with Confidential Computing enabled, this field is immutable once the server has been created — update requests attempting to change it will be rejected.<br>Default: AUTO<br>Options: ['AUTO', 'ZONE_1', 'ZONE_2']</td></tr><tr><td>volume_size<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>The size in GB of the boot volume.<br>Default: 10</td></tr><tr><td>bus<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The bus type for the volume.<br>Default: VIRTIO<br>Options: ['IDE', 'VIRTIO']</td></tr><tr><td>count<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>The number of virtual machines to create.<br>Default: 1</td></tr><tr><td>location<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The datacenter location. Use only if you want to create the Datacenter or else this value is ignored.<br>Default: us/las<br>Options: ['us/las', 'us/ewr', 'de/fra', 'de/fra/1', 'de/fra/2', 'de/fkb', 'de/txl', 'gb/lhr', 'es/vit', 'fr/par', 'us/mci']</td></tr><tr><td>lan<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The ID or name of the LAN you wish to add the servers to (can be a string or a number).</td></tr><tr><td>nat<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Boolean value indicating if the private IP address has outbound access to the public Internet.<br>Default: False<br>Options: [True, False]</td></tr><tr><td>remove_boot_volume<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Remove the bootVolume of the virtual machine you're destroying.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>disk_type<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The disk type for the volume.<br>Default: HDD<br>Options: ['HDD', 'SSD', 'SSD Standard', 'SSD Premium', 'DAS', 'ESSENTIAL', 'BALANCED', 'PERFORMANCE']</td></tr><tr><td>nic_ips<br><mark style="color:blue;">list</mark></td><td align="center">False</td><td>The list of IPS for the NIC.</td></tr><tr><td>boot_volume<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Reference to a volume used as boot device. If the server has a volume with a Confidential Computing image, that volume — and only that volume — is eligible as the boot volume. Setting `bootVolume` to any other volume is rejected. If `bootVolume` is not provided on a server that has a Confidential Computing volume, that volume is automatically selected as the boot device. On servers with Confidential Computing enabled this field is immutable once the server has been created — update requests attempting to change it will be rejected.</td></tr><tr><td>boot_cdrom<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Reference to a CD-ROM used as boot device. Forbidden when the server has a volume whose image is a Confidential Computing image: such a server must boot from that volume and cannot boot from a CD-ROM. On servers with Confidential Computing enabled this field is immutable — update requests attempting to change it will be rejected.</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['running', 'stopped', 'absent', 'present', 'update']</td></tr></tbody></table>

&#x20;

&#x20;

## state: **update**

```yaml
  
name: Update servers
ionoscloudsdk.ionoscloud.server:
  datacenter: 'AnsibleAutoTestCompute'
  instance_ids:
  - 'AnsibleAutoTestCompute 01'
  - 'AnsibleAutoTestCompute 02'
  cores: 2
  cpu_family: INTEL_SKYLAKE
  ram: 2048
  wait_timeout: '500'
  state: update

```

#### Available parameters for state **update**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>name<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The name of the resource.</td></tr><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The datacenter to provision this virtual machine.</td></tr><tr><td>cores<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>The total number of cores for the server. It can not be supplied for the VMs that have to be created based on templates. For servers with Confidential Computing enabled, the number of cores must match the amount of cores required by the Confidential Computing image, and this field is immutable once the server has been created — update requests attempting to change it will be rejected.<br>Default: 2</td></tr><tr><td>ram<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>The memory size for the server in MB, such as 2048. Size must be specified in multiples of 256 MB with a minimum of 256 MB; however, if you set ramHotPlug to TRUE then you must use a minimum of 1024 MB. If you set the RAM size more than 240GB, then ramHotPlug will be set to FALSE and can not be set to TRUE unless RAM size not set to less than 240GB. It can not be supplied for the VMs that have to be created based on templates. For servers with Confidential Computing enabled, this field is immutable once the server has been created — update requests attempting to change it will be rejected.<br>Default: 2048</td></tr><tr><td>instance_ids<br><mark style="color:blue;">list</mark></td><td align="center">False</td><td>list of instance ids. Should only contain one ID if renaming in update state<br>Default:</td></tr><tr><td>boot_volume<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Reference to a volume used as boot device. If the server has a volume with a Confidential Computing image, that volume — and only that volume — is eligible as the boot volume. Setting `bootVolume` to any other volume is rejected. If `bootVolume` is not provided on a server that has a Confidential Computing volume, that volume is automatically selected as the boot device. On servers with Confidential Computing enabled this field is immutable once the server has been created — update requests attempting to change it will be rejected.</td></tr><tr><td>boot_cdrom<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Reference to a CD-ROM used as boot device. Forbidden when the server has a volume whose image is a Confidential Computing image: such a server must boot from that volume and cannot boot from a CD-ROM. On servers with Confidential Computing enabled this field is immutable — update requests attempting to change it will be rejected.</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['running', 'stopped', 'absent', 'present', 'update']</td></tr></tbody></table>

&#x20;

&#x20;


# Snapshot

## snapshot

This module allows you to create or remove a snapshot.

### Example Syntax

```yaml

name: Create snapshot
ionoscloudsdk.ionoscloud.snapshot:
  datacenter: 'AnsibleAutoTestCompute'
  volume: 'AnsibleAutoTestCompute'
  name: 'AnsibleAutoTestCompute'
  description: Ansible test snapshot
  wait_timeout: 600
register: result


name: Update snapshot
ionoscloudsdk.ionoscloud.snapshot:
  snapshot: 'AnsibleAutoTestCompute'
  description: Ansible test snapshot - RENAME
  state: update


name: Restore snapshot
ionoscloudsdk.ionoscloud.snapshot:
  datacenter: 'AnsibleAutoTestCompute'
  volume: 'AnsibleAutoTestCompute'
  snapshot: 'AnsibleAutoTestCompute'
  state: restore


name: Delete snapshot
ionoscloudsdk.ionoscloud.snapshot:
  snapshot: 'AnsibleAutoTestCompute'
  wait_timeout: 600
  state: absent

```

&#x20; &#x20;

### Returned object

```json
{
    "changed": true,
    "failed": false,
    "action": "create",
    "snapshot": {
        "href": "https://api.ionos.com/cloudapi/v6/snapshots/c77c9be7-fb6d-4747-ac3d-a8489d8499d1",
        "id": "c77c9be7-fb6d-4747-ac3d-a8489d8499d1",
        "metadata": {
            "created_by": "<USER_EMAIL>",
            "created_by_user_id": "<USER_ID>",
            "created_date": "2023-05-29T12:57:58+00:00",
            "etag": "f47933bc5bead5ca05821105dc943e9f",
            "last_modified_by": "<USER_EMAIL>",
            "last_modified_by_user_id": "<USER_ID>",
            "last_modified_date": "2023-05-29T12:57:58+00:00",
            "state": "BUSY"
        },
        "properties": {
            "cpu_hot_plug": false,
            "cpu_hot_unplug": false,
            "description": "Ansible test snapshot",
            "disc_scsi_hot_plug": false,
            "disc_scsi_hot_unplug": false,
            "disc_virtio_hot_plug": false,
            "disc_virtio_hot_unplug": false,
            "licence_type": "UNKNOWN",
            "location": "gb/lhr",
            "name": "AnsibleAutoTestCompute",
            "nic_hot_plug": false,
            "nic_hot_unplug": false,
            "ram_hot_plug": false,
            "ram_hot_unplug": false,
            "sec_auth_protection": false,
            "size": 10.0
        },
        "type": "snapshot"
    }
}

```

#### For more examples please check out the tests [here](https://github.com/ionos-cloud/module-ansible/tree/master/tests/compute-engine).

&#x20;

&#x20;

## state: **present**

```yaml
  
name: Create snapshot
ionoscloudsdk.ionoscloud.snapshot:
  datacenter: 'AnsibleAutoTestCompute'
  volume: 'AnsibleAutoTestCompute'
  name: 'AnsibleAutoTestCompute'
  description: Ansible test snapshot
  wait_timeout: 600
register: result

```

#### Available parameters for state **present**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The datacenter in which the volumes reside.</td></tr><tr><td>volume<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The name or UUID of the volume.</td></tr><tr><td>description<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Human-readable description.</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['present', 'absent', 'update', 'restore']</td></tr></tbody></table>

&#x20;

&#x20;

## state: **absent**

```yaml
  
name: Delete snapshot
ionoscloudsdk.ionoscloud.snapshot:
  snapshot: 'AnsibleAutoTestCompute'
  wait_timeout: 600
  state: absent

```

#### Available parameters for state **absent**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>snapshot<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of an existing snapshot.</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['present', 'absent', 'update', 'restore']</td></tr></tbody></table>

&#x20;

&#x20;

## state: **update**

```yaml
  
name: Update snapshot
ionoscloudsdk.ionoscloud.snapshot:
  snapshot: 'AnsibleAutoTestCompute'
  description: Ansible test snapshot - RENAME
  state: update

```

#### Available parameters for state **update**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>snapshot<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of an existing snapshot.</td></tr><tr><td>licence_type<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>OS type of this snapshot<br>Options: ['UNKNOWN', 'WINDOWS', 'WINDOWS2016', 'WINDOWS2022', 'RHEL', 'LINUX', 'OTHER']</td></tr><tr><td>cpu_hot_plug<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Hot-plug capable CPU (no reboot required).</td></tr><tr><td>cpu_hot_unplug<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Hot-unplug capable CPU (no reboot required).</td></tr><tr><td>ram_hot_plug<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Hot-plug capable RAM (no reboot required).</td></tr><tr><td>ram_hot_unplug<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Hot-unplug capable RAM (no reboot required).</td></tr><tr><td>nic_hot_plug<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Hot-plug capable NIC (no reboot required).</td></tr><tr><td>nic_hot_unplug<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Hot-unplug capable NIC (no reboot required).</td></tr><tr><td>disc_scsi_hot_plug<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Hot-plug capable SCSI drive (no reboot required).</td></tr><tr><td>disc_scsi_hot_unplug<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Is capable of SCSI drive hot unplug (no reboot required). This works only for non-Windows virtual Machines.</td></tr><tr><td>disc_virtio_hot_plug<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Hot-plug capable Virt-IO drive (no reboot required).</td></tr><tr><td>disc_virtio_hot_unplug<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Hot-unplug capable Virt-IO drive (no reboot required). Not supported with Windows VMs.</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['present', 'absent', 'update', 'restore']</td></tr></tbody></table>

&#x20;

&#x20;

## state: **restore**

```yaml
  
name: Restore snapshot
ionoscloudsdk.ionoscloud.snapshot:
  datacenter: 'AnsibleAutoTestCompute'
  volume: 'AnsibleAutoTestCompute'
  snapshot: 'AnsibleAutoTestCompute'
  state: restore

```

#### Available parameters for state **restore**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The datacenter in which the volumes reside.</td></tr><tr><td>volume<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The name or UUID of the volume.</td></tr><tr><td>snapshot<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The ID or name of an existing snapshot.</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['present', 'absent', 'update', 'restore']</td></tr></tbody></table>

&#x20;

&#x20;


# Volume

## volume

Allows you to create, update or remove a volume from a Ionos datacenter.

### Example Syntax

```yaml

name: Create volumes
ionoscloudsdk.ionoscloud.volume:
  datacenter: 'AnsibleAutoTestCompute'
  name: 'AnsibleAutoTestCompute %02d'
  disk_type: SSD Premium
  image: 'ubuntu:latest'
  image_password: '{{ lookup('ansible.builtin.password', '/dev/null chars=ascii_letters,digits') }}'
  count: 2
  size: 20
  availability_zone: AUTO
  cpu_hot_plug: false
  ram_hot_plug: true
  nic_hot_plug: true
  nic_hot_unplug: true
  disc_virtio_hot_plug: true
  disc_virtio_hot_unplug: true
  wait_timeout: 600
  wait: true
  state: present
register: volume_create_response


name: Update no change
ionoscloudsdk.ionoscloud.volume:
  datacenter: 'AnsibleAutoTestCompute'
  instance_ids:
  - 'AnsibleAutoTestCompute 01'
  disk_type: SSD Premium
  size: 20
  availability_zone: AUTO
  image: ''
  ram_hot_plug: true
  nic_hot_plug: true
  nic_hot_unplug: true
  disc_virtio_hot_plug: true
  disc_virtio_hot_unplug: true
  allow_replace: false
  wait_timeout: 600
  wait: true
  state: update
register: volume_create_response_nochange


name: Delete volumes
ionoscloudsdk.ionoscloud.volume:
  datacenter: 'AnsibleAutoTestCompute'
  instance_ids:
  - 'AnsibleAutoTestCompute modified'
  - 'AnsibleAutoTestCompute 02'
  wait_timeout: 600
  state: absent

```

&#x20; &#x20;

### Returned object

```json
{
    "changed": true,
    "failed": false,
    "volumes": [
        {
            "href": "https://api.ionos.com/cloudapi/v6/datacenters/ea545f2e-4c15-4be7-8fb8-867fb6e9d330/volumes/9be90788-1b11-4d1b-bfb3-857f0c7bd5a3",
            "id": "9be90788-1b11-4d1b-bfb3-857f0c7bd5a3",
            "metadata": {
                "created_by": "<USER_EMAIL>",
                "created_by_user_id": "<USER_ID>",
                "created_date": "2023-05-29T09:43:18+00:00",
                "etag": "1e8b91b7c574e42452b1628408959166",
                "last_modified_by": "<USER_EMAIL>",
                "last_modified_by_user_id": "<USER_ID>",
                "last_modified_date": "2023-05-29T09:43:18+00:00",
                "state": "BUSY"
            },
            "properties": {
                "availability_zone": null,
                "backupunit_id": null,
                "boot_order": "AUTO",
                "boot_server": null,
                "bus": "VIRTIO",
                "cpu_hot_plug": false,
                "device_number": null,
                "disc_virtio_hot_plug": false,
                "disc_virtio_hot_unplug": false,
                "image": null,
                "image_alias": null,
                "image_password": null,
                "licence_type": "OTHER",
                "name": "AnsibleAutoTestCompute-data",
                "nic_hot_plug": false,
                "nic_hot_unplug": false,
                "pci_slot": null,
                "ram_hot_plug": false,
                "size": 20.0,
                "ssh_keys": [],
                "type": "HDD",
                "user_data": null
            },
            "type": "volume"
        }
    ],
    "action": "create",
    "instance_ids": [
        "9be90788-1b11-4d1b-bfb3-857f0c7bd5a3"
    ]
}

```

#### For more examples please check out the tests [here](https://github.com/ionos-cloud/module-ansible/tree/master/tests/compute-engine/README.md).

&#x20;

***NOTE:*** **If you are using a versions 7.0.0 and up**: modules can replace resources if certain set parameters differ from the results found in the API!

### Parameters that can trigger a resource replacement:

* size
* disk\_type
* availability\_zone
* licence\_type
* user\_data (Might trigger replace just by being set as this parameter is retrieved from the API as the image ID, so when using an alias it will always cause a resource replacement!)
* image (Might trigger replace just by being set as this parameter is retrieved from the API as the image ID, so when using an alias it will always cause a resource replacement!)
* image\_password (Will trigger replace just by being set as this parameter cannot be retrieved from the api to check for changes!)
* ssh\_keys (Will trigger replace just by being set as this parameter cannot be retrieved from the api to check for changes!)
* backupunit (Will trigger replace just by being set as this parameter cannot be retrieved from the api to check for changes!) &#x20;

## state: **present**

```yaml
  
name: Create volumes
ionoscloudsdk.ionoscloud.volume:
  datacenter: 'AnsibleAutoTestCompute'
  name: 'AnsibleAutoTestCompute %02d'
  disk_type: SSD Premium
  image: 'ubuntu:latest'
  image_password: '{{ lookup('ansible.builtin.password', '/dev/null chars=ascii_letters,digits') }}'
  count: 2
  size: 20
  availability_zone: AUTO
  cpu_hot_plug: false
  ram_hot_plug: true
  nic_hot_plug: true
  nic_hot_unplug: true
  disc_virtio_hot_plug: true
  disc_virtio_hot_unplug: true
  wait_timeout: 600
  wait: true
  state: present
register: volume_create_response

```

#### Available parameters for state **present**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The datacenter in which to create the volumes.</td></tr><tr><td>server<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The server to which to attach the volume.</td></tr><tr><td>name<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The name of the resource.</td></tr><tr><td>size<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>The size of the volume in GB.</td></tr><tr><td>bus<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The bus type for this volume; default is VIRTIO.<br>Default: VIRTIO<br>Options: ['VIRTIO', 'IDE', 'UNKNOWN']</td></tr><tr><td>image<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Image or snapshot ID to be used as template for this volume. MSSQL Enterprise Images can be used only if the feature toggle for MSSQL Enterprise is enabled on the contract.</td></tr><tr><td>image_password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Initial password to be set for installed OS. Works with public images only. Not modifiable, forbidden in update requests. Password rules allows all characters from a-z, A-Z, 0-9.</td></tr><tr><td>ssh_keys<br><mark style="color:blue;">list</mark></td><td align="center">False</td><td>Public SSH keys are set on the image as authorized keys for appropriate SSH login to the instance using the corresponding private key. This field may only be set in creation requests. When reading, it always returns null. SSH keys are only supported if a public Linux image is used for the volume creation.</td></tr><tr><td>disk_type<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The disk type of the volume.<br>Options: ['HDD', 'SSD', 'SSD Premium', 'SSD Standard', 'DAS', 'ISO', 'ESSENTIAL', 'BALANCED', 'PERFORMANCE']</td></tr><tr><td>licence_type<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>OS type for this volume.<br>Options: ['UNKNOWN', 'WINDOWS', 'WINDOWS2016', 'WINDOWS2019', 'WINDOWS2022', 'WINDOWS2025', 'RHEL', 'LINUX', 'OTHER']</td></tr><tr><td>availability_zone<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The availability zone in which the volume should be provisioned. The storage volume will be provisioned on as few physical storage devices as possible, but this cannot be guaranteed upfront. This is uavailable for DAS (Direct Attached Storage), and subject to availability for SSD.<br>Options: ['AUTO', 'ZONE_1', 'ZONE_2', 'ZONE_3']</td></tr><tr><td>count<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>The number of volumes you wish to create.<br>Default: 1</td></tr><tr><td>backupunit<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The ID of the backup unit that the user has access to. The property is immutable and is only allowed to be set on creation of a new a volume. It is mandatory to provide either 'public image' or 'imageAlias' in conjunction with this property.</td></tr><tr><td>user_data<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The cloud-init configuration for the volume as base64 encoded string. The property is immutable and is only allowed to be set on creation of a new a volume. It is mandatory to provide either 'public image' or 'imageAlias' that has cloud-init compatibility in conjunction with this property.</td></tr><tr><td>cpu_hot_plug<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Hot-plug capable CPU (no reboot required).</td></tr><tr><td>ram_hot_plug<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Hot-plug capable RAM (no reboot required).</td></tr><tr><td>nic_hot_plug<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Hot-plug capable NIC (no reboot required).</td></tr><tr><td>nic_hot_unplug<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Hot-unplug capable NIC (no reboot required).</td></tr><tr><td>disc_virtio_hot_plug<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Hot-plug capable Virt-IO drive (no reboot required).</td></tr><tr><td>disc_virtio_hot_unplug<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Hot-unplug capable Virt-IO drive (no reboot required). Not supported with Windows VMs.</td></tr><tr><td>allow_replace<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Boolean indicating if the resource should be recreated when the state cannot be reached in another way. This may be used to prevent resources from being deleted from specifying a different value to an immutable property. An error will be thrown instead<br>Default: False</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['present', 'absent', 'update']</td></tr></tbody></table>

&#x20;

&#x20;

## state: **absent**

```yaml
  
name: Delete volumes
ionoscloudsdk.ionoscloud.volume:
  datacenter: 'AnsibleAutoTestCompute'
  instance_ids:
  - 'AnsibleAutoTestCompute modified'
  - 'AnsibleAutoTestCompute 02'
  wait_timeout: 600
  state: absent

```

#### Available parameters for state **absent**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The datacenter in which to create the volumes.</td></tr><tr><td>name<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The name of the resource.</td></tr><tr><td>instance_ids<br><mark style="color:blue;">list</mark></td><td align="center">False</td><td>list of instance ids or names. Should only contain one ID if renaming in update state<br>Default:</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['present', 'absent', 'update']</td></tr></tbody></table>

&#x20;

&#x20;

## state: **update**

```yaml
  
name: Update no change
ionoscloudsdk.ionoscloud.volume:
  datacenter: 'AnsibleAutoTestCompute'
  instance_ids:
  - 'AnsibleAutoTestCompute 01'
  disk_type: SSD Premium
  size: 20
  availability_zone: AUTO
  image: ''
  ram_hot_plug: true
  nic_hot_plug: true
  nic_hot_unplug: true
  disc_virtio_hot_plug: true
  disc_virtio_hot_unplug: true
  allow_replace: false
  wait_timeout: 600
  wait: true
  state: update
register: volume_create_response_nochange

```

#### Available parameters for state **update**:

&#x20;

<table data-full-width="true"><thead><tr><th width="70">Name</th><th width="40" align="center">Required</th><th>Description</th></tr></thead><tbody><tr><td>datacenter<br><mark style="color:blue;">str</mark></td><td align="center">True</td><td>The datacenter in which to create the volumes.</td></tr><tr><td>name<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The name of the resource.</td></tr><tr><td>size<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>The size of the volume in GB.</td></tr><tr><td>bus<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The bus type for this volume; default is VIRTIO.<br>Default: VIRTIO<br>Options: ['VIRTIO', 'IDE', 'UNKNOWN']</td></tr><tr><td>availability_zone<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The availability zone in which the volume should be provisioned. The storage volume will be provisioned on as few physical storage devices as possible, but this cannot be guaranteed upfront. This is uavailable for DAS (Direct Attached Storage), and subject to availability for SSD.<br>Options: ['AUTO', 'ZONE_1', 'ZONE_2', 'ZONE_3']</td></tr><tr><td>instance_ids<br><mark style="color:blue;">list</mark></td><td align="center">False</td><td>list of instance ids or names. Should only contain one ID if renaming in update state<br>Default:</td></tr><tr><td>cpu_hot_plug<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Hot-plug capable CPU (no reboot required).</td></tr><tr><td>ram_hot_plug<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Hot-plug capable RAM (no reboot required).</td></tr><tr><td>nic_hot_plug<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Hot-plug capable NIC (no reboot required).</td></tr><tr><td>nic_hot_unplug<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Hot-unplug capable NIC (no reboot required).</td></tr><tr><td>disc_virtio_hot_plug<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Hot-plug capable Virt-IO drive (no reboot required).</td></tr><tr><td>disc_virtio_hot_unplug<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Hot-unplug capable Virt-IO drive (no reboot required). Not supported with Windows VMs.</td></tr><tr><td>allow_replace<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Boolean indicating if the resource should be recreated when the state cannot be reached in another way. This may be used to prevent resources from being deleted from specifying a different value to an immutable property. An error will be thrown instead<br>Default: False</td></tr><tr><td>api_url<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API base URL.</td></tr><tr><td>certificate_fingerprint<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos API certificate fingerprint.</td></tr><tr><td>username<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos username. Overrides the IONOS_USERNAME environment variable.</td></tr><tr><td>password<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos password. Overrides the IONOS_PASSWORD environment variable.</td></tr><tr><td>token<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>The Ionos token. Overrides the IONOS_TOKEN environment variable.</td></tr><tr><td>wait<br><mark style="color:blue;">bool</mark></td><td align="center">False</td><td>Wait for the resource to be created before returning.<br>Default: True<br>Options: [True, False]</td></tr><tr><td>wait_timeout<br><mark style="color:blue;">int</mark></td><td align="center">False</td><td>How long before wait gives up, in seconds.<br>Default: 600</td></tr><tr><td>state<br><mark style="color:blue;">str</mark></td><td align="center">False</td><td>Indicate desired state of the resource.<br>Default: present<br>Options: ['present', 'absent', 'update']</td></tr></tbody></table>

&#x20;

&#x20;




---

[Next Page](https://docs.ionos.com/ansible/llms-full.txt/1)

