diff --git a/.devfile.yaml b/.devfile.yaml new file mode 100644 index 000000000..db71b4c9d --- /dev/null +++ b/.devfile.yaml @@ -0,0 +1,12 @@ +schemaVersion: 2.2.0 +metadata: + name: product-demos +components: + - name: product-demos-ee + container: + image: quay.io/mloriedo/ansible-creator-ee:latest # workaround for https://github.com/eclipse/che/issues/21778 + memoryRequest: 256M + memoryLimit: 5Gi + cpuRequest: 250m + cpuLimit: 2000m + args: ['tail', '-f', '/dev/null'] diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 000000000..8983e99c7 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,7 @@ +{ + "recommendations": [ + "redhat.vscode-yaml", + "redhat.ansible", + "ms-python.black-formatter" + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..bd68aec24 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "editor.renderWhitespace": "all" +} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 380400079..2789479fb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -44,3 +44,8 @@ This document aims to outline the requirements for the various forms of contribu - `controller_components` can be any of the roles defined [here](https://github.com/redhat-cop/controller_configuration/tree/devel/roles) - Add variables for each component listed 3) Include a README.md in the subdirectory + +## Testing +To run `ansible-lint` you will need to set an environment variable for the token to connect to Automation Hub. You can get a token from [here](https://console.redhat.com/ansible/automation-hub/token). + +Copy the value of the token and run `export ANSIBLE_GALAXY_SERVER_AH_TOKEN=` diff --git a/README.md b/README.md index dfd19c4c6..c601e4b15 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ +[![Lab](https://img.shields.io/badge/Try%20Me-EE0000?style=for-the-badge&logo=redhat&logoColor=white)](https://red.ht/aap-product-demos) +[![Dev Spaces](https://img.shields.io/badge/Customize%20Here-0078d7.svg?style=for-the-badge&logo=visual-studio-code&logoColor=white)](https://workspaces.openshift.com/f?url=https://github.com/ansible/product-demos) + # Official Ansible Product Demos This is a centralized location for all Ansible Product Demos going forward. diff --git a/ansible.cfg b/ansible.cfg index 5bd4066c4..8e1f70d86 100644 --- a/ansible.cfg +++ b/ansible.cfg @@ -1,3 +1,13 @@ [defaults] collections_paths=./collections roles_path=./roles + +[galaxy] +server_list = ah,galaxy + +[galaxy_server.ah] +url=https://console.redhat.com/api/automation-hub/ +auth_url=https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token + +[galaxy_server.galaxy] +url=https://galaxy.ansible.com/ diff --git a/cloud/README.md b/cloud/README.md index 15cb1078c..7ef5e410d 100644 --- a/cloud/README.md +++ b/cloud/README.md @@ -10,7 +10,7 @@ - [Configure Credentials](#configure-credentials) - [Add Workshop Credential Password](#add-workshop-credential-password) - [Remove Inventory Variables](#remove-inventory-variables) - - [Getting your Puiblic Key for Create Infra Job](#getting-your-puiblic-key-for-create-infra-job) + - [Getting your Puiblic Key for Create Keypair Job](#getting-your-puiblic-key-for-create-keypair-job) - [Suggested Usage](#suggested-usage) - [Known Issues](#known-issues) @@ -20,8 +20,11 @@ This category of demos shows examples of multi-cloud provisioning and management ### Jobs - [**Cloud / Create Infra**](create_infra.yml) - Creates a VPC with required routing and firewall rules for provisioning VMs +- [**Cloud / Create Keypair**](aws_key.yml) - Creates a keypair for connecting to EC2 instances - [**Cloud / Create VM**](create_vm.yml) - Create a VM based on a [blueprint](blueprints/) in the selected cloud provider - [**Cloud / Destroy VM**](destroy_vm.yml) - Destroy a VM that has been created in a cloud provider. VM must be imported into dynamic inventory to be deleted. +- [**Cloud / Snapshot EC2**](snapshot_ec2.yml) - Snapshot a VM that has been created in a cloud provider. VM must be imported into dynamic inventory to be snapshot. +- [**Cloud / Restore EC2 from Snapshot**](snapshot_ec2.yml) - Restore a VM that has been created in a cloud provider. By default, volumes will be restored from their latest snapshot. VM must be imported into dynamic inventory to be patched. ### Inventory @@ -46,7 +49,7 @@ After running the setup job template, there are a few steps required to make the 1) Remove Workshop Inventory variables on the Details page of the inventory. Required until [RFE](https://github.com/ansible/workshops/issues/1597]) is complete -### Getting your Puiblic Key for Create Infra Job +### Getting your Puiblic Key for Create Keypair Job 1) Connect to the command line of your Controller server. This is easiest to do by opening the VS Code Web Editor from the landing page where you found the Controller login details. 2) Open a Terminal Window in the VS Code Web Editor. @@ -56,9 +59,11 @@ After running the setup job template, there are a few steps required to make the ## Suggested Usage -**Cloud / Create Infra** -The Create Infra job builds cloud infrastructure based on the provider definition in the included `demo.cloud` collection. +**Cloud / Create Keypair** - The Create Keypair job creates an EC2 keypair which can be used when creating EC2 instances to enable SSH access. **Cloud / Create VM** - The Create VM job builds a VM in the given provider based on the included `demo.cloud` collection. VM [blueprints](blueprints/) define variables for each provider that override the defaults in the collection. When creating VMs it is recommended to follow naming conventions that can be used as host patterns. (eg. VM names: `win1`, `win2`, `win3`. Host Pattern: `win*` ) +**Cloud / AWS / Patch EC2 Workflow** - Create a VPC and one or more linux VM(s) in AWS using the `Cloud / Create VPC` and `Cloud / Create VM` templates. Run the workflow and observe the instance snapshots followed by patching operation. Optionally, use the survey to force a patch failure in order to demonstrate the restore path. At this time, the workflow does not support patching Windows instances. + ## Known Issues Azure does not work without a custom execution environment that includes the Azure dependencies. \ No newline at end of file diff --git a/cloud/restore_ec2.yml b/cloud/restore_ec2.yml new file mode 100644 index 000000000..93890ec01 --- /dev/null +++ b/cloud/restore_ec2.yml @@ -0,0 +1,10 @@ +--- +- name: Restore ec2 instance from snapshot + hosts: "{{ _hosts | default(omit) }}" + gather_facts: false + + tasks: + - name: Include restore from snapshot role + ansible.builtin.include_role: + name: "demo.cloud.aws" + tasks_from: restore_vm diff --git a/cloud/setup.yml b/cloud/setup.yml index 64ece260b..3161f878d 100644 --- a/cloud/setup.yml +++ b/cloud/setup.yml @@ -367,6 +367,91 @@ controller_templates: variable: aws_keypair_owner required: true + - name: Cloud / AWS / Snapshot EC2 + job_type: run + organization: Default + credentials: + - AWS + project: Ansible official demo project + playbook: cloud/snapshot_ec2.yml + inventory: Demo Inventory + notification_templates_started: Telemetry + notification_templates_success: Telemetry + notification_templates_error: Telemetry + survey_enabled: true + survey: + name: '' + description: '' + spec: + - question_name: AWS Region + type: multiplechoice + variable: aws_region + required: true + default: us-east-1 + choices: + - us-east-1 + - us-east-2 + - us-west-1 + - us-west-2 + - question_name: Specify target hosts + type: text + variable: _hosts + required: false + + - name: Cloud / AWS / Restore EC2 from Snapshot + job_type: run + organization: Default + credentials: + - AWS + project: Ansible official demo project + playbook: cloud/restore_ec2.yml + inventory: Demo Inventory + notification_templates_started: Telemetry + notification_templates_success: Telemetry + notification_templates_error: Telemetry + survey_enabled: true + survey: + name: '' + description: '' + spec: + - question_name: AWS Region + type: multiplechoice + variable: aws_region + required: true + default: us-east-1 + choices: + - us-east-1 + - us-east-2 + - us-west-1 + - us-west-2 + - question_name: Specify target hosts + type: text + variable: _hosts + required: false + + - name: "LINUX / Patching" + job_type: check + inventory: "Demo Inventory" + project: "Ansible official demo project" + playbook: "linux/patching.yml" + execution_environment: Default execution environment + notification_templates_started: Telemetry + notification_templates_success: Telemetry + notification_templates_error: Telemetry + use_fact_cache: true + ask_job_type_on_launch: true + credentials: + - "Demo Credential" + survey_enabled: true + survey: + name: '' + description: '' + spec: + - question_name: Server Name or Pattern + type: text + variable: _hosts + required: true + controller_workflows: - name: Deploy Cloud Stack in AWS description: A workflow to deploy a cloud stack @@ -475,3 +560,56 @@ controller_workflows: feedback: Failed to create AWS instance - identifier: Tag Report unified_job_template: Cloud / AWS / Tags Report + + - name: Cloud / AWS / Patch EC2 Workflow + description: A workflow to patch ec2 instances with snapshot and restore on failure. + organization: Default + notification_templates_started: Telemetry + notification_templates_success: Telemetry + notification_templates_error: Telemetry + survey_enabled: true + survey: + name: '' + description: '' + spec: + - question_name: AWS Region + type: multiplechoice + variable: aws_region + required: true + default: us-east-1 + choices: + - us-east-1 + - us-east-2 + - us-west-1 + - us-west-2 + - question_name: Specify target hosts + type: text + variable: _hosts + required: true + default: os_linux + simplified_workflow_nodes: + - identifier: Project Sync + unified_job_template: Ansible official demo project + success_nodes: + - Take Snapshot + - identifier: Inventory Sync + unified_job_template: AWS Inventory + success_nodes: + - Take Snapshot + - identifier: Take Snapshot + unified_job_template: Cloud / AWS / Snapshot EC2 + success_nodes: + - Patch Instance + - identifier: Patch Instance + unified_job_template: LINUX / Patching + job_type: run + failure_nodes: + - Restore from Snapshot + - identifier: Restore from Snapshot + unified_job_template: Cloud / AWS / Restore EC2 from Snapshot + failure_nodes: + - Ticket - Restore Failed + - identifier: Ticket - Restore Failed + unified_job_template: 'SUBMIT FEEDBACK' + extra_data: + feedback: Cloud / AWS / Patch EC2 Workflow | Failed to restore ec2 from snapshot \ No newline at end of file diff --git a/cloud/snapshot_ec2.yml b/cloud/snapshot_ec2.yml new file mode 100644 index 000000000..3be63bf93 --- /dev/null +++ b/cloud/snapshot_ec2.yml @@ -0,0 +1,10 @@ +--- +- name: Snapshot ec2 instance + hosts: "{{ _hosts | default(omit) }}" + gather_facts: false + + tasks: + - name: Include snapshot role + ansible.builtin.include_role: + name: "demo.cloud.aws" + tasks_from: snapshot_vm diff --git a/collections/ansible_collections/demo/cloud/roles/aws/defaults/main.yml b/collections/ansible_collections/demo/cloud/roles/aws/defaults/main.yml index b152f7ed5..b985bccc4 100644 --- a/collections/ansible_collections/demo/cloud/roles/aws/defaults/main.yml +++ b/collections/ansible_collections/demo/cloud/roles/aws/defaults/main.yml @@ -21,3 +21,4 @@ aws_env_tag: prod aws_purpose_tag: ansible_demo aws_ansiblegroup_tag: cloud aws_ec2_wait: true +aws_snapshots: {} \ No newline at end of file diff --git a/collections/ansible_collections/demo/cloud/roles/aws/tasks/restore_vm.yml b/collections/ansible_collections/demo/cloud/roles/aws/tasks/restore_vm.yml new file mode 100644 index 000000000..7d6297578 --- /dev/null +++ b/collections/ansible_collections/demo/cloud/roles/aws/tasks/restore_vm.yml @@ -0,0 +1,62 @@ +--- +- name: AWS | RESTORE VM + delegate_to: localhost + block: + - name: AWS | RESTORE VM | stop vm + amazon.aws.ec2_instance: + region: "{{ aws_region }}" + instance_ids: "{{ instance_id }}" + state: stopped + wait: true + + - name: AWS | RESTORE VM | get volumes + register: r_vol_info + amazon.aws.ec2_vol_info: + region: "{{ aws_region }}" + filters: + attachment.instance-id: "{{ instance_id }}" + + - name: AWS | RESTORE VM | detach volumes + loop: "{{ r_vol_info.volumes }}" + loop_control: + loop_var: volume + label: "{{ volume.id }}" + amazon.aws.ec2_vol: + region: "{{ aws_region }}" + id: "{{ volume.id }}" + instance: None + + - name: AWS | RESTORE VM | attach snapshots from stat + when: inventory_hostname in aws_snapshots + loop: "{{ aws_snapshots[inventory_hostname] }}" + loop_control: + loop_var: snap + label: "{{ snap.snapshot_id }}" + amazon.aws.ec2_vol: + region: "{{ aws_region }}" + instance: "{{ instance_id }}" + snapshot: "{{ snap.snapshot_id }}" + device_name: "{{ snap.device }}" + + - name: AWS | RESTORE VM | get all snapshots + when: inventory_hostname not in aws_snapshots + register: r_snapshots + amazon.aws.ec2_snapshot_info: + region: "{{ aws_region }}" + filters: + "tag:Name": "{{ inventory_hostname }}" + + - name: AWS | RESTORE VM | create volume from latest snapshot + when: inventory_hostname not in aws_snapshots + amazon.aws.ec2_vol: + region: "{{ aws_region }}" + instance: "{{ instance_id }}" + snapshot: "{{ r_snapshots.snapshots[0].snapshot_id }}" + device_name: "/dev/sda1" + + - name: AWS | RESTORE VM | start vm + amazon.aws.ec2_instance: + region: "{{ aws_region }}" + instance_ids: "{{ instance_id }}" + state: started + wait: true \ No newline at end of file diff --git a/collections/ansible_collections/demo/cloud/roles/aws/tasks/snapshot_vm.yml b/collections/ansible_collections/demo/cloud/roles/aws/tasks/snapshot_vm.yml new file mode 100644 index 000000000..a82e6c1bd --- /dev/null +++ b/collections/ansible_collections/demo/cloud/roles/aws/tasks/snapshot_vm.yml @@ -0,0 +1,43 @@ +--- +- name: AWS | SNAPSHOT VM + delegate_to: localhost + block: + - name: AWS | SNAPSHOT VM | assert id + ansible.builtin.assert: + that: instance_id is defined + fail_msg: "instance_id is required for snapshot operations" + + - name: AWS | SNAPSHOT VM | include vars + ansible.builtin.include_vars: + file: snapshot_vm.yml + + - name: AWS | SNAPSHOT VM | get volumes + register: r_vol_info + amazon.aws.ec2_vol_info: + region: "{{ aws_region }}" + filters: + attachment.instance-id: "{{ instance_id }}" + + - name: AWS | SNAPSHOT VM | take snapshots + loop: "{{ r_vol_info.volumes }}" + loop_control: + loop_var: volume + label: "{{ volume.id }}" + register: r_snapshots + amazon.aws.ec2_snapshot: + region: "{{ aws_region }}" + volume_id: "{{ volume.id }}" + description: "Snapshot taken by Red Hat Product demos" + snapshot_tags: "{{ tags }}" + +- name: AWS | SNAPSHOT VM | format snapshot stat + ansible.builtin.set_fact: + snapshot_stat: + - key: "{{ inventory_hostname }}" + value: "{{ r_snapshots.results | json_query(aws_ec2_snapshot_query) }}" + +- name: AWS | SNAPSHOT VM | record snapshot with host key + ansible.builtin.set_stats: + data: + aws_snapshots: "{{ snapshot_stat | items2dict }}" + diff --git a/collections/ansible_collections/demo/cloud/roles/aws/vars/snapshot_vm.yml b/collections/ansible_collections/demo/cloud/roles/aws/vars/snapshot_vm.yml new file mode 100644 index 000000000..9ad07a7c7 --- /dev/null +++ b/collections/ansible_collections/demo/cloud/roles/aws/vars/snapshot_vm.yml @@ -0,0 +1,10 @@ +# Set stat_snapshots with model: +# [ +# { +# "snapshot_id": "snap-0e981f05704e19ffd", +# "vol_id": "vol-0bd55f313bb7bcdd8", +# "device": "/dev/sda1" +# }, +# ... +# ] +aws_ec2_snapshot_query: "[].{snapshot_id: snapshot_id, vol_id: volume.id, device: volume.attachment_set[?instance_id=='{{ instance_id }}'].device | [0]}" \ No newline at end of file diff --git a/collections/requirements.yml b/collections/requirements.yml index fe3cf7f63..45fc493e8 100644 --- a/collections/requirements.yml +++ b/collections/requirements.yml @@ -35,3 +35,8 @@ collections: version: 5.0.0 - name: ansible.netcommon version: 5.0.0 + # openshift + - name: redhat.openshift + version: 2.3.0 + - name: kubernetes.core + version: 2.4.0 diff --git a/linux/patching.yml b/linux/patching.yml index 23b91eba1..d567292eb 100644 --- a/linux/patching.yml +++ b/linux/patching.yml @@ -29,9 +29,22 @@ - ansible_local.insights.system_id is defined - name: Deploy report server + when: not ansible_check_mode delegate_to: "{{ report_server }}" run_once: true # noqa: run-once[task] block: + - name: Install firewall dependencies + ansible.builtin.dnf: + name: + - firewalld + - python3-firewall + state: present + + - name: Start firewalld + ansible.builtin.service: + name: firewalld + state: started + - name: Build report server ansible.builtin.include_role: name: "{{ item }}" diff --git a/openshift/README.md b/openshift/README.md new file mode 100644 index 000000000..d5bfd7b6d --- /dev/null +++ b/openshift/README.md @@ -0,0 +1,20 @@ +# OpenShift Demos + +## Table of Contents +- [OpenShift Demos](#openshift-demos) + - [Table of Contents](#table-of-contents) + - [About These Demos](#about-these-demos) + - [Jobs](#jobs) + - [Pre Setup](#pre-setup) + +## About These Demos +This category of demos shows examples of openshift operations and management with Ansible Automation Platform. The list of demos can be found below. See the [Suggested Usage](#suggested-usage) section of this document for recommendations on how to best use these demos. + +### Jobs +- [**OpenShift / Dev Spaces**](devspaces.yml) - Install and deploy dev spaces on OCP cluster. After this job has run successfully, login to your OCP cluster, click the application icon (to the left of the bell icon in the top right) to access Dev Spaces + +## Pre Setup +This demo requires an OpenShift cluster to deploy to. If you do not have a cluster to use, one can be requested from [demo.redhat.com](https://demo.redhat.com). +- Search for the [Red Hat OpenShift Container Platform 4.12 Workshop](https://demo.redhat.com/catalog?item=babylon-catalog-prod/sandboxes-gpte.ocp412-wksp.prod&utm_source=webapp&utm_medium=share-link) item in the catalog and request with the number of users you would like for Dev Spaces. +- Login using the admin credentials provided. Click the `admin` username at the top right and select `Copy login command`. +- Authenticate and click `Display Token`. This information will be used to populate the OpenShift Credential after you run the setup. diff --git a/openshift/devspaces.yml b/openshift/devspaces.yml new file mode 100644 index 000000000..dc7304ddb --- /dev/null +++ b/openshift/devspaces.yml @@ -0,0 +1,112 @@ +--- +- name: Deploy Dev Spaces on OCP + hosts: localhost + gather_facts: false + + tasks: + - name: create namespace + redhat.openshift.k8s: + name: eclipse-che + api_version: v1 + kind: Namespace + state: present + + - name: create dev spaces subscription + redhat.openshift.k8s: + state: present + definition: + apiVersion: operators.coreos.com/v1alpha1 + kind: Subscription + metadata: + labels: + operators.coreos.com/devspaces.openshift-operators: '' + name: devspaces + namespace: openshift-operators + spec: + channel: stable + installPlanApproval: Automatic + name: devspaces + source: redhat-operators + sourceNamespace: openshift-marketplace + + - name: wait for dev spaces operator to install + k8s_info: + api_version: apiextensions.k8s.io/v1 + kind: CustomResourceDefinition + name: checlusters.org.eclipse.che + register: crd_che + until: crd_che.resources | list | length == 1 + retries: 10 + delay: 30 + + - name: Wait until devspaces-operator is up + k8s_info: + api_version: v1 + kind: Deployment + name: devspaces-operator + namespace: openshift-operators + register: pod_list + until: pod_list|json_query('resources[*].status.readyReplicas')|unique == [1] + retries: 10 + delay: 30 + + - name: deploy dev spaces + redhat.openshift.k8s: + state: present + definition: + apiVersion: org.eclipse.che/v2 + kind: CheCluster + metadata: + name: devspaces + namespace: eclipse-che + spec: + components: + cheServer: + debug: false + logLevel: INFO + dashboard: {} + database: + credentialsSecretName: postgres-credentials + externalDb: false + postgresDb: dbche + postgresHostName: postgres + postgresPort: '5432' + pvc: + claimSize: 1Gi + devWorkspace: {} + devfileRegistry: {} + imagePuller: + enable: false + spec: {} + metrics: + enable: true + pluginRegistry: + openVSXURL: 'https://open-vsx.org' + containerRegistry: {} + devEnvironments: + startTimeoutSeconds: 300 + secondsOfRunBeforeIdling: -1 + maxNumberOfWorkspacesPerUser: -1 + containerBuildConfiguration: + openShiftSecurityContextConstraint: container-build + disableContainerBuildCapabilities: true + defaultEditor: che-incubator/che-code/insiders + defaultComponents: + - container: + image: >- + registry.redhat.io/devspaces/udi-rhel8@sha256:aa39ede33bcbda6aa2723d271c79ab8d8fd388c7dfcbc3d4ece745b7e9c84193 + sourceMapping: /projects + name: universal-developer-image + defaultNamespace: + autoProvision: true + template: -devspaces + secondsOfInactivityBeforeIdling: 1800 + storage: + pvcStrategy: per-user + gitServices: {} + networking: + auth: + gateway: + configLabels: + app: che + component: che-gateway-config diff --git a/openshift/setup.yml b/openshift/setup.yml new file mode 100644 index 000000000..14035878b --- /dev/null +++ b/openshift/setup.yml @@ -0,0 +1,25 @@ +--- +controller_components: + - credentials + - job_templates + +controller_credentials: + - name: OpenShift Credential + organization: Default + credential_type: OpenShift or Kubernetes API Bearer Token + inputs: + host: CHANGEME + bearer_token: CHANGEME + verify_ssl: false + +controller_templates: + - name: OpenShift / Dev Spaces + job_type: run + inventory: "Demo Inventory" + project: "Ansible official demo project" + playbook: "openshift/devspaces.yml" + notification_templates_started: Telemetry + notification_templates_success: Telemetry + notification_templates_error: Telemetry + credentials: + - "OpenShift Credential"