From 9fd76bb5c75a72f0ea56d8893d4f56202cc48004 Mon Sep 17 00:00:00 2001 From: William Graef Date: Wed, 6 Nov 2024 11:29:35 -0500 Subject: [PATCH 01/16] initialize olam update --- olam/block.yml | 39 ++ olam/build.yaml | 5 +- olam/create_instance.yaml | 677 ++++++++++++----------- olam/create_instance_1.yaml | 379 +++++++++++++ olam/default_vars.yml | 0 olam/requirements.yaml | 4 + olam/templates/egress_security_rules.j2 | 9 + olam/templates/ingress_security_rules.j2 | 88 +++ 8 files changed, 869 insertions(+), 332 deletions(-) create mode 100644 olam/block.yml create mode 100644 olam/create_instance_1.yaml create mode 100644 olam/default_vars.yml create mode 100644 olam/templates/egress_security_rules.j2 create mode 100644 olam/templates/ingress_security_rules.j2 diff --git a/olam/block.yml b/olam/block.yml new file mode 100644 index 0000000..2d932cc --- /dev/null +++ b/olam/block.yml @@ -0,0 +1,39 @@ +--- +# Copyright (c) 2024 Oracle and/or its affiliates. +# This software is made available to you under the terms of the Universal Permissive License (UPL), Version 1.0. +# The Universal Permissive License (UPL), Version 1.0 (see COPYING or https://oss.oracle.com/licenses/upl) +# See LICENSE.TXT for details. + +- name: Add block volumes to the instance + when: + - add_block_storage + block: + - name: Create block volume + oracle.oci.oci_blockstorage_volume: + compartment_id: "{{ my_compartment_id }}" + availability_domain: "{{ my_availability_domain }}" + display_name: "blockvolume-{{ item.value.instance_name | default('instance-'~timestamp) }}" + size_in_gbs: "{{ block_volume_size_in_gbs }}" + register: result + vars: + timestamp: "{{ now().strftime('%Y%m%d-%H%M%S') }}" + retries: 10 + delay: 30 + until: result is not failed + + - name: Set the block volume id + ansible.builtin.set_fact: + volume_id: "{{ result.volume.id }}" + + - name: Attach the block volume + oracle.oci.oci_compute_volume_attachment: + instance_id: "{{ instance_id }}" + type: paravirtualized + volume_id: "{{ volume_id }}" + compartment_id: "{{ my_compartment_id }}" + device: "/dev/oracleoci/oraclevd{{ block_devices[ansible_loop.index0] }}" + is_read_only: false + is_shareable: false + retries: 10 + delay: 30 + until: result is not failed diff --git a/olam/build.yaml b/olam/build.yaml index c6b3f29..6ba3246 100644 --- a/olam/build.yaml +++ b/olam/build.yaml @@ -9,7 +9,10 @@ availability_domain: "{{ my_availability_domain }}" compartment_id: "{{ my_compartment_id }}" name: "{{ item.value.instance_name | default('instance-'~timestamp) }}" - image_id: "{{ ol_image_id }}" + source_details: + image_id: "{{ ol_image_id }}" + source_type: image + boot_volume_size_in_gbs: "{{ item.value.boot_volume_size_in_gbs | default(50) | int }}" shape: "{{ instance_shape }}" shape_config: ocpus: "{{ instance_ocpus }}" diff --git a/olam/create_instance.yaml b/olam/create_instance.yaml index 025f649..b2215b1 100644 --- a/olam/create_instance.yaml +++ b/olam/create_instance.yaml @@ -6,10 +6,8 @@ - name: Gather facts and create instances hosts: localhost - collections: - - oracle.oci - - community.general - + vars_files: + - default_vars.yml vars: oci_config_section: DEFAULT ad_placement: 1 @@ -17,363 +15,380 @@ compartment_id: compute_instances: 1: - instance_name: "control-node" + instance_name: "ol-node-01" + type: "client" 2: - instance_name: "olam-node" + instance_name: "ol-node-02" + type: "server" os: "Oracle Linux" os_version: "8" instance_shape: "VM.Standard.E4.Flex" instance_ocpus: 2 - instance_memory: 16 + instance_memory: 32 private_key: "id_rsa" - # ansible_python_interpreter: /usr/bin/python3.6 + ansible_python_interpreter: "{{ localhost_python_interpreter | default(omit) }}" debug_enabled: false tasks: - # - name: Check if state file exists - # ansible.builtin.stat: - # path: /tmp/ansible.state - # register: state_exists + # - name: Check if state file exists + # ansible.builtin.stat: + # path: /tmp/ansible.state + # register: state_exists - # - name: Fail if state file already exists - # ansible.builtin.fail: - # msg: "Exit instance creation as a state file already exists." - # when: hosts_exists.stat.exists + # - name: Fail if state file already exists + # ansible.builtin.fail: + # msg: "Exit instance creation as a state file already exists." + # when: hosts_exists.stat.exists - - name: Get location of oci_config - ansible.builtin.set_fact: - oci_config_file: "{{lookup('env','HOME') + '/.oci/config'}}" + - name: Get location of oci_config + ansible.builtin.set_fact: + oci_config_file: "{{ lookup('env', 'HOME') + '/.oci/config' }}" - - name: Get tenancy ocid - ansible.builtin.set_fact: + - name: Get tenancy ocid + ansible.builtin.set_fact: my_tenancy_id: "{{ lookup('ini', 'tenancy section={{ oci_config_section }} file={{ oci_config_file }}') }}" - - name: Get region id - ansible.builtin.set_fact: + - name: Get region id + ansible.builtin.set_fact: my_region_id: "{{ lookup('ini', 'region section={{ oci_config_section }} file={{ oci_config_file }}') }}" - - name: Print regions selected - ansible.builtin.debug: - msg: "{{ my_region_id }}" - when: debug_enabled - - - name: Get list availbility domains - oci_identity_availability_domain_facts: - compartment_id: "{{ my_tenancy_id }}" - region: "{{ my_region_id }}" - register: result - - - name: Print availability domains - ansible.builtin.debug: - msg: "{{ result }}" - when: debug_enabled - - - name: Set list of availability domains - ansible.builtin.set_fact: - availability_domains: "{{ result.availability_domains }}" - - - name: Set to availability domain from list - ansible.builtin.set_fact: - my_availability_domain: "{{ availability_domains[ (lookup('ansible.builtin.vars', 'ad_placement')| int)-1 ].name }}" - - - name: Print availability domain ad_placement - ansible.builtin.debug: - msg: "{{ my_availability_domain }}" - when: debug_enabled - -## Get compartment id from .oci/config or env OCI_COMPARTMENT_OCID - - - name: Get compartment id - ansible.builtin.set_fact: - my_compartment_id: "{{ compartment_id | default(lookup('ansible.builtin.env', 'OCI_COMPARMENT_OCID'), true) | default(lookup('ini', 'compartment-id section={{ oci_config_section }} file={{ oci_config_file }}'), true) }}" - - - name: Print compartment id - ansible.builtin.debug: - msg: "{{ my_compartment_id }}" - when: debug_enabled - - - name: Fail when compartment_id is not defined - ansible.builtin.fail: - msg: "Variable for compartment_id is not defined." - when: my_compartment_id is not defined - - - name: Generate random hex string - ansible.builtin.set_fact: - vcn_code: "{{ query('community.general.random_string', upper=false, lower=false, override_special=hex_chars, numbers=false) }}" - vars: - hex_chars: '0123456789abcdef' - - - name: Create a virtual cloud network - oci_network_vcn: - compartment_id: "{{ my_compartment_id }}" - display_name: "Linuxvirt Virtual Cloud Network" - cidr_blocks: "10.0.0.0/16" - dns_label: "vcn" - register: result - retries: 10 - delay: 30 - until: result is not failed - - - name: Set vcn id - ansible.builtin.set_fact: - my_vcn_id: "{{ result.vcn.id }}" - - - name: Create internet_gateway - oci_network_internet_gateway: - compartment_id: "{{ my_compartment_id }}" - vcn_id: "{{ my_vcn_id }}" - is_enabled: true - display_name: "Linuxvirt Internet Gateway" - state: 'present' - register: result - retries: 10 - delay: 30 - until: result is not failed - - - name: Set internet gateway id - ansible.builtin.set_fact: - my_internet_gateway_id: "{{ result.internet_gateway.id }}" - - - name: Create route_table - oci_network_route_table: - compartment_id: "{{ my_compartment_id }}" - vcn_id: "{{ my_vcn_id }}" - display_name: "Linuxvirt Route Table" - route_rules: - - network_entity_id: "{{ my_internet_gateway_id }}" - cidr_block: "0.0.0.0/0" - destination_type: CIDR_BLOCK - state: 'present' - register: result - retries: 10 - delay: 30 - until: result is not failed - - - name: Set route table id - ansible.builtin.set_fact: - my_rt_id: "{{ result.route_table.id }}" - - - name: Create security_list - oci_network_security_list: - display_name: "Linuxvirt Security List" - compartment_id: "{{ my_compartment_id }}" - vcn_id: "{{ my_vcn_id }}" - egress_security_rules: - - destination: "0.0.0.0/0" - protocol: 6 - ingress_security_rules: - - source: "0.0.0.0/0" - protocol: 6 - tcp_options: - destination_port_range: - max: 22 - min: 22 - register: result - retries: 10 - delay: 30 - until: result is not failed - - - name: Set security list id - ansible.builtin.set_fact: - my_security_list_id: "{{ result.security_list.id }}" - - - name: Create subnet - oci_network_subnet: - compartment_id: "{{ my_compartment_id }}" - vcn_id: "{{ my_vcn_id }}" - cidr_block: "10.0.0.48/28" - display_name: "Linuxvirt Subnet" - prohibit_public_ip_on_vnic: false - route_table_id: "{{ my_rt_id }}" - security_list_ids: "{{ my_security_list_id }}" - dns_label: "lv" - register: result - retries: 10 - delay: 30 - until: result is not failed - - - name: Set subnet id - ansible.builtin.set_fact: - my_subnet_id: "{{ result.subnet.id }}" - - - name: Get image - oci_compute_image_facts: - compartment_id: "{{ my_compartment_id }}" - operating_system: "{{ os }}" - operating_system_version: "{{ os_version }}" - shape: "{{ instance_shape }}" - sort_by: TIMECREATED - sort_order: DESC - register: result - retries: 10 - delay: 30 - until: result is not failed - - - name: Print image list - ansible.builtin.debug: - var: result - when: debug_enabled - - - name: Set compute image id - ansible.builtin.set_fact: - ol_image_id: "{{ result.images[0].id }}" - - # - name: Create the state file - # ansible.builtin.copy: - # dest: /tmp/ansible.state - # content: | - # vcn_id: {{ my_vcn_id }} - # internet_gateway_id: {{ my_internet_gateway_id }} - # route_table_id: {{ my_rt_id }} - # security_list_id: {{ my_security_list_id }} - # subnet_id: {{ my_subnet_id }} - - - name: Build an instance - ansible.builtin.include_tasks: "build.yaml" - loop: "{{ lookup('dict', compute_instances) }}" - - - name: Print in-memory inventory - ansible.builtin.debug: - msg: "{{ groups['in_memory'] }}" - when: debug_enabled + - name: Print regions selected + ansible.builtin.debug: + msg: "{{ my_region_id }}" + when: debug_enabled + + - name: Get list availbility domains + oracle.oci.oci_identity_availability_domain_facts: + compartment_id: "{{ my_tenancy_id }}" + region: "{{ my_region_id }}" + register: result + retries: 10 + delay: 30 + until: result is not failed + + - name: Print availability domains + ansible.builtin.debug: + msg: "{{ result }}" + when: debug_enabled + + - name: Set list of availability domains + ansible.builtin.set_fact: + availability_domains: "{{ result.availability_domains }}" + + - name: Set to availability domain from list + ansible.builtin.set_fact: + my_availability_domain: "{{ availability_domains[(lookup('ansible.builtin.vars', 'ad_placement') | int) - 1].name }}" + + - name: Print availability domain ad_placement + ansible.builtin.debug: + msg: "{{ my_availability_domain }}" + when: debug_enabled + + - name: Get compartment id from .oci/config or env OCI_COMPARTMENT_OCID + vars: + env_lookup: "{{ lookup('ansible.builtin.env', 'OCI_COMPARMENT_OCID') }}" + ini_lookup: "{{ lookup('ini', 'compartment-id section={{ oci_config_section }} file={{ oci_config_file }}') }}" + ansible.builtin.set_fact: + my_compartment_id: "{{ compartment_id | default(env_lookup, true) | default(ini_lookup, true) }}" + + - name: Print compartment id + ansible.builtin.debug: + msg: "{{ my_compartment_id }}" + when: debug_enabled + + - name: Fail when compartment_id is not defined + ansible.builtin.fail: + msg: "Variable for compartment_id is not defined." + when: my_compartment_id is not defined + + - name: Generate random hex string + vars: + hex_chars: '0123456789abcdef' + ansible.builtin.set_fact: + vcn_code: "{{ query('community.general.random_string', upper=false, lower=false, override_special=hex_chars, numbers=false) }}" + + - name: Create a virtual cloud network + oracle.oci.oci_network_vcn: + compartment_id: "{{ my_compartment_id }}" + display_name: "Linuxvirt Virtual Cloud Network" + cidr_blocks: "10.0.0.0/16" + dns_label: "vcn" + register: result + retries: 10 + delay: 30 + until: result is not failed + + - name: Set vcn id + ansible.builtin.set_fact: + my_vcn_id: "{{ result.vcn.id }}" + + - name: Create internet_gateway + oracle.oci.oci_network_internet_gateway: + compartment_id: "{{ my_compartment_id }}" + vcn_id: "{{ my_vcn_id }}" + is_enabled: true + display_name: "Linuxvirt Internet Gateway" + state: 'present' + register: result + retries: 10 + delay: 30 + until: result is not failed + + - name: Set internet gateway id + ansible.builtin.set_fact: + my_internet_gateway_id: "{{ result.internet_gateway.id }}" + + - name: Create route_table + oracle.oci.oci_network_route_table: + compartment_id: "{{ my_compartment_id }}" + vcn_id: "{{ my_vcn_id }}" + display_name: "Linuxvirt Route Table" + route_rules: + - network_entity_id: "{{ my_internet_gateway_id }}" + cidr_block: "0.0.0.0/0" + destination_type: CIDR_BLOCK + state: 'present' + register: result + retries: 10 + delay: 30 + until: result is not failed + + - name: Set route table id + ansible.builtin.set_fact: + my_rt_id: "{{ result.route_table.id }}" + + - name: Create ingress rules yaml list + ansible.builtin.template: + src: ingress_security_rules.j2 + dest: /tmp/instance_ingress_security_rules.yaml + mode: "0664" + + - name: Create egress rules yaml list + ansible.builtin.template: + src: egress_security_rules.j2 + dest: /tmp/instance_egress_security_rules.yaml + mode: "0664" + + - name: Load the variables defined in the ingress rules yaml list + ansible.builtin.include_vars: + file: /tmp/instance_ingress_security_rules.yaml + name: loaded_ingress + + - name: Print loaded_ingress + ansible.builtin.debug: + msg: "loaded ingress is {{ loaded_ingress }}" + when: debug_enabled + + - name: Load the variables defined in the egress rules yaml list + ansible.builtin.include_vars: + file: /tmp/instance_egress_security_rules.yaml + name: loaded_egress + + - name: Print loaded_egress + ansible.builtin.debug: + msg: "loaded egress is {{ loaded_egress }}" + when: debug_enabled + + - name: Create security_list + oracle.oci.oci_network_security_list: + display_name: "Linuxvirt Security List" + compartment_id: "{{ my_compartment_id }}" + vcn_id: "{{ my_vcn_id }}" + ingress_security_rules: "{{ loaded_ingress.instance_ingress_security_rules }}" + egress_security_rules: "{{ loaded_egress.instance_egress_security_rules }}" + register: result + retries: 10 + delay: 30 + until: result is not failed + + - name: Set security list id + ansible.builtin.set_fact: + my_security_list_id: "{{ result.security_list.id }}" + + - name: Create subnet + oracle.oci.oci_network_subnet: + compartment_id: "{{ my_compartment_id }}" + vcn_id: "{{ my_vcn_id }}" + cidr_block: "{{ subnet_cidr_block }}" + display_name: "Linuxvirt Subnet" + prohibit_public_ip_on_vnic: false + route_table_id: "{{ my_rt_id }}" + security_list_ids: "{{ my_security_list_id }}" + dns_label: "lv" + register: result + retries: 10 + delay: 30 + until: result is not failed + + - name: Set subnet id + ansible.builtin.set_fact: + my_subnet_id: "{{ result.subnet.id }}" + + - name: Set subnet domain_name + ansible.builtin.set_fact: + my_subnet_domain_name: "{{ result.subnet.subnet_domain_name }}" + + - name: Set oci vars file + ansible.builtin.template: + src: oci_vars.j2 + dest: oci_vars.yml + mode: "0664" + + - name: Get image + oracle.oci.oci_compute_image_facts: + compartment_id: "{{ my_compartment_id }}" + operating_system: "{{ os }}" + operating_system_version: "{{ os_version }}" + shape: "{{ instance_shape }}" + sort_by: TIMECREATED + sort_order: DESC + register: result + retries: 10 + delay: 30 + until: result is not failed + + - name: Print image list + ansible.builtin.debug: + var: result + when: debug_enabled + + - name: Set compute image id + ansible.builtin.set_fact: + ol_image_id: "{{ result.images[0].id }}" + + - name: Build an instance + ansible.builtin.include_tasks: "build.yml" + loop: "{{ lookup('dict', compute_instances, wantlist=True) }}" - name: Configure new instances - hosts: in_memory - become: yes + hosts: all gather_facts: false + vars_files: + - default_vars.yml + - oci_vars.yml vars: username: "oracle" user_default_password: "oracle" private_key: "id_rsa" debug_enabled: false - + + tasks: + + - name: Print in-memory inventory + ansible.builtin.debug: + msg: "{{ groups['all'] }}" + delegate_to: localhost + when: + - debug_enabled + - inventory_hostname == ansible_play_hosts_all[0] + + - name: Print all variables/facts known for a host + ansible.builtin.debug: + msg: "{{ hostvars[item] }}" + loop: "{{ groups['all'] | flatten(levels=1) }}" + delegate_to: localhost + when: + - debug_enabled + - inventory_hostname == ansible_play_hosts_all[0] + + - name: Configure instance + ansible.builtin.include_tasks: "host_setup.yml" + + - name: Configure passwordless SSH + ansible.builtin.include_tasks: "passwordless_setup.yml" + when: passwordless_ssh + +- name: Update all rpm packages + ansible.builtin.import_playbook: update_all_rpms.yml + when: update_all + +- name: Provision KVM server + ansible.builtin.import_playbook: provision_kvm.yml + when: use_kvm + +- name: Provision Podman and Container Tools + ansible.builtin.import_playbook: provision_podman.yml + when: use_podman + +- name: Provision VNC Server + ansible.builtin.import_playbook: provision_vnc.yml + when: use_vnc + +- name: Provision VirtualBox + ansible.builtin.import_playbook: provision_vbox.yml + when: use_vbox + +- name: Download OL ISO + ansible.builtin.import_playbook: download_ol_iso.yml + when: dwnld_ol_iso + +- name: Print instances + hosts: all + become: true + gather_facts: false + vars_files: + - ocir_vars.yml + tasks: - - name: Wait for system to become reachable - ansible.builtin.wait_for_connection: - - - name: Run facts module to get latest information - ansible.builtin.setup: - - - name: Add user account with access to sudo - ansible.builtin.user: - name: "{{ username }}" - password: "{{ user_default_password | password_hash('sha512') }}" - comment: Ansible created user - groups: wheel - append: yes - update_password: on_create - - - name: Set authorized key for user using local pubilc key file - ansible.posix.authorized_key: - user: "{{ username }}" - state: present - key: "{{ lookup('file', lookup('env','HOME') + '/.ssh/' + private_key + '.pub' ) }}" - - - name: Set user with passwordless sudo access - ansible.builtin.lineinfile: - path: '/etc/sudoers.d/{{ username }}' - regexp: '{{ username }} ALL=' - line: '{{ username}} ALL=(ALL:ALL) NOPASSWD: ALL' - state: present - create: yes - - - name: Add locale settings to .bashrc - ansible.builtin.lineinfile: - dest: ~/.bashrc - line: "{{ item }}" - with_items: - - 'export LC_ALL="en_US.UTF-8"' - - 'export LC_CTYPE="en_US.UTF-8"' - become_user: "{{ username }}" - - - name: Generate ssh keypair for user - community.crypto.openssh_keypair: - path: ~/.ssh/id_rsa - size: 2048 - comment: ocne ssh keypair - become_user: "{{ username }}" - - - name: Fetch public key file from server - ansible.builtin.fetch: - src: "~/.ssh/id_rsa.pub" - dest: "buffer/{{ inventory_hostname }}-id_rsa.pub" - flat: yes - become_user: "{{ username }}" - - - name: Copy public key to each destination - ansible.posix.authorized_key: - user: "{{ username }}" - state: present - key: "{{ lookup('file', 'buffer/{{ item }}-id_rsa.pub') }}" - loop: "{{ groups['in_memory'] | flatten(levels=1) }}" - - - name: Print hostvars for groups - ansible.builtin.debug: - msg: "{{ hostvars[item] }}" - loop: "{{ groups['in_memory'] | flatten(levels=1) }}" - when: debug_enabled - - - name: Accept new ssh fingerprints - ansible.builtin.shell: | - ssh-keyscan -t ecdsa-sha2-nistp256 {{ hostvars[item].ansible_host }} >> ~/.ssh/known_hosts - with_items: - - "{{ groups['in_memory'] }}" - become_user: "{{ username }}" - - - name: Install Oracle Linux Automation Manager - ansible.builtin.include_tasks: deploy-olam-tasks.yaml - vars: - control_node_ip: "{{ hostvars[inventory_hostname]['ansible_default_ipv4']['address'] }}" - when: inventory_hostname == 'olam-node' - - - name: Print instance details - ansible.builtin.debug: - msg: - - "Instance name: {{ hostvars[inventory_hostname]['ansible_hostname'] }}" - - " public ip: {{ hostvars[inventory_hostname]['ansible_host'] }}" - - " private ip: {{ hostvars[inventory_hostname]['ansible_default_ipv4']['address'] }}" - - - name: Pause play to interact with the servers - ansible.builtin.pause: - prompt: "Playbook paused... hit to continue or then to abort. Aborting at this stage requires manual removal of all cloud resources this playbook creates." + - name: Print instance details + ansible.builtin.debug: + msg: + - "Instance details:" + - " name: {{ hostvars[inventory_hostname]['ansible_hostname'] }}" + - " public ip: {{ hostvars[inventory_hostname]['ansible_host'] }}" + - " private ip: {{ hostvars[inventory_hostname]['ansible_default_ipv4']['address'] }}" + + - name: Pause play to interact with the servers + ansible.builtin.pause: + prompt: | + Playbook paused... hit to continue or then to abort. + Aborting at this stage requires manual removal of all cloud resources this playbook creates. - name: Terminate instances and delete OCI resources hosts: localhost - collections: - - oracle.oci - - community.general + vars_files: + - default_vars.yml + vars: + ansible_python_interpreter: "{{ localhost_python_interpreter | default(omit) }}" tasks: - - name: Terminate the instances - oci_compute_instance: - id: "{{ hostvars[item]['instance_ocid'] }}" - state: absent - loop: "{{ groups['in_memory'] | flatten(levels=1) }}" - - - name: Delete the subnet - oci_network_subnet: - id: "{{ my_subnet_id }}" - state: absent - - - name: Delete the security list - oci_network_security_list: - id: "{{ my_security_list_id }}" - state: absent - - - name: Delete the route table - oci_network_route_table: - id: "{{ my_rt_id }}" - state: absent - - - name: Delete the Internet Gateway - oci_network_internet_gateway: - id: "{{ my_internet_gateway_id }}" - state: absent - - - name: Delete the VCN - oci_network_vcn: - vcn_id: "{{ my_vcn_id }}" - state: absent \ No newline at end of file + - name: Terminate the instances + oracle.oci.oci_compute_instance: + id: "{{ hostvars[item]['instance_ocid'] }}" + state: absent + loop: "{{ groups['all'] | flatten(levels=1) }}" + + - name: Delete the subnet + oracle.oci.oci_network_subnet: + id: "{{ my_subnet_id }}" + state: absent + + - name: Delete the security list + oracle.oci.oci_network_security_list: + id: "{{ my_security_list_id }}" + state: absent + + - name: Delete the route table + oracle.oci.oci_network_route_table: + id: "{{ my_rt_id }}" + state: absent + + - name: Delete the Internet Gateway + oracle.oci.oci_network_internet_gateway: + id: "{{ my_internet_gateway_id }}" + state: absent + + - name: Delete the VCN + oracle.oci.oci_network_vcn: + vcn_id: "{{ my_vcn_id }}" + state: absent + + - name: Remove artifacts + ansible.builtin.file: + state: absent + path: "{{ item }}" + loop: + - oci_vars.yml diff --git a/olam/create_instance_1.yaml b/olam/create_instance_1.yaml new file mode 100644 index 0000000..025f649 --- /dev/null +++ b/olam/create_instance_1.yaml @@ -0,0 +1,379 @@ +--- +# Copyright (c) 2024 Oracle and/or its affiliates. +# This software is made available to you under the terms of the Universal Permissive License (UPL), Version 1.0. +# The Universal Permissive License (UPL), Version 1.0 (see COPYING or https://oss.oracle.com/licenses/upl) +# See LICENSE.TXT for details. + +- name: Gather facts and create instances + hosts: localhost + collections: + - oracle.oci + - community.general + + vars: + oci_config_section: DEFAULT + ad_placement: 1 + compartment_name: + compartment_id: + compute_instances: + 1: + instance_name: "control-node" + 2: + instance_name: "olam-node" + os: "Oracle Linux" + os_version: "8" + instance_shape: "VM.Standard.E4.Flex" + instance_ocpus: 2 + instance_memory: 16 + private_key: "id_rsa" + # ansible_python_interpreter: /usr/bin/python3.6 + debug_enabled: false + + tasks: + + # - name: Check if state file exists + # ansible.builtin.stat: + # path: /tmp/ansible.state + # register: state_exists + + # - name: Fail if state file already exists + # ansible.builtin.fail: + # msg: "Exit instance creation as a state file already exists." + # when: hosts_exists.stat.exists + + - name: Get location of oci_config + ansible.builtin.set_fact: + oci_config_file: "{{lookup('env','HOME') + '/.oci/config'}}" + + - name: Get tenancy ocid + ansible.builtin.set_fact: + my_tenancy_id: "{{ lookup('ini', 'tenancy section={{ oci_config_section }} file={{ oci_config_file }}') }}" + + - name: Get region id + ansible.builtin.set_fact: + my_region_id: "{{ lookup('ini', 'region section={{ oci_config_section }} file={{ oci_config_file }}') }}" + + - name: Print regions selected + ansible.builtin.debug: + msg: "{{ my_region_id }}" + when: debug_enabled + + - name: Get list availbility domains + oci_identity_availability_domain_facts: + compartment_id: "{{ my_tenancy_id }}" + region: "{{ my_region_id }}" + register: result + + - name: Print availability domains + ansible.builtin.debug: + msg: "{{ result }}" + when: debug_enabled + + - name: Set list of availability domains + ansible.builtin.set_fact: + availability_domains: "{{ result.availability_domains }}" + + - name: Set to availability domain from list + ansible.builtin.set_fact: + my_availability_domain: "{{ availability_domains[ (lookup('ansible.builtin.vars', 'ad_placement')| int)-1 ].name }}" + + - name: Print availability domain ad_placement + ansible.builtin.debug: + msg: "{{ my_availability_domain }}" + when: debug_enabled + +## Get compartment id from .oci/config or env OCI_COMPARTMENT_OCID + + - name: Get compartment id + ansible.builtin.set_fact: + my_compartment_id: "{{ compartment_id | default(lookup('ansible.builtin.env', 'OCI_COMPARMENT_OCID'), true) | default(lookup('ini', 'compartment-id section={{ oci_config_section }} file={{ oci_config_file }}'), true) }}" + + - name: Print compartment id + ansible.builtin.debug: + msg: "{{ my_compartment_id }}" + when: debug_enabled + + - name: Fail when compartment_id is not defined + ansible.builtin.fail: + msg: "Variable for compartment_id is not defined." + when: my_compartment_id is not defined + + - name: Generate random hex string + ansible.builtin.set_fact: + vcn_code: "{{ query('community.general.random_string', upper=false, lower=false, override_special=hex_chars, numbers=false) }}" + vars: + hex_chars: '0123456789abcdef' + + - name: Create a virtual cloud network + oci_network_vcn: + compartment_id: "{{ my_compartment_id }}" + display_name: "Linuxvirt Virtual Cloud Network" + cidr_blocks: "10.0.0.0/16" + dns_label: "vcn" + register: result + retries: 10 + delay: 30 + until: result is not failed + + - name: Set vcn id + ansible.builtin.set_fact: + my_vcn_id: "{{ result.vcn.id }}" + + - name: Create internet_gateway + oci_network_internet_gateway: + compartment_id: "{{ my_compartment_id }}" + vcn_id: "{{ my_vcn_id }}" + is_enabled: true + display_name: "Linuxvirt Internet Gateway" + state: 'present' + register: result + retries: 10 + delay: 30 + until: result is not failed + + - name: Set internet gateway id + ansible.builtin.set_fact: + my_internet_gateway_id: "{{ result.internet_gateway.id }}" + + - name: Create route_table + oci_network_route_table: + compartment_id: "{{ my_compartment_id }}" + vcn_id: "{{ my_vcn_id }}" + display_name: "Linuxvirt Route Table" + route_rules: + - network_entity_id: "{{ my_internet_gateway_id }}" + cidr_block: "0.0.0.0/0" + destination_type: CIDR_BLOCK + state: 'present' + register: result + retries: 10 + delay: 30 + until: result is not failed + + - name: Set route table id + ansible.builtin.set_fact: + my_rt_id: "{{ result.route_table.id }}" + + - name: Create security_list + oci_network_security_list: + display_name: "Linuxvirt Security List" + compartment_id: "{{ my_compartment_id }}" + vcn_id: "{{ my_vcn_id }}" + egress_security_rules: + - destination: "0.0.0.0/0" + protocol: 6 + ingress_security_rules: + - source: "0.0.0.0/0" + protocol: 6 + tcp_options: + destination_port_range: + max: 22 + min: 22 + register: result + retries: 10 + delay: 30 + until: result is not failed + + - name: Set security list id + ansible.builtin.set_fact: + my_security_list_id: "{{ result.security_list.id }}" + + - name: Create subnet + oci_network_subnet: + compartment_id: "{{ my_compartment_id }}" + vcn_id: "{{ my_vcn_id }}" + cidr_block: "10.0.0.48/28" + display_name: "Linuxvirt Subnet" + prohibit_public_ip_on_vnic: false + route_table_id: "{{ my_rt_id }}" + security_list_ids: "{{ my_security_list_id }}" + dns_label: "lv" + register: result + retries: 10 + delay: 30 + until: result is not failed + + - name: Set subnet id + ansible.builtin.set_fact: + my_subnet_id: "{{ result.subnet.id }}" + + - name: Get image + oci_compute_image_facts: + compartment_id: "{{ my_compartment_id }}" + operating_system: "{{ os }}" + operating_system_version: "{{ os_version }}" + shape: "{{ instance_shape }}" + sort_by: TIMECREATED + sort_order: DESC + register: result + retries: 10 + delay: 30 + until: result is not failed + + - name: Print image list + ansible.builtin.debug: + var: result + when: debug_enabled + + - name: Set compute image id + ansible.builtin.set_fact: + ol_image_id: "{{ result.images[0].id }}" + + # - name: Create the state file + # ansible.builtin.copy: + # dest: /tmp/ansible.state + # content: | + # vcn_id: {{ my_vcn_id }} + # internet_gateway_id: {{ my_internet_gateway_id }} + # route_table_id: {{ my_rt_id }} + # security_list_id: {{ my_security_list_id }} + # subnet_id: {{ my_subnet_id }} + + - name: Build an instance + ansible.builtin.include_tasks: "build.yaml" + loop: "{{ lookup('dict', compute_instances) }}" + + - name: Print in-memory inventory + ansible.builtin.debug: + msg: "{{ groups['in_memory'] }}" + when: debug_enabled + +- name: Configure new instances + hosts: in_memory + become: yes + gather_facts: false + vars: + username: "oracle" + user_default_password: "oracle" + private_key: "id_rsa" + debug_enabled: false + + tasks: + + - name: Wait for system to become reachable + ansible.builtin.wait_for_connection: + + - name: Run facts module to get latest information + ansible.builtin.setup: + + - name: Add user account with access to sudo + ansible.builtin.user: + name: "{{ username }}" + password: "{{ user_default_password | password_hash('sha512') }}" + comment: Ansible created user + groups: wheel + append: yes + update_password: on_create + + - name: Set authorized key for user using local pubilc key file + ansible.posix.authorized_key: + user: "{{ username }}" + state: present + key: "{{ lookup('file', lookup('env','HOME') + '/.ssh/' + private_key + '.pub' ) }}" + + - name: Set user with passwordless sudo access + ansible.builtin.lineinfile: + path: '/etc/sudoers.d/{{ username }}' + regexp: '{{ username }} ALL=' + line: '{{ username}} ALL=(ALL:ALL) NOPASSWD: ALL' + state: present + create: yes + + - name: Add locale settings to .bashrc + ansible.builtin.lineinfile: + dest: ~/.bashrc + line: "{{ item }}" + with_items: + - 'export LC_ALL="en_US.UTF-8"' + - 'export LC_CTYPE="en_US.UTF-8"' + become_user: "{{ username }}" + + - name: Generate ssh keypair for user + community.crypto.openssh_keypair: + path: ~/.ssh/id_rsa + size: 2048 + comment: ocne ssh keypair + become_user: "{{ username }}" + + - name: Fetch public key file from server + ansible.builtin.fetch: + src: "~/.ssh/id_rsa.pub" + dest: "buffer/{{ inventory_hostname }}-id_rsa.pub" + flat: yes + become_user: "{{ username }}" + + - name: Copy public key to each destination + ansible.posix.authorized_key: + user: "{{ username }}" + state: present + key: "{{ lookup('file', 'buffer/{{ item }}-id_rsa.pub') }}" + loop: "{{ groups['in_memory'] | flatten(levels=1) }}" + + - name: Print hostvars for groups + ansible.builtin.debug: + msg: "{{ hostvars[item] }}" + loop: "{{ groups['in_memory'] | flatten(levels=1) }}" + when: debug_enabled + + - name: Accept new ssh fingerprints + ansible.builtin.shell: | + ssh-keyscan -t ecdsa-sha2-nistp256 {{ hostvars[item].ansible_host }} >> ~/.ssh/known_hosts + with_items: + - "{{ groups['in_memory'] }}" + become_user: "{{ username }}" + + - name: Install Oracle Linux Automation Manager + ansible.builtin.include_tasks: deploy-olam-tasks.yaml + vars: + control_node_ip: "{{ hostvars[inventory_hostname]['ansible_default_ipv4']['address'] }}" + when: inventory_hostname == 'olam-node' + + - name: Print instance details + ansible.builtin.debug: + msg: + - "Instance name: {{ hostvars[inventory_hostname]['ansible_hostname'] }}" + - " public ip: {{ hostvars[inventory_hostname]['ansible_host'] }}" + - " private ip: {{ hostvars[inventory_hostname]['ansible_default_ipv4']['address'] }}" + + - name: Pause play to interact with the servers + ansible.builtin.pause: + prompt: "Playbook paused... hit to continue or then to abort. Aborting at this stage requires manual removal of all cloud resources this playbook creates." + +- name: Terminate instances and delete OCI resources + hosts: localhost + collections: + - oracle.oci + - community.general + + tasks: + + - name: Terminate the instances + oci_compute_instance: + id: "{{ hostvars[item]['instance_ocid'] }}" + state: absent + loop: "{{ groups['in_memory'] | flatten(levels=1) }}" + + - name: Delete the subnet + oci_network_subnet: + id: "{{ my_subnet_id }}" + state: absent + + - name: Delete the security list + oci_network_security_list: + id: "{{ my_security_list_id }}" + state: absent + + - name: Delete the route table + oci_network_route_table: + id: "{{ my_rt_id }}" + state: absent + + - name: Delete the Internet Gateway + oci_network_internet_gateway: + id: "{{ my_internet_gateway_id }}" + state: absent + + - name: Delete the VCN + oci_network_vcn: + vcn_id: "{{ my_vcn_id }}" + state: absent \ No newline at end of file diff --git a/olam/default_vars.yml b/olam/default_vars.yml new file mode 100644 index 0000000..e69de29 diff --git a/olam/requirements.yaml b/olam/requirements.yaml index c6c0774..fa329b2 100644 --- a/olam/requirements.yaml +++ b/olam/requirements.yaml @@ -24,5 +24,9 @@ collections: version: main - name: https://github.com/ansible-collections/community.crypto.git + type: git + version: main + + - name: https://github.com/ansible-collections/community.libvirt.git type: git version: main \ No newline at end of file diff --git a/olam/templates/egress_security_rules.j2 b/olam/templates/egress_security_rules.j2 new file mode 100644 index 0000000..f89f2e6 --- /dev/null +++ b/olam/templates/egress_security_rules.j2 @@ -0,0 +1,9 @@ +--- +# Copyright (c) 2024 Oracle and/or its affiliates. +# This software is made available to you under the terms of the Universal Permissive License (UPL), Version 1.0. +# The Universal Permissive License (UPL), Version 1.0 (see COPYING or https://oss.oracle.com/licenses/upl) +# See LICENSE.TXT for details. + +instance_egress_security_rules: + - destination: "0.0.0.0/0" + protocol: 6 \ No newline at end of file diff --git a/olam/templates/ingress_security_rules.j2 b/olam/templates/ingress_security_rules.j2 new file mode 100644 index 0000000..c4f607e --- /dev/null +++ b/olam/templates/ingress_security_rules.j2 @@ -0,0 +1,88 @@ +--- +# Copyright (c) 2024 Oracle and/or its affiliates. +# This software is made available to you under the terms of the Universal Permissive License (UPL), Version 1.0. +# The Universal Permissive License (UPL), Version 1.0 (see COPYING or https://oss.oracle.com/licenses/upl) +# See LICENSE.TXT for details. + +instance_ingress_security_rules: + # Allow incoming SSH connections + - source: "0.0.0.0/0" + protocol: 6 + tcp_options: + destination_port_range: + max: 22 + min: 22 +{% if use_haproxy %} + - source: "10.0.0.0/24" + protocol: 6 + tcp_options: + destination_port_range: + max: 8080 + min: 8080 +{% endif %} +{% if use_nginx %} + - source: "0.0.0.0/0" + protocol: 6 + tcp_options: + destination_port_range: + max: 80 + min: 80 + - source: "0.0.0.0/0" + protocol: 6 + tcp_options: + destination_port_range: + max: 443 + min: 443 + - source: "0.0.0.0/0" + protocol: 6 + tcp_options: + destination_port_range: + max: 8080 + min: 8080 +{% endif %} +{% if use_nfs %} + - source: "10.0.0.0/24" + protocol: 6 + tcp_options: + destination_port_range: + max: 2049 + min: 2049 + - source: "10.0.0.0/24" + protocol: 17 + udp_options: + destination_port_range: + max: 2049 + min: 2049 +{% endif %} +{% if use_quay_ha %} + - source: "10.0.0.0/24" + protocol: 6 + tcp_options: + destination_port_range: + max: 2049 + min: 2049 + - source: "10.0.0.0/24" + protocol: 17 + udp_options: + destination_port_range: + max: 2049 + min: 2049 + - source: "10.0.0.0/24" + protocol: 6 + tcp_options: + destination_port_range: + max: 8080 + min: 8080 + - source: "10.0.0.0/24" + protocol: 6 + tcp_options: + destination_port_range: + max: 5432 + min: 5432 + - source: "10.0.0.0/24" + protocol: 6 + tcp_options: + destination_port_range: + max: 6379 + min: 6379 +{% endif %} \ No newline at end of file From b72c8f4005df77c6d200a3fab6717201932099e6 Mon Sep 17 00:00:00 2001 From: William Graef Date: Wed, 6 Nov 2024 11:45:02 -0500 Subject: [PATCH 02/16] fix ext to yml --- olam/{build.yaml => build.yml} | 0 olam/{create_instance.yaml => create_instance.yml} | 0 olam/{create_instance_1.yaml => create_instance_1.yml} | 0 olam/{deploy-olam-tasks.yaml => deploy-olam-tasks.yml} | 0 olam/{get_facts.yaml => get_facts.yml} | 0 olam/{requirements.yaml => requirements.yml} | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename olam/{build.yaml => build.yml} (100%) rename olam/{create_instance.yaml => create_instance.yml} (100%) rename olam/{create_instance_1.yaml => create_instance_1.yml} (100%) rename olam/{deploy-olam-tasks.yaml => deploy-olam-tasks.yml} (100%) rename olam/{get_facts.yaml => get_facts.yml} (100%) rename olam/{requirements.yaml => requirements.yml} (100%) diff --git a/olam/build.yaml b/olam/build.yml similarity index 100% rename from olam/build.yaml rename to olam/build.yml diff --git a/olam/create_instance.yaml b/olam/create_instance.yml similarity index 100% rename from olam/create_instance.yaml rename to olam/create_instance.yml diff --git a/olam/create_instance_1.yaml b/olam/create_instance_1.yml similarity index 100% rename from olam/create_instance_1.yaml rename to olam/create_instance_1.yml diff --git a/olam/deploy-olam-tasks.yaml b/olam/deploy-olam-tasks.yml similarity index 100% rename from olam/deploy-olam-tasks.yaml rename to olam/deploy-olam-tasks.yml diff --git a/olam/get_facts.yaml b/olam/get_facts.yml similarity index 100% rename from olam/get_facts.yaml rename to olam/get_facts.yml diff --git a/olam/requirements.yaml b/olam/requirements.yml similarity index 100% rename from olam/requirements.yaml rename to olam/requirements.yml From 30a2b3c93b413fa728bd155a2dc63f98e13f198a Mon Sep 17 00:00:00 2001 From: William Graef Date: Wed, 6 Nov 2024 11:49:24 -0500 Subject: [PATCH 03/16] add update all rpms --- olam/update_all_rpms.yml | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 olam/update_all_rpms.yml diff --git a/olam/update_all_rpms.yml b/olam/update_all_rpms.yml new file mode 100644 index 0000000..d10b15b --- /dev/null +++ b/olam/update_all_rpms.yml @@ -0,0 +1,37 @@ +--- +# Copyright (c) 2024 Oracle and/or its affiliates. +# This software is made available to you under the terms of the Universal Permissive License (UPL), Version 1.0. +# The Universal Permissive License (UPL), Version 1.0 (see COPYING or https://oss.oracle.com/licenses/upl) +# See LICENSE.TXT for details. + +- name: Install latest Oracle Linux packages + hosts: server,vbox + vars_files: + - default_vars.yml + become: true + + tasks: + + - name: Update all Oracle Linux packages + ansible.builtin.dnf: + name: "*" + state: latest + update_only: true + when: ansible_distribution == 'OracleLinux' + + - name: Check if a reboot is required + ansible.builtin.command: /usr/bin/needs-restarting -r + register: reboot_required + ignore_errors: true + changed_when: false + failed_when: reboot_required.rc == 2 + when: ansible_distribution == 'OracleLinux' + + - name: Print reboot is required + ansible.builtin.debug: + var: reboot_required + when: debug_enabled + + - name: Reboot (if needed) to apply latest kernel and updates + ansible.builtin.reboot: + when: ansible_distribution == 'OracleLinux' and reboot_required.rc == 1 From d3276fc69a77f14587ff72a2a9766293ef5e34a2 Mon Sep 17 00:00:00 2001 From: William Graef Date: Wed, 6 Nov 2024 11:52:38 -0500 Subject: [PATCH 04/16] remove extra tasks --- olam/create_instance.yml | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/olam/create_instance.yml b/olam/create_instance.yml index b2215b1..68fb1f7 100644 --- a/olam/create_instance.yml +++ b/olam/create_instance.yml @@ -303,26 +303,6 @@ ansible.builtin.import_playbook: update_all_rpms.yml when: update_all -- name: Provision KVM server - ansible.builtin.import_playbook: provision_kvm.yml - when: use_kvm - -- name: Provision Podman and Container Tools - ansible.builtin.import_playbook: provision_podman.yml - when: use_podman - -- name: Provision VNC Server - ansible.builtin.import_playbook: provision_vnc.yml - when: use_vnc - -- name: Provision VirtualBox - ansible.builtin.import_playbook: provision_vbox.yml - when: use_vbox - -- name: Download OL ISO - ansible.builtin.import_playbook: download_ol_iso.yml - when: dwnld_ol_iso - - name: Print instances hosts: all become: true From d93086698f3eed584a1c23d85d4be5a6471f19ee Mon Sep 17 00:00:00 2001 From: William Graef Date: Wed, 6 Nov 2024 11:55:22 -0500 Subject: [PATCH 05/16] remove excess ingress rules --- olam/templates/ingress_security_rules.j2 | 76 +----------------------- 1 file changed, 1 insertion(+), 75 deletions(-) diff --git a/olam/templates/ingress_security_rules.j2 b/olam/templates/ingress_security_rules.j2 index c4f607e..db769f6 100644 --- a/olam/templates/ingress_security_rules.j2 +++ b/olam/templates/ingress_security_rules.j2 @@ -11,78 +11,4 @@ instance_ingress_security_rules: tcp_options: destination_port_range: max: 22 - min: 22 -{% if use_haproxy %} - - source: "10.0.0.0/24" - protocol: 6 - tcp_options: - destination_port_range: - max: 8080 - min: 8080 -{% endif %} -{% if use_nginx %} - - source: "0.0.0.0/0" - protocol: 6 - tcp_options: - destination_port_range: - max: 80 - min: 80 - - source: "0.0.0.0/0" - protocol: 6 - tcp_options: - destination_port_range: - max: 443 - min: 443 - - source: "0.0.0.0/0" - protocol: 6 - tcp_options: - destination_port_range: - max: 8080 - min: 8080 -{% endif %} -{% if use_nfs %} - - source: "10.0.0.0/24" - protocol: 6 - tcp_options: - destination_port_range: - max: 2049 - min: 2049 - - source: "10.0.0.0/24" - protocol: 17 - udp_options: - destination_port_range: - max: 2049 - min: 2049 -{% endif %} -{% if use_quay_ha %} - - source: "10.0.0.0/24" - protocol: 6 - tcp_options: - destination_port_range: - max: 2049 - min: 2049 - - source: "10.0.0.0/24" - protocol: 17 - udp_options: - destination_port_range: - max: 2049 - min: 2049 - - source: "10.0.0.0/24" - protocol: 6 - tcp_options: - destination_port_range: - max: 8080 - min: 8080 - - source: "10.0.0.0/24" - protocol: 6 - tcp_options: - destination_port_range: - max: 5432 - min: 5432 - - source: "10.0.0.0/24" - protocol: 6 - tcp_options: - destination_port_range: - max: 6379 - min: 6379 -{% endif %} \ No newline at end of file + min: 22 \ No newline at end of file From 61d02c7986e687862668203805afbd3de9d407de Mon Sep 17 00:00:00 2001 From: William Graef Date: Wed, 6 Nov 2024 12:14:17 -0500 Subject: [PATCH 06/16] cleanup ol files and add to olam deploy --- ol/build.yml | 2 +- ol/host_setup.yml | 2 +- olam/build.yml | 51 +++++++---- olam/default_vars.yml | 19 ++++ olam/host_setup.yml | 169 ++++++++++++++++++++++++++++++++++++ olam/passwordless_setup.yml | 53 +++++++++++ 6 files changed, 275 insertions(+), 21 deletions(-) create mode 100644 olam/host_setup.yml create mode 100644 olam/passwordless_setup.yml diff --git a/ol/build.yml b/ol/build.yml index 597d5c6..410f528 100644 --- a/ol/build.yml +++ b/ol/build.yml @@ -80,7 +80,7 @@ - name: Add block storage to an instance ansible.builtin.include_tasks: "block.yml" - loop: "{{ query('sequence', 'start=1 end='+(block_count)|string) }}" + loop: "{{ query('sequence', 'start=1 end=' + (block_count) | string) }}" loop_control: extended: true vars: diff --git a/ol/host_setup.yml b/ol/host_setup.yml index bcb15b9..5a77316 100644 --- a/ol/host_setup.yml +++ b/ol/host_setup.yml @@ -43,7 +43,7 @@ become: true register: result changed_when: result.rc == 0 - + - name: Add user account with access to sudo ansible.builtin.user: name: "{{ username }}" diff --git a/olam/build.yml b/olam/build.yml index 6ba3246..410f528 100644 --- a/olam/build.yml +++ b/olam/build.yml @@ -5,7 +5,7 @@ # See LICENSE.TXT for details. - name: Launch an instance - oci_compute_instance: + oracle.oci.oci_compute_instance: availability_domain: "{{ my_availability_domain }}" compartment_id: "{{ my_compartment_id }}" name: "{{ item.value.instance_name | default('instance-'~timestamp) }}" @@ -22,25 +22,25 @@ hostname_label: "{{ item.value.instance_name | default('instance-'~timestamp) }}" subnet_id: "{{ my_subnet_id }}" metadata: - ssh_authorized_keys: "{{ lookup('file', lookup('env','HOME') + '/.ssh/' + private_key + '.pub' ) }}" + ssh_authorized_keys: "{{ lookup('file', lookup('env', 'HOME') + '/.ssh/' + private_key + '.pub') }}" agent_config: is_monitoring_disabled: false is_management_disabled: false are_all_plugins_disabled: false plugins_config: - - - name: "OS Management Service Agent" - desired_state: DISABLED + - + name: "OS Management Service Agent" + desired_state: DISABLED register: result vars: timestamp: "{{ now().strftime('%Y%m%d-%H%M%S') }}" retries: 10 delay: 30 until: result is not failed - + - name: Print instance details ansible.builtin.debug: - msg: + msg: - "Launched a new instance:" - "{{ result }}" when: debug_enabled @@ -54,15 +54,21 @@ instance_display_name: "{{ result.instance.display_name }}" - name: Get the vnic attachment details of instance - oci_compute_vnic_attachment_facts: + oracle.oci.oci_compute_vnic_attachment_facts: compartment_id: "{{ my_compartment_id }}" instance_id: "{{ instance_id }}" register: result + retries: 10 + delay: 30 + until: result is not failed - name: Get vnic details - oci_network_vnic_facts: + oracle.oci.oci_network_vnic_facts: id: "{{ result.vnic_attachments[0].vnic_id }}" register: result + retries: 10 + delay: 30 + until: result is not failed - name: Set the instance private ip address ansible.builtin.set_fact: @@ -72,27 +78,34 @@ ansible.builtin.set_fact: instance_public_ip: "{{ result.vnic.public_ip }}" +- name: Add block storage to an instance + ansible.builtin.include_tasks: "block.yml" + loop: "{{ query('sequence', 'start=1 end=' + (block_count) | string) }}" + loop_control: + extended: true + vars: + block_devices: + - b + - c + - d + - e + - f + - name: Print the public and private ip of the newly created instance ansible.builtin.debug: - msg: + msg: - "Instance name: {{ instance_display_name }}" - " public ip: {{ instance_public_ip }}" - " private ip: {{ instance_private_ip }}" when: debug_enabled - + - name: Add host to in-memory host file ansible.builtin.add_host: name: "{{ instance_display_name }}" - groups: "in_memory" + groups: "{{ item.value.type }}" ansible_user: opc - ansible_ssh_private_key_file: "{{ lookup('env','HOME') + '/.ssh/' + private_key }}" + ansible_private_key_file: "{{ lookup('env', 'HOME') + '/.ssh/' + private_key }}" ansible_ssh_common_args: "-o StrictHostKeyChecking=no" ansible_host: "{{ instance_public_ip }}" ansible_port: 22 instance_ocid: "{{ instance_id }}" - -# - name: Add instance to the state file -# ansible.builtin.lineinfile: -# path: /tmp/ansible.state -# line: "id{{ groups['in_memory'].index(instance_display_name) }}: {{ instance_id }}" -# create: true diff --git a/olam/default_vars.yml b/olam/default_vars.yml index e69de29..56059ca 100644 --- a/olam/default_vars.yml +++ b/olam/default_vars.yml @@ -0,0 +1,19 @@ +compute_instances: + 1: + instance_name: "olam" + type: "server" + boot_volume_size_in_gbs: 50 +os: "Oracle Linux" +os_version: "8" +instance_shape: "VM.Standard.E4.Flex" +instance_ocpus: 2 +instance_memory: 32 +subnet_cidr_block: "10.0.0.48/28" + +username: "oracle" +usergroup: "{{ username }}" +user_default_password: "oracle" +debug_enabled: false +add_block_storage: false +block_volume_size_in_gbs: 50 +block_count: 1 \ No newline at end of file diff --git a/olam/host_setup.yml b/olam/host_setup.yml new file mode 100644 index 0000000..bcb15b9 --- /dev/null +++ b/olam/host_setup.yml @@ -0,0 +1,169 @@ +--- +# Copyright (c) 2024 Oracle and/or its affiliates. +# This software is made available to you under the terms of the Universal Permissive License (UPL), Version 1.0. +# The Universal Permissive License (UPL), Version 1.0 (see COPYING or https://oss.oracle.com/licenses/upl) +# See LICENSE.TXT for details. + +- name: Group of setup tasks for each instance + vars: + max_retries: "{{ 5 if max_retries is undefined else max_retries | int }}" + retry_delay: "{{ 10 if retry_delay is undefined else retry_delay | int }}" + block: + - name: Increment the retry count + ansible.builtin.set_fact: + retry_count: "{{ 0 if retry_count is undefined else retry_count | int + 1 }}" + + # - name: Wait 300 seconds for port 22 to become open and contain "OpenSSH" + # ansible.builtin.wait_for: + # host: "{{ hostvars[inventory_hostname].ansible_host }}" + # port: 22 + # search_regex: OpenSSH + # delay: 10 + + - name: Wait for system to become reachable + ansible.builtin.wait_for_connection: + vars: + python_version: "/usr/bin/python3" + ansible_python_interpreter: "{{ python_version if localhost_python_interpreter is defined | default(omit) }}" + + # - name: Run ansible adhoc ping module + # ansible.builtin.command: ansible all -i '{{ hostvars[inventory_hostname].ansible_host }},' -m ping + # ignore_errors: false + # register: result + # until: result.rc == 0 + # retries: 10 + # delay: 15 + + - name: Run facts module to get latest information + ansible.builtin.setup: + + - name: Grow the root filesystem + ansible.builtin.shell: | + /usr/libexec/oci-growfs -y + become: true + register: result + changed_when: result.rc == 0 + + - name: Add user account with access to sudo + ansible.builtin.user: + name: "{{ username }}" + password: "{{ user_default_password | password_hash('sha512') }}" + comment: Ansible created user + groups: wheel + append: true + update_password: on_create + become: true + + - name: Set authorized key for user using local public key file + ansible.posix.authorized_key: + user: "{{ username }}" + state: present + key: "{{ lookup('file', lookup('env', 'HOME') + '/.ssh/' + private_key + '.pub') }}" + become: true + + - name: Set user with passwordless sudo access + vars: + sudo_content: "{{ username }} ALL=(ALL:ALL) NOPASSWD: ALL" + ansible.builtin.lineinfile: + path: "/etc/sudoers.d/{{ username }}" + regexp: "{{ username }} ALL=" + line: "{{ sudo_content }}" + state: present + create: true + mode: "0644" + become: true + + - name: Create the ansible tmp directory if it does not exist + ansible.builtin.file: + path: ~/.ansible/tmp + state: directory + mode: '0700' + become: true + become_user: "{{ username }}" + + - name: Add locale settings to .bashrc + ansible.builtin.lineinfile: + dest: ~/.bashrc + line: "{{ item }}" + with_items: + - 'export LC_ALL="en_US.UTF-8"' + - 'export LC_CTYPE="en_US.UTF-8"' + become: true + become_user: "{{ username }}" + + # - name: Generate ssh keypair for user + # community.crypto.openssh_keypair: + # path: ~/.ssh/id_rsa + # size: 2048 + # comment: ocne ssh keypair + # become: true + # become_user: "{{ username }}" + + # - name: Fetch public key file from server + # ansible.builtin.fetch: + # src: "~/.ssh/id_rsa.pub" + # dest: "buffer/{{ inventory_hostname }}-id_rsa.pub" + # flat: true + # become: true + # become_user: "{{ username }}" + + # - name: Copy public key to each destination + # ansible.posix.authorized_key: + # user: "{{ username }}" + # state: present + # key: "{{ lookup('file', 'buffer/{{ item }}-id_rsa.pub') }}" + # loop: "{{ groups['all'] | flatten(levels=1) }}" + # become: true + + # - name: Print hostvars for groups + # ansible.builtin.debug: + # msg: "{{ hostvars[item] }}" + # loop: "{{ groups['all'] | flatten(levels=1) }}" + # when: debug_enabled + + # - name: Print vnc subnet_domain_name + # ansible.builtin.debug: + # var: my_subnet_domain_name + # when: debug_enabled + + # - name: Accept new ssh fingerprints + # ansible.builtin.shell: | + # ssh-keyscan -t ecdsa-sha2-nistp256 \ + # {{ hostvars[item].ansible_hostname }},\ + # {{ hostvars[item].ansible_default_ipv4.address }},\ + # {{ hostvars[item].ansible_hostname + '.' + my_subnet_domain_name }} >> ~/.ssh/known_hosts + # with_items: + # - "{{ groups['all'] }}" + # become: true + # become_user: "{{ username }}" + # register: result + # changed_when: result.rc == 0 + + - name: Configure firewall to log denied packets + ansible.builtin.command: + cmd: firewall-cmd --set-log-denied=all + when: debug_enabled + register: firewall_result + changed_when: firewall_result.rc == 0 + become: true + + # Check denied packets with "journalctl -x -e" or with "dmesg | grep -i REJECT" + + rescue: + - name: Fail message for rescue + ansible.builtin.fail: + msg: Maximum retries of host setup tasks reached + when: retry_count | int == max_retries | int + + - name: Print retry message + ansible.builtin.debug: + msg: "Host setup task group failed, try again..." + + - name: Sleep between retries + ansible.builtin.wait_for: + timeout: "{{ retry_delay }}" # seconds + delegate_to: localhost + become: false + + - name: Retry host setup if there is a failure + ansible.builtin.include_tasks: host_setup.yml diff --git a/olam/passwordless_setup.yml b/olam/passwordless_setup.yml new file mode 100644 index 0000000..70e0c45 --- /dev/null +++ b/olam/passwordless_setup.yml @@ -0,0 +1,53 @@ +--- +# Copyright (c) 2024 Oracle and/or its affiliates. +# This software is made available to you under the terms of the Universal Permissive License (UPL), Version 1.0. +# The Universal Permissive License (UPL), Version 1.0 (see COPYING or https://oss.oracle.com/licenses/upl) +# See LICENSE.TXT for details. + +- name: Generate ssh keypair for user + community.crypto.openssh_keypair: + path: ~/.ssh/id_rsa + size: 2048 + comment: ocne ssh keypair + become: true + become_user: "{{ username }}" + +- name: Fetch public key file from server + ansible.builtin.fetch: + src: "~/.ssh/id_rsa.pub" + dest: "buffer/{{ inventory_hostname }}-id_rsa.pub" + flat: true + become: true + become_user: "{{ username }}" + +- name: Copy public key to each destination + ansible.posix.authorized_key: + user: "{{ username }}" + state: present + key: "{{ lookup('file', 'buffer/{{ item }}-id_rsa.pub') }}" + loop: "{{ groups['all'] | flatten(levels=1) }}" + become: true + +- name: Print hostvars for groups + ansible.builtin.debug: + msg: "{{ hostvars[item] }}" + loop: "{{ groups['all'] | flatten(levels=1) }}" + when: debug_enabled + +- name: Print vnc subnet_domain_name + ansible.builtin.debug: + var: my_subnet_domain_name + when: debug_enabled + +- name: Accept new ssh fingerprints + ansible.builtin.shell: | + ssh-keyscan -t ecdsa-sha2-nistp256 \ + {{ hostvars[item].ansible_hostname }},\ + {{ hostvars[item].ansible_default_ipv4.address }},\ + {{ hostvars[item].ansible_hostname + '.' + my_subnet_domain_name }} >> ~/.ssh/known_hosts + with_items: + - "{{ groups['all'] }}" + become: true + become_user: "{{ username }}" + register: result + changed_when: result.rc == 0 From e083f26133a6df359986c31c42f86f15f98bb2dc Mon Sep 17 00:00:00 2001 From: William Graef Date: Wed, 6 Nov 2024 12:15:53 -0500 Subject: [PATCH 07/16] add oci vars template --- olam/templates/oci_vars.j2 | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 olam/templates/oci_vars.j2 diff --git a/olam/templates/oci_vars.j2 b/olam/templates/oci_vars.j2 new file mode 100644 index 0000000..0a4dd0a --- /dev/null +++ b/olam/templates/oci_vars.j2 @@ -0,0 +1,10 @@ +--- +# Copyright (c) 2024 Oracle and/or its affiliates. +# This software is made available to you under the terms of the Universal Permissive License (UPL), Version 1.0. +# The Universal Permissive License (UPL), Version 1.0 (see COPYING or https://oss.oracle.com/licenses/upl) +# See LICENSE.TXT for details. + +my_compartment_id: {{ my_compartment_id }} +my_vcn_id: {{ my_vcn_id }} +my_subnet_id: {{ my_subnet_id }} +my_subnet_domain_name: {{ my_subnet_domain_name }} \ No newline at end of file From 2f79a2e628e4539b75877caba0c5da25a75e45d0 Mon Sep 17 00:00:00 2001 From: William Graef Date: Wed, 6 Nov 2024 13:13:55 -0500 Subject: [PATCH 08/16] add vars for rpm update and passwordless ssh --- olam/default_vars.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/olam/default_vars.yml b/olam/default_vars.yml index 56059ca..35ad695 100644 --- a/olam/default_vars.yml +++ b/olam/default_vars.yml @@ -16,4 +16,7 @@ user_default_password: "oracle" debug_enabled: false add_block_storage: false block_volume_size_in_gbs: 50 -block_count: 1 \ No newline at end of file +block_count: 1 + +update_all: false +passwordless_ssh: false \ No newline at end of file From e3b26bd697eb5fd371c1a9102641ca4ca8f2d9fa Mon Sep 17 00:00:00 2001 From: William Graef Date: Wed, 6 Nov 2024 13:31:59 -0500 Subject: [PATCH 09/16] update instance build --- olam/build.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/olam/build.yml b/olam/build.yml index 410f528..b565b54 100644 --- a/olam/build.yml +++ b/olam/build.yml @@ -8,7 +8,7 @@ oracle.oci.oci_compute_instance: availability_domain: "{{ my_availability_domain }}" compartment_id: "{{ my_compartment_id }}" - name: "{{ item.value.instance_name | default('instance-'~timestamp) }}" + display_name: "{{ item.value.instance_name | default('instance-'~timestamp) }}" source_details: image_id: "{{ ol_image_id }}" source_type: image @@ -19,8 +19,10 @@ memory_in_gbs: "{{ instance_memory }}" create_vnic_details: assign_public_ip: true + display_name: "{{ item.value.instance_name | default('instance-'~timestamp) }}-vnic" hostname_label: "{{ item.value.instance_name | default('instance-'~timestamp) }}" subnet_id: "{{ my_subnet_id }}" + hostname_label: "{{ item.value.instance_name | default('instance-'~timestamp) }}" metadata: ssh_authorized_keys: "{{ lookup('file', lookup('env', 'HOME') + '/.ssh/' + private_key + '.pub') }}" agent_config: From e8f2f155c31288a49ee3d4b821b10e56a1986eb9 Mon Sep 17 00:00:00 2001 From: William Graef Date: Wed, 6 Nov 2024 15:23:49 -0500 Subject: [PATCH 10/16] fix host setup --- ol/passwordless_setup.yml | 2 +- olam/create_instance.yml | 14 ++ olam/host_setup.yml | 275 +++++++++++++++--------------------- olam/passwordless_setup.yml | 2 +- 4 files changed, 129 insertions(+), 164 deletions(-) diff --git a/ol/passwordless_setup.yml b/ol/passwordless_setup.yml index 70e0c45..33a1b1c 100644 --- a/ol/passwordless_setup.yml +++ b/ol/passwordless_setup.yml @@ -8,7 +8,7 @@ community.crypto.openssh_keypair: path: ~/.ssh/id_rsa size: 2048 - comment: ocne ssh keypair + comment: ol ssh keypair become: true become_user: "{{ username }}" diff --git a/olam/create_instance.yml b/olam/create_instance.yml index 68fb1f7..3d11623 100644 --- a/olam/create_instance.yml +++ b/olam/create_instance.yml @@ -292,8 +292,22 @@ - debug_enabled - inventory_hostname == ansible_play_hosts_all[0] + - name: Wait for systems to become reachable + ansible.builtin.wait_for_connection: + vars: + python_version: "/usr/bin/python3" + ansible_python_interpreter: "{{ python_version if localhost_python_interpreter is defined | default(omit) }}" + - name: Configure instance ansible.builtin.include_tasks: "host_setup.yml" + when: inventory_hostname in groups['server'] + + - name: Set unique authorized key on host + ansible.posix.authorized_key: + user: opc + state: present + key: "{{ lookup('file', lookup('env', 'HOME') + '/.ssh/' + private_key + '.pub') }}" + when: inventory_hostname in groups['client'] - name: Configure passwordless SSH ansible.builtin.include_tasks: "passwordless_setup.yml" diff --git a/olam/host_setup.yml b/olam/host_setup.yml index bcb15b9..cababf1 100644 --- a/olam/host_setup.yml +++ b/olam/host_setup.yml @@ -4,166 +4,117 @@ # The Universal Permissive License (UPL), Version 1.0 (see COPYING or https://oss.oracle.com/licenses/upl) # See LICENSE.TXT for details. -- name: Group of setup tasks for each instance +- name: Run facts module to get latest information + ansible.builtin.setup: + +- name: Grow the root filesystem + ansible.builtin.shell: | + /usr/libexec/oci-growfs -y + become: true + register: result + changed_when: result.rc == 0 + +- name: Add user account with access to sudo + ansible.builtin.user: + name: "{{ username }}" + password: "{{ user_default_password | password_hash('sha512') }}" + comment: Ansible created user + groups: wheel + append: true + update_password: on_create + become: true + +- name: Set authorized key for user using local public key file + ansible.posix.authorized_key: + user: "{{ username }}" + state: present + key: "{{ lookup('file', lookup('env', 'HOME') + '/.ssh/' + private_key + '.pub') }}" + become: true + +- name: Set user with passwordless sudo access vars: - max_retries: "{{ 5 if max_retries is undefined else max_retries | int }}" - retry_delay: "{{ 10 if retry_delay is undefined else retry_delay | int }}" - block: - - name: Increment the retry count - ansible.builtin.set_fact: - retry_count: "{{ 0 if retry_count is undefined else retry_count | int + 1 }}" - - # - name: Wait 300 seconds for port 22 to become open and contain "OpenSSH" - # ansible.builtin.wait_for: - # host: "{{ hostvars[inventory_hostname].ansible_host }}" - # port: 22 - # search_regex: OpenSSH - # delay: 10 - - - name: Wait for system to become reachable - ansible.builtin.wait_for_connection: - vars: - python_version: "/usr/bin/python3" - ansible_python_interpreter: "{{ python_version if localhost_python_interpreter is defined | default(omit) }}" - - # - name: Run ansible adhoc ping module - # ansible.builtin.command: ansible all -i '{{ hostvars[inventory_hostname].ansible_host }},' -m ping - # ignore_errors: false - # register: result - # until: result.rc == 0 - # retries: 10 - # delay: 15 - - - name: Run facts module to get latest information - ansible.builtin.setup: - - - name: Grow the root filesystem - ansible.builtin.shell: | - /usr/libexec/oci-growfs -y - become: true - register: result - changed_when: result.rc == 0 - - - name: Add user account with access to sudo - ansible.builtin.user: - name: "{{ username }}" - password: "{{ user_default_password | password_hash('sha512') }}" - comment: Ansible created user - groups: wheel - append: true - update_password: on_create - become: true - - - name: Set authorized key for user using local public key file - ansible.posix.authorized_key: - user: "{{ username }}" - state: present - key: "{{ lookup('file', lookup('env', 'HOME') + '/.ssh/' + private_key + '.pub') }}" - become: true - - - name: Set user with passwordless sudo access - vars: - sudo_content: "{{ username }} ALL=(ALL:ALL) NOPASSWD: ALL" - ansible.builtin.lineinfile: - path: "/etc/sudoers.d/{{ username }}" - regexp: "{{ username }} ALL=" - line: "{{ sudo_content }}" - state: present - create: true - mode: "0644" - become: true - - - name: Create the ansible tmp directory if it does not exist - ansible.builtin.file: - path: ~/.ansible/tmp - state: directory - mode: '0700' - become: true - become_user: "{{ username }}" - - - name: Add locale settings to .bashrc - ansible.builtin.lineinfile: - dest: ~/.bashrc - line: "{{ item }}" - with_items: - - 'export LC_ALL="en_US.UTF-8"' - - 'export LC_CTYPE="en_US.UTF-8"' - become: true - become_user: "{{ username }}" - - # - name: Generate ssh keypair for user - # community.crypto.openssh_keypair: - # path: ~/.ssh/id_rsa - # size: 2048 - # comment: ocne ssh keypair - # become: true - # become_user: "{{ username }}" - - # - name: Fetch public key file from server - # ansible.builtin.fetch: - # src: "~/.ssh/id_rsa.pub" - # dest: "buffer/{{ inventory_hostname }}-id_rsa.pub" - # flat: true - # become: true - # become_user: "{{ username }}" - - # - name: Copy public key to each destination - # ansible.posix.authorized_key: - # user: "{{ username }}" - # state: present - # key: "{{ lookup('file', 'buffer/{{ item }}-id_rsa.pub') }}" - # loop: "{{ groups['all'] | flatten(levels=1) }}" - # become: true - - # - name: Print hostvars for groups - # ansible.builtin.debug: - # msg: "{{ hostvars[item] }}" - # loop: "{{ groups['all'] | flatten(levels=1) }}" - # when: debug_enabled - - # - name: Print vnc subnet_domain_name - # ansible.builtin.debug: - # var: my_subnet_domain_name - # when: debug_enabled - - # - name: Accept new ssh fingerprints - # ansible.builtin.shell: | - # ssh-keyscan -t ecdsa-sha2-nistp256 \ - # {{ hostvars[item].ansible_hostname }},\ - # {{ hostvars[item].ansible_default_ipv4.address }},\ - # {{ hostvars[item].ansible_hostname + '.' + my_subnet_domain_name }} >> ~/.ssh/known_hosts - # with_items: - # - "{{ groups['all'] }}" - # become: true - # become_user: "{{ username }}" - # register: result - # changed_when: result.rc == 0 - - - name: Configure firewall to log denied packets - ansible.builtin.command: - cmd: firewall-cmd --set-log-denied=all - when: debug_enabled - register: firewall_result - changed_when: firewall_result.rc == 0 - become: true - - # Check denied packets with "journalctl -x -e" or with "dmesg | grep -i REJECT" - - rescue: - - name: Fail message for rescue - ansible.builtin.fail: - msg: Maximum retries of host setup tasks reached - when: retry_count | int == max_retries | int - - - name: Print retry message - ansible.builtin.debug: - msg: "Host setup task group failed, try again..." - - - name: Sleep between retries - ansible.builtin.wait_for: - timeout: "{{ retry_delay }}" # seconds - delegate_to: localhost - become: false - - - name: Retry host setup if there is a failure - ansible.builtin.include_tasks: host_setup.yml + sudo_content: "{{ username }} ALL=(ALL:ALL) NOPASSWD: ALL" + ansible.builtin.lineinfile: + path: "/etc/sudoers.d/{{ username }}" + regexp: "{{ username }} ALL=" + line: "{{ sudo_content }}" + state: present + create: true + mode: "0644" + become: true + +- name: Create the ansible tmp directory if it does not exist + ansible.builtin.file: + path: ~/.ansible/tmp + state: directory + mode: '0700' + become: true + become_user: "{{ username }}" + +- name: Add locale settings to .bashrc + ansible.builtin.lineinfile: + dest: ~/.bashrc + line: "{{ item }}" + with_items: + - 'export LC_ALL="en_US.UTF-8"' + - 'export LC_CTYPE="en_US.UTF-8"' + become: true + become_user: "{{ username }}" + +# - name: Generate ssh keypair for user +# community.crypto.openssh_keypair: +# path: ~/.ssh/id_rsa +# size: 2048 +# comment: ocne ssh keypair +# become: true +# become_user: "{{ username }}" + +# - name: Fetch public key file from server +# ansible.builtin.fetch: +# src: "~/.ssh/id_rsa.pub" +# dest: "buffer/{{ inventory_hostname }}-id_rsa.pub" +# flat: true +# become: true +# become_user: "{{ username }}" + +# - name: Copy public key to each destination +# ansible.posix.authorized_key: +# user: "{{ username }}" +# state: present +# key: "{{ lookup('file', 'buffer/{{ item }}-id_rsa.pub') }}" +# loop: "{{ groups['all'] | flatten(levels=1) }}" +# become: true + +# - name: Print hostvars for groups +# ansible.builtin.debug: +# msg: "{{ hostvars[item] }}" +# loop: "{{ groups['all'] | flatten(levels=1) }}" +# when: debug_enabled + +# - name: Print vnc subnet_domain_name +# ansible.builtin.debug: +# var: my_subnet_domain_name +# when: debug_enabled + +# - name: Accept new ssh fingerprints +# ansible.builtin.shell: | +# ssh-keyscan -t ecdsa-sha2-nistp256 \ +# {{ hostvars[item].ansible_hostname }},\ +# {{ hostvars[item].ansible_default_ipv4.address }},\ +# {{ hostvars[item].ansible_hostname + '.' + my_subnet_domain_name }} >> ~/.ssh/known_hosts +# with_items: +# - "{{ groups['all'] }}" +# become: true +# become_user: "{{ username }}" +# register: result +# changed_when: result.rc == 0 + +- name: Configure firewall to log denied packets + ansible.builtin.command: + cmd: firewall-cmd --set-log-denied=all + when: debug_enabled + register: firewall_result + changed_when: firewall_result.rc == 0 + become: true + +# Check denied packets with "journalctl -x -e" or with "dmesg | grep -i REJECT" diff --git a/olam/passwordless_setup.yml b/olam/passwordless_setup.yml index 70e0c45..2926ac8 100644 --- a/olam/passwordless_setup.yml +++ b/olam/passwordless_setup.yml @@ -8,7 +8,7 @@ community.crypto.openssh_keypair: path: ~/.ssh/id_rsa size: 2048 - comment: ocne ssh keypair + comment: olam ssh keypair become: true become_user: "{{ username }}" From 3293f5628f85329b82f75d0415f825c44862f549 Mon Sep 17 00:00:00 2001 From: William Graef Date: Thu, 7 Nov 2024 13:09:44 -0500 Subject: [PATCH 11/16] fix passwordless ssh from control to host --- olam/create_instance.yml | 15 ++++----------- olam/default_vars.yml | 2 +- ..._setup.yml => olam_passwordless_setup.yml} | 19 ++++++++----------- olam/update_all_rpms.yml | 2 +- 4 files changed, 14 insertions(+), 24 deletions(-) rename olam/{passwordless_setup.yml => olam_passwordless_setup.yml} (79%) diff --git a/olam/create_instance.yml b/olam/create_instance.yml index 3d11623..b7bfe21 100644 --- a/olam/create_instance.yml +++ b/olam/create_instance.yml @@ -293,7 +293,7 @@ - inventory_hostname == ansible_play_hosts_all[0] - name: Wait for systems to become reachable - ansible.builtin.wait_for_connection: + ansible.builtin.wait_for_connection: vars: python_version: "/usr/bin/python3" ansible_python_interpreter: "{{ python_version if localhost_python_interpreter is defined | default(omit) }}" @@ -302,15 +302,8 @@ ansible.builtin.include_tasks: "host_setup.yml" when: inventory_hostname in groups['server'] - - name: Set unique authorized key on host - ansible.posix.authorized_key: - user: opc - state: present - key: "{{ lookup('file', lookup('env', 'HOME') + '/.ssh/' + private_key + '.pub') }}" - when: inventory_hostname in groups['client'] - - name: Configure passwordless SSH - ansible.builtin.include_tasks: "passwordless_setup.yml" + ansible.builtin.include_tasks: "olam_passwordless_setup.yml" when: passwordless_ssh - name: Update all rpm packages @@ -320,9 +313,9 @@ - name: Print instances hosts: all become: true - gather_facts: false + gather_facts: true vars_files: - - ocir_vars.yml + - oci_vars.yml tasks: diff --git a/olam/default_vars.yml b/olam/default_vars.yml index 35ad695..8d63e8f 100644 --- a/olam/default_vars.yml +++ b/olam/default_vars.yml @@ -19,4 +19,4 @@ block_volume_size_in_gbs: 50 block_count: 1 update_all: false -passwordless_ssh: false \ No newline at end of file +passwordless_ssh: true \ No newline at end of file diff --git a/olam/passwordless_setup.yml b/olam/olam_passwordless_setup.yml similarity index 79% rename from olam/passwordless_setup.yml rename to olam/olam_passwordless_setup.yml index 2926ac8..d35a10f 100644 --- a/olam/passwordless_setup.yml +++ b/olam/olam_passwordless_setup.yml @@ -4,28 +4,30 @@ # The Universal Permissive License (UPL), Version 1.0 (see COPYING or https://oss.oracle.com/licenses/upl) # See LICENSE.TXT for details. -- name: Generate ssh keypair for user +- name: Generate ssh keypair for ol-control-node community.crypto.openssh_keypair: path: ~/.ssh/id_rsa size: 2048 comment: olam ssh keypair become: true become_user: "{{ username }}" + when: inventory_hostname in groups['server'] -- name: Fetch public key file from server +- name: Fetch public key file from ol-control-node ansible.builtin.fetch: src: "~/.ssh/id_rsa.pub" dest: "buffer/{{ inventory_hostname }}-id_rsa.pub" flat: true become: true become_user: "{{ username }}" + when: inventory_hostname in groups['server'] -- name: Copy public key to each destination +- name: Copy public key to ol-host ansible.posix.authorized_key: - user: "{{ username }}" + user: opc state: present key: "{{ lookup('file', 'buffer/{{ item }}-id_rsa.pub') }}" - loop: "{{ groups['all'] | flatten(levels=1) }}" + loop: "{{ groups['client'] | flatten(levels=1) }}" become: true - name: Print hostvars for groups @@ -34,11 +36,6 @@ loop: "{{ groups['all'] | flatten(levels=1) }}" when: debug_enabled -- name: Print vnc subnet_domain_name - ansible.builtin.debug: - var: my_subnet_domain_name - when: debug_enabled - - name: Accept new ssh fingerprints ansible.builtin.shell: | ssh-keyscan -t ecdsa-sha2-nistp256 \ @@ -46,7 +43,7 @@ {{ hostvars[item].ansible_default_ipv4.address }},\ {{ hostvars[item].ansible_hostname + '.' + my_subnet_domain_name }} >> ~/.ssh/known_hosts with_items: - - "{{ groups['all'] }}" + - "{{ groups['client'] }}" become: true become_user: "{{ username }}" register: result diff --git a/olam/update_all_rpms.yml b/olam/update_all_rpms.yml index d10b15b..d83e466 100644 --- a/olam/update_all_rpms.yml +++ b/olam/update_all_rpms.yml @@ -5,7 +5,7 @@ # See LICENSE.TXT for details. - name: Install latest Oracle Linux packages - hosts: server,vbox + hosts: server vars_files: - default_vars.yml become: true From 1f9455414fb2d604b914c0d3eec7d01ec0036871 Mon Sep 17 00:00:00 2001 From: William Graef Date: Thu, 7 Nov 2024 13:35:41 -0500 Subject: [PATCH 12/16] fix copy key to host --- olam/olam_passwordless_setup.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/olam/olam_passwordless_setup.yml b/olam/olam_passwordless_setup.yml index d35a10f..c7aa94c 100644 --- a/olam/olam_passwordless_setup.yml +++ b/olam/olam_passwordless_setup.yml @@ -27,8 +27,9 @@ user: opc state: present key: "{{ lookup('file', 'buffer/{{ item }}-id_rsa.pub') }}" - loop: "{{ groups['client'] | flatten(levels=1) }}" + loop: "{{ groups['server'] | flatten(levels=1) }}" become: true + when: inventory_hostname in groups['client'] - name: Print hostvars for groups ansible.builtin.debug: From cf88ee780f3b35ab329bf27ebeddd27474298750 Mon Sep 17 00:00:00 2001 From: William Graef Date: Thu, 7 Nov 2024 13:38:42 -0500 Subject: [PATCH 13/16] gather facts for keys and add idempotence key to build --- olam/build.yml | 1 + olam/create_instance.yml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/olam/build.yml b/olam/build.yml index b565b54..77d7dad 100644 --- a/olam/build.yml +++ b/olam/build.yml @@ -33,6 +33,7 @@ - name: "OS Management Service Agent" desired_state: DISABLED + key_by: [compartment_id, availability_domain, display_name] register: result vars: timestamp: "{{ now().strftime('%Y%m%d-%H%M%S') }}" diff --git a/olam/create_instance.yml b/olam/create_instance.yml index b7bfe21..9343619 100644 --- a/olam/create_instance.yml +++ b/olam/create_instance.yml @@ -263,7 +263,7 @@ - name: Configure new instances hosts: all - gather_facts: false + gather_facts: true vars_files: - default_vars.yml - oci_vars.yml From 00ed80bc4eff8265e810c51f155e854ff59cc9ff Mon Sep 17 00:00:00 2001 From: William Graef Date: Thu, 7 Nov 2024 13:43:59 -0500 Subject: [PATCH 14/16] accept fingerpring only on control --- olam/olam_passwordless_setup.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/olam/olam_passwordless_setup.yml b/olam/olam_passwordless_setup.yml index c7aa94c..df1c62e 100644 --- a/olam/olam_passwordless_setup.yml +++ b/olam/olam_passwordless_setup.yml @@ -49,3 +49,4 @@ become_user: "{{ username }}" register: result changed_when: result.rc == 0 + when: inventory_hostname in groups['server'] From 87261cda2bcd92529201fd1574b60b9432097920 Mon Sep 17 00:00:00 2001 From: William Graef Date: Thu, 7 Nov 2024 13:51:43 -0500 Subject: [PATCH 15/16] change names for host types --- olam/create_instance.yml | 6 +++--- olam/default_vars.yml | 2 +- olam/get_facts.yml | 22 +++++++++++----------- olam/olam_passwordless_setup.yml | 12 ++++++------ 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/olam/create_instance.yml b/olam/create_instance.yml index 9343619..909fdbe 100644 --- a/olam/create_instance.yml +++ b/olam/create_instance.yml @@ -16,10 +16,10 @@ compute_instances: 1: instance_name: "ol-node-01" - type: "client" + type: "control" 2: instance_name: "ol-node-02" - type: "server" + type: "remote" os: "Oracle Linux" os_version: "8" instance_shape: "VM.Standard.E4.Flex" @@ -300,7 +300,7 @@ - name: Configure instance ansible.builtin.include_tasks: "host_setup.yml" - when: inventory_hostname in groups['server'] + when: inventory_hostname in groups['control'] - name: Configure passwordless SSH ansible.builtin.include_tasks: "olam_passwordless_setup.yml" diff --git a/olam/default_vars.yml b/olam/default_vars.yml index 8d63e8f..b2fe46e 100644 --- a/olam/default_vars.yml +++ b/olam/default_vars.yml @@ -1,7 +1,7 @@ compute_instances: 1: instance_name: "olam" - type: "server" + type: "control" boot_volume_size_in_gbs: 50 os: "Oracle Linux" os_version: "8" diff --git a/olam/get_facts.yml b/olam/get_facts.yml index 3ea5a94..bf3a8af 100644 --- a/olam/get_facts.yml +++ b/olam/get_facts.yml @@ -10,16 +10,16 @@ tasks: - - name: Get minimum set of available facts - ansible.builtin.setup: - gather_subset: - - 'min' - register: min_facts + - name: Get minimum set of available facts + ansible.builtin.setup: + gather_subset: + - 'min' + register: min_facts - - name: Print minimum set of facts - ansible.builtin.debug: - msg: "{{ min_facts }}" + - name: Print minimum set of facts + ansible.builtin.debug: + msg: "{{ min_facts }}" - - name: Print system date - ansible.builtin.debug: - var: ansible_date_time.date + - name: Print system date + ansible.builtin.debug: + var: ansible_date_time.date diff --git a/olam/olam_passwordless_setup.yml b/olam/olam_passwordless_setup.yml index df1c62e..d44f842 100644 --- a/olam/olam_passwordless_setup.yml +++ b/olam/olam_passwordless_setup.yml @@ -11,7 +11,7 @@ comment: olam ssh keypair become: true become_user: "{{ username }}" - when: inventory_hostname in groups['server'] + when: inventory_hostname in groups['control'] - name: Fetch public key file from ol-control-node ansible.builtin.fetch: @@ -20,16 +20,16 @@ flat: true become: true become_user: "{{ username }}" - when: inventory_hostname in groups['server'] + when: inventory_hostname in groups['control'] - name: Copy public key to ol-host ansible.posix.authorized_key: user: opc state: present key: "{{ lookup('file', 'buffer/{{ item }}-id_rsa.pub') }}" - loop: "{{ groups['server'] | flatten(levels=1) }}" + loop: "{{ groups['control'] | flatten(levels=1) }}" become: true - when: inventory_hostname in groups['client'] + when: inventory_hostname in groups['remote'] - name: Print hostvars for groups ansible.builtin.debug: @@ -44,9 +44,9 @@ {{ hostvars[item].ansible_default_ipv4.address }},\ {{ hostvars[item].ansible_hostname + '.' + my_subnet_domain_name }} >> ~/.ssh/known_hosts with_items: - - "{{ groups['client'] }}" + - "{{ groups['remote'] }}" become: true become_user: "{{ username }}" register: result changed_when: result.rc == 0 - when: inventory_hostname in groups['server'] + when: inventory_hostname in groups['control'] From 11d3a799fd85f6cfe91a0382c2e25bdd1b0f6ac6 Mon Sep 17 00:00:00 2001 From: William Graef Date: Thu, 7 Nov 2024 14:02:48 -0500 Subject: [PATCH 16/16] fix wait and facts --- olam/create_instance.yml | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/olam/create_instance.yml b/olam/create_instance.yml index 909fdbe..b86a69d 100644 --- a/olam/create_instance.yml +++ b/olam/create_instance.yml @@ -263,7 +263,7 @@ - name: Configure new instances hosts: all - gather_facts: true + gather_facts: false vars_files: - default_vars.yml - oci_vars.yml @@ -275,6 +275,15 @@ tasks: + - name: Wait for systems to become reachable + ansible.builtin.wait_for_connection: + vars: + python_version: "/usr/bin/python3" + ansible_python_interpreter: "{{ python_version if localhost_python_interpreter is defined | default(omit) }}" + + - name: Get a set of all available facts + ansible.builtin.setup: + - name: Print in-memory inventory ansible.builtin.debug: msg: "{{ groups['all'] }}" @@ -292,12 +301,6 @@ - debug_enabled - inventory_hostname == ansible_play_hosts_all[0] - - name: Wait for systems to become reachable - ansible.builtin.wait_for_connection: - vars: - python_version: "/usr/bin/python3" - ansible_python_interpreter: "{{ python_version if localhost_python_interpreter is defined | default(omit) }}" - - name: Configure instance ansible.builtin.include_tasks: "host_setup.yml" when: inventory_hostname in groups['control']