From 6b33d09d9fc81ec2e2b1fdb4e47df676f400b2e2 Mon Sep 17 00:00:00 2001 From: Jack Ivanov <17044561+jackivanov@users.noreply.github.com> Date: Fri, 3 May 2019 09:55:45 +0200 Subject: [PATCH] Scaleway modules (#1410) * Scaleway modules * Update docs --- docs/deploy-from-ansible.md | 1 - library/scaleway_compute.py | 619 +++++++++++++++++++++ roles/cloud-scaleway/tasks/image_facts.yml | 10 - roles/cloud-scaleway/tasks/main.yml | 155 ++---- roles/cloud-scaleway/tasks/prompts.yml | 13 +- 5 files changed, 657 insertions(+), 141 deletions(-) create mode 100644 library/scaleway_compute.py delete mode 100644 roles/cloud-scaleway/tasks/image_facts.yml diff --git a/docs/deploy-from-ansible.md b/docs/deploy-from-ansible.md index 9816f0bd1..f062a04f6 100644 --- a/docs/deploy-from-ansible.md +++ b/docs/deploy-from-ansible.md @@ -230,7 +230,6 @@ Possible options can be gathered via cli `aws lightsail get-regions` Required variables: - [scaleway_token](https://www.scaleway.com/docs/generate-an-api-token/) -- [scaleway_org](https://cloud.scaleway.com/#/billing) - region Possible regions: diff --git a/library/scaleway_compute.py b/library/scaleway_compute.py new file mode 100644 index 000000000..8aa6ce487 --- /dev/null +++ b/library/scaleway_compute.py @@ -0,0 +1,619 @@ +#!/usr/bin/python +# +# Scaleway Compute management module +# +# Copyright (C) 2018 Online SAS. +# https://www.scaleway.com +# +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +ANSIBLE_METADATA = { + 'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community' +} + +DOCUMENTATION = ''' +--- +module: scaleway_compute +short_description: Scaleway compute management module +version_added: "2.6" +author: Remy Leone (@sieben) +description: + - "This module manages compute instances on Scaleway." +extends_documentation_fragment: scaleway + +options: + + enable_ipv6: + description: + - Enable public IPv6 connectivity on the instance + default: false + type: bool + + boot_type: + description: + - Boot method + default: bootscript + choices: + - bootscript + - local + + image: + description: + - Image identifier used to start the instance with + required: true + + name: + description: + - Name of the instance + + organization: + description: + - Organization identifier + required: true + + state: + description: + - Indicate desired state of the instance. + default: present + choices: + - present + - absent + - running + - restarted + - stopped + + tags: + description: + - List of tags to apply to the instance (5 max) + required: false + default: [] + + region: + description: + - Scaleway compute zone + required: true + choices: + - ams1 + - EMEA-NL-EVS + - par1 + - EMEA-FR-PAR1 + + commercial_type: + description: + - Commercial name of the compute node + required: true + choices: + - ARM64-2GB + - ARM64-4GB + - ARM64-8GB + - ARM64-16GB + - ARM64-32GB + - ARM64-64GB + - ARM64-128GB + - C1 + - C2S + - C2M + - C2L + - START1-XS + - START1-S + - START1-M + - START1-L + - X64-15GB + - X64-30GB + - X64-60GB + - X64-120GB + + wait: + description: + - Wait for the instance to reach its desired state before returning. + type: bool + default: 'no' + + wait_timeout: + description: + - Time to wait for the server to reach the expected state + required: false + default: 300 + + wait_sleep_time: + description: + - Time to wait before every attempt to check the state of the server + required: false + default: 3 +''' + +EXAMPLES = ''' +- name: Create a server + scaleway_compute: + name: foobar + state: present + image: 89ee4018-f8c3-4dc4-a6b5-bca14f985ebe + organization: 951df375-e094-4d26-97c1-ba548eeb9c42 + region: ams1 + commercial_type: VC1S + tags: + - test + - www + +- name: Destroy it right after + scaleway_compute: + name: foobar + state: absent + image: 89ee4018-f8c3-4dc4-a6b5-bca14f985ebe + organization: 951df375-e094-4d26-97c1-ba548eeb9c42 + region: ams1 + commercial_type: VC1S +''' + +RETURN = ''' +''' + +import datetime +import time + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.six.moves.urllib.parse import quote as urlquote +from ansible.module_utils.scaleway import SCALEWAY_LOCATION, scaleway_argument_spec, Scaleway + +SCALEWAY_COMMERCIAL_TYPES = [ + + # Virtual ARM64 compute instance + 'ARM64-2GB', + 'ARM64-4GB', + 'ARM64-8GB', + 'ARM64-16GB', + 'ARM64-32GB', + 'ARM64-64GB', + 'ARM64-128GB', + + # Baremetal + 'C1', # ARM64 (4 cores) - 2GB + 'C2S', # X86-64 (4 cores) - 8GB + 'C2M', # X86-64 (8 cores) - 16GB + 'C2L', # x86-64 (8 cores) - 32 GB + + # Virtual X86-64 compute instance + 'START1-XS', # Starter X86-64 (1 core) - 1GB - 25 GB NVMe + 'START1-S', # Starter X86-64 (2 cores) - 2GB - 50 GB NVMe + 'START1-M', # Starter X86-64 (4 cores) - 4GB - 100 GB NVMe + 'START1-L', # Starter X86-64 (8 cores) - 8GB - 200 GB NVMe + 'X64-15GB', + 'X64-30GB', + 'X64-60GB', + 'X64-120GB', +] + +SCALEWAY_SERVER_STATES = ( + 'stopped', + 'stopping', + 'starting', + 'running', + 'locked' +) + +SCALEWAY_TRANSITIONS_STATES = ( + "stopping", + "starting", + "pending" +) + + +def fetch_state(compute_api, server): + compute_api.module.debug("fetch_state of server: %s" % server["id"]) + response = compute_api.get(path="servers/%s" % server["id"]) + + if response.status_code == 404: + return "absent" + + if not response.ok: + msg = 'Error during state fetching: (%s) %s' % (response.status_code, response.json) + compute_api.module.fail_json(msg=msg) + + try: + compute_api.module.debug("Server %s in state: %s" % (server["id"], response.json["server"]["state"])) + return response.json["server"]["state"] + except KeyError: + compute_api.module.fail_json(msg="Could not fetch state in %s" % response.json) + + +def wait_to_complete_state_transition(compute_api, server): + wait = compute_api.module.params["wait"] + if not wait: + return + wait_timeout = compute_api.module.params["wait_timeout"] + wait_sleep_time = compute_api.module.params["wait_sleep_time"] + + start = datetime.datetime.utcnow() + end = start + datetime.timedelta(seconds=wait_timeout) + while datetime.datetime.utcnow() < end: + compute_api.module.debug("We are going to wait for the server to finish its transition") + if fetch_state(compute_api, server) not in SCALEWAY_TRANSITIONS_STATES: + compute_api.module.debug("It seems that the server is not in transition anymore.") + compute_api.module.debug("Server in state: %s" % fetch_state(compute_api, server)) + break + time.sleep(wait_sleep_time) + else: + compute_api.module.fail_json(msg="Server takes too long to finish its transition") + + +def create_server(compute_api, server): + compute_api.module.debug("Starting a create_server") + target_server = None + response = compute_api.post(path="servers", + data={"enable_ipv6": server["enable_ipv6"], + "boot_type": server["boot_type"], + "tags": server["tags"], + "commercial_type": server["commercial_type"], + "image": server["image"], + "name": server["name"], + "organization": server["organization"]}) + + if not response.ok: + msg = 'Error during server creation: (%s) %s' % (response.status_code, response.json) + compute_api.module.fail_json(msg=msg) + + try: + target_server = response.json["server"] + except KeyError: + compute_api.module.fail_json(msg="Error in getting the server information from: %s" % response.json) + + wait_to_complete_state_transition(compute_api=compute_api, server=target_server) + + return target_server + + +def restart_server(compute_api, server): + return perform_action(compute_api=compute_api, server=server, action="reboot") + + +def stop_server(compute_api, server): + return perform_action(compute_api=compute_api, server=server, action="poweroff") + + +def start_server(compute_api, server): + return perform_action(compute_api=compute_api, server=server, action="poweron") + + +def perform_action(compute_api, server, action): + response = compute_api.post(path="servers/%s/action" % server["id"], + data={"action": action}) + if not response.ok: + msg = 'Error during server %s: (%s) %s' % (action, response.status_code, response.json) + compute_api.module.fail_json(msg=msg) + + wait_to_complete_state_transition(compute_api=compute_api, server=server) + + return response + + +def remove_server(compute_api, server): + compute_api.module.debug("Starting remove server strategy") + response = compute_api.delete(path="servers/%s" % server["id"]) + if not response.ok: + msg = 'Error during server deletion: (%s) %s' % (response.status_code, response.json) + compute_api.module.fail_json(msg=msg) + + wait_to_complete_state_transition(compute_api=compute_api, server=server) + + return response + + +def present_strategy(compute_api, wished_server): + compute_api.module.debug("Starting present strategy") + changed = False + query_results = find(compute_api=compute_api, wished_server=wished_server, per_page=1) + + if not query_results: + changed = True + if compute_api.module.check_mode: + return changed, {"status": "A server would be created."} + + target_server = create_server(compute_api=compute_api, server=wished_server) + else: + target_server = query_results[0] + + if server_attributes_should_be_changed(compute_api=compute_api, target_server=target_server, + wished_server=wished_server): + changed = True + + if compute_api.module.check_mode: + return changed, {"status": "Server %s attributes would be changed." % target_server["id"]} + + server_change_attributes(compute_api=compute_api, target_server=target_server, wished_server=wished_server) + + return changed, target_server + + +def absent_strategy(compute_api, wished_server): + compute_api.module.debug("Starting absent strategy") + changed = False + target_server = None + query_results = find(compute_api=compute_api, wished_server=wished_server, per_page=1) + + if not query_results: + return changed, {"status": "Server already absent."} + else: + target_server = query_results[0] + + changed = True + + if compute_api.module.check_mode: + return changed, {"status": "Server %s would be made absent." % target_server["id"]} + + # A server MUST be stopped to be deleted. + while not fetch_state(compute_api=compute_api, server=target_server) == "stopped": + wait_to_complete_state_transition(compute_api=compute_api, server=target_server) + response = stop_server(compute_api=compute_api, server=target_server) + + if not response.ok: + err_msg = 'Error while stopping a server before removing it [{0}: {1}]'.format(response.status_code, + response.json) + compute_api.module.fail_json(msg=err_msg) + + wait_to_complete_state_transition(compute_api=compute_api, server=target_server) + + response = remove_server(compute_api=compute_api, server=target_server) + + if not response.ok: + err_msg = 'Error while removing server [{0}: {1}]'.format(response.status_code, response.json) + compute_api.module.fail_json(msg=err_msg) + + return changed, {"status": "Server %s deleted" % target_server["id"]} + + +def running_strategy(compute_api, wished_server): + compute_api.module.debug("Starting running strategy") + changed = False + query_results = find(compute_api=compute_api, wished_server=wished_server, per_page=1) + + if not query_results: + changed = True + if compute_api.module.check_mode: + return changed, {"status": "A server would be created before being run."} + + target_server = create_server(compute_api=compute_api, server=wished_server) + else: + target_server = query_results[0] + + if server_attributes_should_be_changed(compute_api=compute_api, target_server=target_server, + wished_server=wished_server): + changed = True + + if compute_api.module.check_mode: + return changed, {"status": "Server %s attributes would be changed before running it." % target_server["id"]} + + server_change_attributes(compute_api=compute_api, target_server=target_server, wished_server=wished_server) + + current_state = fetch_state(compute_api=compute_api, server=target_server) + if current_state not in ("running", "starting"): + compute_api.module.debug("running_strategy: Server in state: %s" % current_state) + changed = True + + if compute_api.module.check_mode: + return changed, {"status": "Server %s attributes would be changed." % target_server["id"]} + + response = start_server(compute_api=compute_api, server=target_server) + if not response.ok: + msg = 'Error while running server [{0}: {1}]'.format(response.status_code, response.json) + compute_api.module.fail_json(msg=msg) + + return changed, target_server + + +def stop_strategy(compute_api, wished_server): + compute_api.module.debug("Starting stop strategy") + query_results = find(compute_api=compute_api, wished_server=wished_server, per_page=1) + + changed = False + + if not query_results: + + if compute_api.module.check_mode: + return changed, {"status": "A server would be created before being stopped."} + + target_server = create_server(compute_api=compute_api, server=wished_server) + changed = True + else: + target_server = query_results[0] + + compute_api.module.debug("stop_strategy: Servers are found.") + + if server_attributes_should_be_changed(compute_api=compute_api, target_server=target_server, + wished_server=wished_server): + changed = True + + if compute_api.module.check_mode: + return changed, { + "status": "Server %s attributes would be changed before stopping it." % target_server["id"]} + + server_change_attributes(compute_api=compute_api, target_server=target_server, wished_server=wished_server) + + wait_to_complete_state_transition(compute_api=compute_api, server=target_server) + + current_state = fetch_state(compute_api=compute_api, server=target_server) + if current_state not in ("stopped",): + compute_api.module.debug("stop_strategy: Server in state: %s" % current_state) + + changed = True + + if compute_api.module.check_mode: + return changed, {"status": "Server %s would be stopped." % target_server["id"]} + + response = stop_server(compute_api=compute_api, server=target_server) + compute_api.module.debug(response.json) + compute_api.module.debug(response.ok) + + if not response.ok: + msg = 'Error while stopping server [{0}: {1}]'.format(response.status_code, response.json) + compute_api.module.fail_json(msg=msg) + + return changed, target_server + + +def restart_strategy(compute_api, wished_server): + compute_api.module.debug("Starting restart strategy") + changed = False + query_results = find(compute_api=compute_api, wished_server=wished_server, per_page=1) + + if not query_results: + changed = True + if compute_api.module.check_mode: + return changed, {"status": "A server would be created before being rebooted."} + + target_server = create_server(compute_api=compute_api, server=wished_server) + else: + target_server = query_results[0] + + if server_attributes_should_be_changed(compute_api=compute_api, + target_server=target_server, + wished_server=wished_server): + changed = True + + if compute_api.module.check_mode: + return changed, { + "status": "Server %s attributes would be changed before rebooting it." % target_server["id"]} + + server_change_attributes(compute_api=compute_api, target_server=target_server, wished_server=wished_server) + + changed = True + if compute_api.module.check_mode: + return changed, {"status": "Server %s would be rebooted." % target_server["id"]} + + wait_to_complete_state_transition(compute_api=compute_api, server=target_server) + + if fetch_state(compute_api=compute_api, server=target_server) in ("running",): + response = restart_server(compute_api=compute_api, server=target_server) + wait_to_complete_state_transition(compute_api=compute_api, server=target_server) + if not response.ok: + msg = 'Error while restarting server that was running [{0}: {1}].'.format(response.status_code, + response.json) + compute_api.module.fail_json(msg=msg) + + if fetch_state(compute_api=compute_api, server=target_server) in ("stopped",): + response = restart_server(compute_api=compute_api, server=target_server) + wait_to_complete_state_transition(compute_api=compute_api, server=target_server) + if not response.ok: + msg = 'Error while restarting server that was stopped [{0}: {1}].'.format(response.status_code, + response.json) + compute_api.module.fail_json(msg=msg) + + return changed, target_server + + +state_strategy = { + "present": present_strategy, + "restarted": restart_strategy, + "stopped": stop_strategy, + "running": running_strategy, + "absent": absent_strategy +} + + +def find(compute_api, wished_server, per_page=1): + compute_api.module.debug("Getting inside find") + # Only the name attribute is accepted in the Compute query API + url = 'servers?name=%s&per_page=%d' % (urlquote(wished_server["name"]), per_page) + response = compute_api.get(url) + + if not response.ok: + msg = 'Error during server search: (%s) %s' % (response.status_code, response.json) + compute_api.module.fail_json(msg=msg) + + search_results = response.json["servers"] + + return search_results + + +PATCH_MUTABLE_SERVER_ATTRIBUTES = ( + "ipv6", + "tags", + "name", + "dynamic_ip_required", +) + + +def server_attributes_should_be_changed(compute_api, target_server, wished_server): + compute_api.module.debug("Checking if server attributes should be changed") + compute_api.module.debug("Current Server: %s" % target_server) + compute_api.module.debug("Wished Server: %s" % wished_server) + debug_dict = dict((x, (target_server[x], wished_server[x])) + for x in PATCH_MUTABLE_SERVER_ATTRIBUTES + if x in target_server and x in wished_server) + compute_api.module.debug("Debug dict %s" % debug_dict) + + try: + return any([target_server[x] != wished_server[x] + for x in PATCH_MUTABLE_SERVER_ATTRIBUTES + if x in target_server and x in wished_server]) + except AttributeError: + compute_api.module.fail_json(msg="Error while checking if attributes should be changed") + + +def server_change_attributes(compute_api, target_server, wished_server): + compute_api.module.debug("Starting patching server attributes") + patch_payload = dict((x, wished_server[x]) + for x in PATCH_MUTABLE_SERVER_ATTRIBUTES + if x in wished_server and x in target_server) + response = compute_api.patch(path="servers/%s" % target_server["id"], + data=patch_payload) + if not response.ok: + msg = 'Error during server attributes patching: (%s) %s' % (response.status_code, response.json) + compute_api.module.fail_json(msg=msg) + + wait_to_complete_state_transition(compute_api=compute_api, server=target_server) + + return response + + +def core(module): + region = module.params["region"] + wished_server = { + "state": module.params["state"], + "image": module.params["image"], + "name": module.params["name"], + "commercial_type": module.params["commercial_type"], + "enable_ipv6": module.params["enable_ipv6"], + "boot_type": module.params["boot_type"], + "tags": module.params["tags"], + "organization": module.params["organization"] + } + module.params['api_url'] = SCALEWAY_LOCATION[region]["api_endpoint"] + + compute_api = Scaleway(module=module) + + changed, summary = state_strategy[wished_server["state"]](compute_api=compute_api, wished_server=wished_server) + module.exit_json(changed=changed, msg=summary) + + +def main(): + argument_spec = scaleway_argument_spec() + argument_spec.update(dict( + image=dict(required=True), + name=dict(), + region=dict(required=True, choices=SCALEWAY_LOCATION.keys()), + commercial_type=dict(required=True, choices=SCALEWAY_COMMERCIAL_TYPES), + enable_ipv6=dict(default=False, type="bool"), + boot_type=dict(default="bootscript"), + state=dict(choices=state_strategy.keys(), default='present'), + tags=dict(type="list", default=[]), + organization=dict(required=True), + wait=dict(type="bool", default=False), + wait_timeout=dict(type="int", default=300), + wait_sleep_time=dict(type="int", default=3), + )) + module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + ) + + core(module) + + +if __name__ == '__main__': + main() diff --git a/roles/cloud-scaleway/tasks/image_facts.yml b/roles/cloud-scaleway/tasks/image_facts.yml deleted file mode 100644 index 41269845d..000000000 --- a/roles/cloud-scaleway/tasks/image_facts.yml +++ /dev/null @@ -1,10 +0,0 @@ ---- -- name: Set image id as a fact - set_fact: - image_id: "{{ item.id }}" - no_log: true - when: - - cloud_providers.scaleway.image == item.name - - cloud_providers.scaleway.arch == item.arch - - server_disk_size == item.root_volume.size - with_items: "{{ outer_item['json']['images'] }}" diff --git a/roles/cloud-scaleway/tasks/main.yml b/roles/cloud-scaleway/tasks/main.yml index 3e9a39b8b..d7aae7951 100644 --- a/roles/cloud-scaleway/tasks/main.yml +++ b/roles/cloud-scaleway/tasks/main.yml @@ -1,133 +1,46 @@ - name: Include prompts import_tasks: prompts.yml -- name: Set disk size - set_fact: - server_disk_size: 50000000000 - -- name: Check server size - set_fact: - server_disk_size: 25000000000 - when: cloud_providers.scaleway.size == "START1-XS" - -- name: Check if server exists - uri: - url: "https://cp-{{ algo_region }}.scaleway.com/servers" - method: GET - headers: - Content-Type: 'application/json' - X-Auth-Token: "{{ algo_scaleway_token }}" - status_code: 200 - register: scaleway_servers - -- name: Set server id as a fact - set_fact: - server_id: "{{ item.id }}" - no_log: true - when: algo_server_name == item.name - with_items: "{{ scaleway_servers.json.servers }}" - -- name: Create a server if it doesn't exist - block: - - name: Get the organization id - uri: - url: https://account.cloud.online.net/organizations - method: GET - headers: - Content-Type: 'application/json' - X-Auth-Token: "{{ algo_scaleway_token }}" - status_code: 200 - register: scaleway_organizations - - - name: Set organization id as a fact - set_fact: - organization_id: "{{ item.id }}" - no_log: true - when: algo_scaleway_org == item.name - with_items: "{{ scaleway_organizations.json.organizations }}" - - - name: Get total count of images - uri: - url: "https://cp-{{ algo_region }}.scaleway.com/images" - method: GET - headers: - Content-Type: 'application/json' - X-Auth-Token: "{{ algo_scaleway_token }}" - status_code: 200 - register: scaleway_pages +- block: + - name: Gather Scaleway organizations facts + scaleway_organization_facts: - name: Get images - uri: - url: "https://cp-{{ algo_region }}.scaleway.com/images?per_page=100&page={{ item }}" - method: GET - headers: - Content-Type: 'application/json' - X-Auth-Token: "{{ algo_scaleway_token }}" - status_code: 200 - register: scaleway_images - with_sequence: start=1 end={{ ((scaleway_pages.x_total_count|int / 100)| round )|int }} + scaleway_image_facts: + region: "{{ algo_region }}" - - name: Set image id as a fact - include_tasks: image_facts.yml - with_items: "{{ scaleway_images['results'] }}" - loop_control: - loop_var: outer_item + - name: Set cloud specific facts + set_fact: + organization_id: "{{ scaleway_organization_facts[0]['id'] }}" + images: >- + [{% for i in scaleway_image_facts -%} + {% if i.name == cloud_providers.scaleway.image and + i.arch == cloud_providers.scaleway.arch -%} + '{{ i.id }}'{% if not loop.last %},{% endif %} + {%- endif -%} + {%- endfor -%}] - name: Create a server - uri: - url: "https://cp-{{ algo_region }}.scaleway.com/servers/" - method: POST - headers: - Content-Type: 'application/json' - X-Auth-Token: "{{ algo_scaleway_token }}" - body: - organization: "{{ organization_id }}" - name: "{{ algo_server_name }}" - image: "{{ image_id }}" - commercial_type: "{{ cloud_providers.scaleway.size }}" - enable_ipv6: true - boot_type: local - tags: - - Environment:Algo - - AUTHORIZED_KEY={{ lookup('file', SSH_keys.public)|regex_replace(' ', '_') }} - status_code: 201 - body_format: json + scaleway_compute: + name: "{{ algo_server_name }}" + enable_ipv6: true + boot_type: local + state: running + image: "{{ images[0] }}" + organization: "{{ organization_id }}" + region: "{{ algo_region }}" + commercial_type: "{{ cloud_providers.scaleway.size }}" + wait: true + tags: + - Environment:Algo + - AUTHORIZED_KEY={{ lookup('file', SSH_keys.public)|regex_replace(' ', '_') }} register: algo_instance - - - name: Set server id as a fact - set_fact: - server_id: "{{ algo_instance.json.server.id }}" - when: server_id is not defined - -- name: Power on the server - uri: - url: https://cp-{{ algo_region }}.scaleway.com/servers/{{ server_id }}/action - method: POST - headers: - Content-Type: application/json - X-Auth-Token: "{{ algo_scaleway_token }}" - body: - action: poweron - status_code: 202 - body_format: json - ignore_errors: true - no_log: true - -- name: Wait for the server to become running - uri: - url: "https://cp-{{ algo_region }}.scaleway.com/servers/{{ server_id }}" - method: GET - headers: - Content-Type: 'application/json' - X-Auth-Token: "{{ algo_scaleway_token }}" - status_code: 200 - until: - - algo_instance.json.server.state is defined - - algo_instance.json.server.state == "running" - retries: 20 - delay: 30 - register: algo_instance + until: algo_instance.msg.public_ip + retries: 3 + delay: 3 + environment: + SCW_TOKEN: "{{ algo_scaleway_token }}" - set_fact: - cloud_instance_ip: "{{ algo_instance['json']['server']['public_ip']['address'] }}" + cloud_instance_ip: "{{ algo_instance.msg.public_ip.address }}" ansible_ssh_user: root diff --git a/roles/cloud-scaleway/tasks/prompts.yml b/roles/cloud-scaleway/tasks/prompts.yml index b481880d9..be4743fb4 100644 --- a/roles/cloud-scaleway/tasks/prompts.yml +++ b/roles/cloud-scaleway/tasks/prompts.yml @@ -4,13 +4,9 @@ Enter your auth token (https://www.scaleway.com/docs/generate-an-api-token/) echo: false register: _scaleway_token - when: scaleway_token is undefined - -- pause: - prompt: | - Enter your organization name (https://cloud.scaleway.com/#/billing) - register: _scaleway_org - when: scaleway_org is undefined + when: + - scaleway_token is undefined + - lookup('env','SCW_TOKEN')|length <= 0 - pause: prompt: | @@ -26,8 +22,7 @@ - name: Set scaleway facts set_fact: - algo_scaleway_token: "{{ scaleway_token | default(_scaleway_token.user_input) }}" - algo_scaleway_org: "{{ scaleway_org | default(_scaleway_org.user_input|default(omit)) }}" + algo_scaleway_token: "{{ scaleway_token | default(_scaleway_token.user_input) | default(lookup('env','SCW_TOKEN'), true) }}" algo_region: >- {% if region is defined %}{{ region }} {%- elif _algo_region.user_input %}{{ scaleway_regions[_algo_region.user_input | int -1 ]['alias'] }}