From cab4180bdab0a9343adbad029de5d145d93c6bd3 Mon Sep 17 00:00:00 2001 From: sean cavanaugh Date: Fri, 4 Oct 2024 16:15:54 -0400 Subject: [PATCH 1/8] sync to upstream devel --- .../01-controller/assignment.md | 258 ++++++++++++++++ .../01-controller/check-controller | 9 + .../01-controller/solve-controller | 1 + .../02-hybrid-cloud-info-module/assignment.md | 291 ++++++++++++++++++ .../check-controller | 10 + .../setup-controller | 5 + .../solve-controller | 1 + .../03-cloudreport/assignment.md | 217 +++++++++++++ .../03-cloudreport/check-controller | 10 + .../03-cloudreport/setup-controller | 125 ++++++++ .../03-cloudreport/solve-controller | 1 + .../assets/Aug-09-2024_at_13.54.42-image.png | Bin 0 -> 7498 bytes .../assets/Aug-09-2024_at_13.55.38-image.png | Bin 0 -> 6896 bytes .../assets/Aug-09-2024_at_14.01.54-image.png | Bin 0 -> 15634 bytes .../assets/Aug-09-2024_at_14.02.38-image.png | Bin 0 -> 7135 bytes tracks/cloud-visibility/config.yml | 73 +++++ tracks/cloud-visibility/track.yml | 36 +++ .../track_scripts/setup-controller | 131 ++++++++ 18 files changed, 1168 insertions(+) create mode 100755 tracks/cloud-visibility/01-controller/assignment.md create mode 100755 tracks/cloud-visibility/01-controller/check-controller create mode 100755 tracks/cloud-visibility/01-controller/solve-controller create mode 100755 tracks/cloud-visibility/02-hybrid-cloud-info-module/assignment.md create mode 100755 tracks/cloud-visibility/02-hybrid-cloud-info-module/check-controller create mode 100755 tracks/cloud-visibility/02-hybrid-cloud-info-module/setup-controller create mode 100755 tracks/cloud-visibility/02-hybrid-cloud-info-module/solve-controller create mode 100755 tracks/cloud-visibility/03-cloudreport/assignment.md create mode 100755 tracks/cloud-visibility/03-cloudreport/check-controller create mode 100755 tracks/cloud-visibility/03-cloudreport/setup-controller create mode 100755 tracks/cloud-visibility/03-cloudreport/solve-controller create mode 100644 tracks/cloud-visibility/assets/Aug-09-2024_at_13.54.42-image.png create mode 100644 tracks/cloud-visibility/assets/Aug-09-2024_at_13.55.38-image.png create mode 100644 tracks/cloud-visibility/assets/Aug-09-2024_at_14.01.54-image.png create mode 100644 tracks/cloud-visibility/assets/Aug-09-2024_at_14.02.38-image.png create mode 100644 tracks/cloud-visibility/config.yml create mode 100755 tracks/cloud-visibility/track.yml create mode 100755 tracks/cloud-visibility/track_scripts/setup-controller diff --git a/tracks/cloud-visibility/01-controller/assignment.md b/tracks/cloud-visibility/01-controller/assignment.md new file mode 100755 index 00000000..b1351683 --- /dev/null +++ b/tracks/cloud-visibility/01-controller/assignment.md @@ -0,0 +1,258 @@ +--- +slug: controller +id: 4if5qoqvyjev +type: challenge +title: Understanding and using Automation controller +teaser: Setup dynamic inventory in automation controller for AWS EC2 +notes: +- type: text + contents: |- + Please click the Green Start button on the *bottom right corner* if it did not already start creating the lab environment.
+ + To begin your lab briefing click the white `>` on the right-> +- type: text + contents: | + # Automation controller + + The control plane for Ansible Automation Platform is the automation controller (replacing Ansible Tower). + +
+ + Automation controller helps standardize how automation is deployed, initiated, delegated, and audited, allowing enterprises to automate with confidence while reducing sprawl and variance. Manage inventory, launch and schedule workflows, track changes, and integrate into reporting, all from a centralized user interface and RESTful API. +- type: text + contents: |+ + # Inventories + + An Inventory is a collection of hosts against which jobs may be launched, the same as an Ansible inventory file. Inventories are divided into groups and these groups contain the actual hosts. Groups may be sourced manually, by entering host names into the automation controller, or from one of its supported cloud providers. + + # Inventory Plugins + + There is a variety of pre-built Inventory Plugins that are available: + + * Amazon Web Services EC2 + * Google Compute Engine + * Microsoft Azure Resource Manager + * VMware vCenter + +- type: text + contents: |- + Example of configuring AWS inventory source: + + ![picture of AWS inventory](https://docs.ansible.com/automation-controller/latest/html/userguide/_images/inventories-create-source-AWS-example.png) +- type: text + contents: |- + # Lab Diagram + + Here is a diagram of the lab topology. +
+
+ + There is one automation controller node, and two Red Hat Enterprise Linux nodes running in Amazon Web Services (AWS) Elastic Cloud (EC2). +- type: text + contents: |- + # Lets get started + + That is the end of of your lab briefing! + + Once the lab is setup you can click the Green start button in the bottom right corner of this window. +tabs: +- id: 90jzkougrut1 + title: Automation Controller + type: service + hostname: controller + port: 443 +- id: hx9j8lettyru + title: AWS console + type: service + hostname: cloud-client + path: / + port: 80 +difficulty: "" +timelimit: 300 +--- +👋 Introduction +=== +#### Estimated time to complete: *5 minutes*

+Welcome to the Ansible Hybrid Cloud Automation - Infrastructure visibility lab. In the following challenges and tasks we will guide you in understanding Infrastructure visibility use case. In this first challenge, you will learn about setting up a dynamic inventory for AWS EC2 in automation controller. + +Login to Automation controller with the following credentials + + + + + + + + + + +
username:admin
password:ansible123!
+ +☑️ Task 1 - Understanding credentials +=== + +Credentials are utilized for authentication when launching Jobs against machines, synchronizing with inventory sources, and importing project content from a version control system. In this lab, we have two different credentials: + +* **RHEL on AWS - SSH KEY** - This is an SSH key for the two Red Hat Enterprise Linux hosts running on AWS +* **aws_credential** - This is the AWS credential for performing actions on AWS cloud. For example, creating a VPC, or shutting down an instance. + +In the **Automation Controller** tab at the top of your window click on the **Credentials** link under **Resources** to examine the two pre-configured credentials. Login with the credentials provided above. + +**Note** The keys are encrypted so no one, not even an administrator, can see the key once it has been placed in automation controller. + + +☑️ Task 2 - Creating an Inventory +=== + +Click on the **Automation Controller** tab at the top of lab. Click on the **Inventories** link under the **Resources** group on the left navigation menu. Now, click the blue **Add** button and select **Add Inventory**. + + + +Fill out the following fields: + + + + + + +
ParameterValue
NameAWS Inventory
OrganizationDefault
+ +Click the blue **Save** button. + +☑️ Task 3 - Creating an Inventory Source +=== + +Now that you have created the **AWS Inventory** click on the Sources tab at the top of the inventory. + + + +Now click the blue **Add** button. + +Fill out the following fields: + + + + + + +
ParameterValue
NameAWS Source
SourceAmazon EC2
+ +Once you select **Amazon EC2** some more choices will pop up. Fill out the following field: + + + + + +
ParameterValue
Credential (click the magnifying glass)aws_credential
+ +Select the radio button next to `aws_credential`, then click select. + +Click **Save** + +Now click **Sync** to retrieve the inventory from AWS EC2. + +☑️ Task 4 - Examine the Inventory +=== + +For this task we will examine the inventory then run an ad-hoc job. Click on the **AWS Inventory** link to return to the top-level menu for the AWS Inventory. + + + +Now click on **Hosts**. There will be two hosts listed with their name pre-pended with **ec2**. These were dynamically pulled from AWS via the Inventory Plugin we just setup. Click the checkmark next to each host then click the **Run Command** button. Fill out the following fields: + +### **Details**: + + + + +
ParameterValue
Moduleping
+ +Click **Next** + +


+ +### **Execution Environment**: + +Select +* **Default execution environment** + +Click **Next** + +
+ +### **Credential**: + +Select +* **RHEL on AWS - SSH KEY** + +Click **Next** + +
+ +### **Preview** + +Press the **Launch** button. + +
+ + +The ad-hoc test will setup an Ansible ping task which will verify we have SSH connectivity between our control node and the two RHEL instances running on AWS. + +✅ Next Challenge +=== +Press the `Check` button below to go to the next challenge once you’ve completed the task. + +🐛 Encountered an issue? +==== + +If you have encountered an issue or have noticed something not quite right, please [open an issue](https://github.com/ansible/instruqt/issues/new?title=Issue+with+Ansible+Hybrid+Cloud+Automation+-+Infrastructure+visibility&assignees=ipvsean). + + diff --git a/tracks/cloud-visibility/01-controller/check-controller b/tracks/cloud-visibility/01-controller/check-controller new file mode 100755 index 00000000..5ecb46a4 --- /dev/null +++ b/tracks/cloud-visibility/01-controller/check-controller @@ -0,0 +1,9 @@ +#!/bin/bash + +tower-cli config verify_ssl false +tower-cli login admin --password ansible123! + +if ! tower-cli inventory list -f json | jq -e '.results[] | select(.name | match("AWS Inventory";"i"))'; then + fail-message "You have not created 'AWS inventory'" + exit 1 +fi \ No newline at end of file diff --git a/tracks/cloud-visibility/01-controller/solve-controller b/tracks/cloud-visibility/01-controller/solve-controller new file mode 100755 index 00000000..a9bf588e --- /dev/null +++ b/tracks/cloud-visibility/01-controller/solve-controller @@ -0,0 +1 @@ +#!/bin/bash diff --git a/tracks/cloud-visibility/02-hybrid-cloud-info-module/assignment.md b/tracks/cloud-visibility/02-hybrid-cloud-info-module/assignment.md new file mode 100755 index 00000000..16b63e16 --- /dev/null +++ b/tracks/cloud-visibility/02-hybrid-cloud-info-module/assignment.md @@ -0,0 +1,291 @@ +--- +slug: hybrid-cloud-info-module +id: bjcbifhf5o4y +type: challenge +title: Retrieve public cloud information +teaser: Create job templates in automation controller to retrieve public cloud structured + data +notes: +- type: text + contents: |- + # Challenge summary + + In this challenge, you'll perform automation against your AWS public cloud environment. You will also learn how to create a `Job Template` in Automation controller. + + You will launch a number of job templates to perform the following: + - Retrieve information about VPCs (Virtual Private Cloud) + - Retrieve information about EC2 instances (virtual computing environments + - Retrieve information about IGWs (internet gateways) +- type: text + contents: |- + # Infrastructure visibility + + Cloud automation begins and ends with structured data. Ansible can help retrieve information from your public cloud to help you understand your cloud footprint. + + +- type: text + contents: |+ + # Understanding Job Templates + + A job template is a definition and set of parameters for running an Ansible job. Job templates are useful to execute the same job many times. Job templates also encourage the reuse of Ansible playbook content and collaboration between teams. + + + +- type: text + contents: |- + # Lets get started + + That is the end of of your challenge briefing! + + Once the lab is setup you can click the Green start button in the bottom right corner of this window. +tabs: +- id: ryk3mt1oogaj + title: Ansible Automation Controller + type: service + hostname: controller + port: 443 +- id: rcuzyp1lngfk + title: AWS console + type: service + hostname: cloud-client + path: / + port: 80 +difficulty: "" +timelimit: 900 +--- +👋 Introduction +=== +#### Estimated time to complete: *5 minutes*

+Welcome to the second challenge. For this challenge we will learn how to retrieve public cloud information with a job template. + +Login to Automation controller with the following credentials + + + + + + + + + + +
username:admin
password:ansible123!
+ +☑️ Task 1 - Create a Job Template +=== + +To create a **Job Template** we need three main components: +1. An **inventory** to run the automation against +2. A **credential** to access the API +3. A **project** to sync playbooks from. + +Click the **Templates** link in the left navigation menu underneath the Resources tab. + + + +- Now click on `Add` then scroll down and click `Add job template` + +
+Fill out the following fields: +


+ + + + + + + + + + +
ParameterValue
NameRetrieve VPC info
Job TypeRun
InventoryDemo Inventory
ProjectAWS Demos Project
Execution EnvironmentAWS Execution Environment
Playbookplaybooks/info_vpcs.yml
Credentialsaws_credential
+
+ +* If you have trouble finding the `aws_credential` make sure you are looking under the Credential Type `Amazon Web Services` + +Click the blue **Save** button. + + +The project we are loading Ansible Playbooks from can be found here [https://github.com/ansible-cloud/aws_demos](https://github.com/ansible-cloud/aws_demos) + + +☑️ Task 2 - Launch the Job Template +=== + +Click the **Templates** link in the left navigation menu underneath the Resources tab. You will see your `Retrieve VPC info` job template. + +Click the rocket symbol to `Launch Template`. + + +This playbook has two tasks. The first task `amazon.aws.ec2_vpc_net_info` will retrieve structured data for VPCs (by default this will use `us-east-1`). The 2nd task will use the `debug` module to print this out to the terminal which we can see in the automation controller job window. + +Click on the `print vpc info to terminal` task output then click on the `JSON` tab. You will see the structured data retrieve for VPCs on us-east-1. We have pre-configured one (1) VPC on this region. + +![picture of json output](https://github.com/IPvSean/pictures_for_github/blob/master/public_cloud_json_output.png?raw=true) + +This structured data can be used in our future challenge to crate dynamic documentation. + + +☑️ Task 3 - Create a Survey +=== + +Click the **Templates** link in the left navigation menu underneath the Resources tab. You will see your `Retrieve VPC info` job template. + + + +* Click the `Retrieve VPC info` link to open the job template. +* Now, click the `Survey` tab at the top of the job template. + + + +* Click the blue `Add` button. + + + +Fill out the following values: +
+ + + + + + + + + + +
ParameterValue
QuestionWhat AWS region?
Descriptionchoose the AWS region you want
Answer variable nameec2_region
Answer typeMultiple Choice (single select)
Required☑️
Multiple Choice Options
  • us-east-1
  • us-east-2
  • eu-central-1
+ +Click the Default checkmark next to `us-east-1` + +Click the blue **Save** button. + +
+ +Make sure to click the toggle button to enabled the survey. + + + +Either click the `Details` tab or click the **Templates** link in the left navigation menu underneath the Resources tab. You will see your `Retrieve VPC info` job template again. Launch the job again. + +
+ +This time you will see a survey prompt: + + + +Surveys set extra variables for the playbook in a user-friendly question and answer way. This allows you to abstract complexity using question and answer format. + +Feel free to choose another region (other than us-east-1) and verify the output is different from us-east-1. + + +☑️ Task 4 - Optional - Create more job templates +=== + +This is an optional task. There is two more job templates similar to the `Retrieve VPC info` one we can create for EC2 instances and IGW (internet gateways) for AWS. Create the following two job templates: + + + + + + + + + + + + +
ParameterValue
NameRetrieve EC2 instances info
Job TypeRun
InventoryDemo Inventory
ProjectAWS Demos Project
Execution EnvironmentAWS Execution Environment
Playbookplaybooks/info_instances.yml
Credentialsaws_credential
+ +
+ + + + + + + + + +
NameRetrieve IGWs info
Job TypeRun
InventoryDemo Inventory
ProjectAWS Demos Project
Execution EnvironmentAWS Execution Environment
Playbookplaybooks/info_igws.yml
Credentialsaws_credential
+ +These will provide structured data for EC2 instances and IGWs respectively. Try adding a survey to them as well! + +
+ +Going even further... what if we combined all of these? Create one more job template: + + + + + + + + + +
NameRetrieve Combined info
Job TypeRun
InventoryDemo Inventory
ProjectAWS Demos Project
Execution EnvironmentAWS Execution Environment
Playbookplaybooks/info_combined.yml
Credentialsaws_credential
+ +This last one may look formatted incorrectly inside automation controller but what it is actually doing is combining the structured data from VPCs, EC2 instances and IGWs to create infrastructure awareness for the cloud administrator. This is what the standard out will look like (non-JSON): + +![picture of combined output](https://github.com/IPvSean/pictures_for_github/blob/master/cloud_awareness.png?raw=true) + +A cloud operator can quickly see how many instances are online in that region, and what VPCs they are on, as well as the associated IGW. This is combining several info modules which correspond to multiple AWS boto3 API calls. In the above image I can quickly see there is multiple VPCs that I can retire because they are not in use. + +✅ Next Challenge +=== +Press the `Check` button below to go to the next challenge once you’ve completed the task. + +🐛 Encountered an issue? +==== + +If you have encountered an issue or have noticed something not quite right, please [open an issue](https://github.com/ansible/instruqt/issues/new?title=Issue+with+Ansible+Hybrid+Cloud+Automation+-+Infrastructure+visibility&assignees=ipvsean). + + diff --git a/tracks/cloud-visibility/02-hybrid-cloud-info-module/check-controller b/tracks/cloud-visibility/02-hybrid-cloud-info-module/check-controller new file mode 100755 index 00000000..416d02d1 --- /dev/null +++ b/tracks/cloud-visibility/02-hybrid-cloud-info-module/check-controller @@ -0,0 +1,10 @@ +#!/bin/bash + +tower-cli config verify_ssl false +tower-cli login admin --password ansible123! + + +if ! tower-cli job_template list -f json | jq -e '.results[] | select(.name | match("Retrieve VPC info";"i"))'; then + fail-message "You have not created the 'Retrieve VPC info' job template" + exit 1 +fi \ No newline at end of file diff --git a/tracks/cloud-visibility/02-hybrid-cloud-info-module/setup-controller b/tracks/cloud-visibility/02-hybrid-cloud-info-module/setup-controller new file mode 100755 index 00000000..7d2fdfc3 --- /dev/null +++ b/tracks/cloud-visibility/02-hybrid-cloud-info-module/setup-controller @@ -0,0 +1,5 @@ +#!/bin/bash + +# ansible-playbook /tmp/setup-scripts/azure-lab-1/azure_creds.yml + +exit 0 \ No newline at end of file diff --git a/tracks/cloud-visibility/02-hybrid-cloud-info-module/solve-controller b/tracks/cloud-visibility/02-hybrid-cloud-info-module/solve-controller new file mode 100755 index 00000000..a9bf588e --- /dev/null +++ b/tracks/cloud-visibility/02-hybrid-cloud-info-module/solve-controller @@ -0,0 +1 @@ +#!/bin/bash diff --git a/tracks/cloud-visibility/03-cloudreport/assignment.md b/tracks/cloud-visibility/03-cloudreport/assignment.md new file mode 100755 index 00000000..21ba8f4d --- /dev/null +++ b/tracks/cloud-visibility/03-cloudreport/assignment.md @@ -0,0 +1,217 @@ +--- +slug: cloudreport +id: 0m2bcdieznwl +type: challenge +title: Creating Dynamic Documentation +teaser: Create a dynamic HTML website out of your public cloud structured data +notes: +- type: text + contents: |- + # Challenge summary + + In this challenge we will create Dynamic Documentation. Public cloud enviornments are often being used by many different teams and invidiuals. By using automation we can quickly get a 'lay of the land' and then generate easy-to-read HTML, markdown, CSV files or whatever our team requires. Specifically in this challenge we will create an HTML website from some pre-made Ansible roles. +- type: text + contents: |- + # Example dynamic documentation + + ![example picture of report](https://github.com/IPvSean/pictures_for_github/blob/master/big_cloud_report.png?raw=true) + + In this report it is really easy for the cloud operator to see there is several VPCs that are empty (containing no instances) that could be retired. +- type: text + contents: |- + # Lets get started + + That is the end of of your challenge briefing! + + Once the lab is setup you can click the Green start button in the bottom right corner of this window. +tabs: +- id: ymwtxnuvvmmn + title: Ansible Automation Controller + type: service + hostname: controller + port: 443 +- id: t4yjd0nc4r9n + title: AWS console + type: service + hostname: cloud-client + path: / + port: 80 +- id: dczapdobgtsm + title: Dynamic Report + type: service + hostname: controller + path: / + port: 8088 +difficulty: "" +timelimit: 1500 +--- +👋 Introduction +=== +#### Estimated time to complete: *5 minutes*

+Welcome to the third challenge. For this challenge we will create dynamic documentation. More specifically we will generated a HTML website using the structured data that we showcased in the previous challenge. + +Login to Automation controller with the following credentials + + + + + + + + + + +
username:admin
password:ansible123!
+ +☑️ Task 1 - Create a new Job Template +=== + +Click the **Templates** link in the left navigation menu underneath the Resources tab. + +![templates link picture](https://github.com/IPvSean/pictures_for_github/blob/master/job_templates.png?raw=true) + +Click the blue Add button and click `Add job template` + +Fill out the following fields: + + + + + + + + + + + +
ParameterValue
NameCreate Report
Job TypeRun
InventoryDemo Inventory
ProjectAWS Demos Project
Execution EnvironmentAWS Execution Environment
Playbookplaybooks/cloud_report.yml
Credentialsaws_credential
+ +* If you have trouble finding the `aws_credential` make sure you are looking under the Credential Type `Amazon Web Services` + +Click the blue **Save** button. + +The project we are loading Ansible Playbooks from can be found here [https://github.com/ansible-cloud/aws_demos](https://github.com/ansible-cloud/aws_demos) + +☑️ Task 2 - Add a survey +=== + +For this next step we are going to add a survey so the user can select where they want the HTML report hosted. This allows the operator to select a Linux host to serve the HTML file for others to view! + +Click the Survey tab ![Aug-09-2024_at_13.54.42-image.png](../assets/Aug-09-2024_at_13.54.42-image.png) + +Click the blue Add button ![Aug-09-2024_at_13.55.38-image.png](../assets/Aug-09-2024_at_13.55.38-image.png) + +Fill out the following table: + + + + + + + +
ParameterValue
NameWhich host should host the report?
Answer variable name _hosts
Answer typeMultiple Choice (single select)
Multiple Choice Optionsansible-1
+ +For lab purposes we are just going to host it on the host ansible-1 but we are showing how this can be easily configurable by the administrator to allow you to choose anywhere to host dynamic documentaition. If you don't select a host we can just use Amazon S3 and host it there. + +☑️ Task 3 - Launch the Job Template +=== + +Click the **Templates** link in the left navigation menu underneath the Resources tab. You will see your `Create Report` job template. + +Click the rocket symbol to `Launch Template`. + + +Select the host: +![Aug-09-2024_at_14.01.54-image.png](../assets/Aug-09-2024_at_14.01.54-image.png) + +Click Next and then Launch. +![Aug-09-2024_at_14.02.38-image.png](../assets/Aug-09-2024_at_14.02.38-image.png) + +## Explanation: +## +This playbook has two roles. + +1. The first role will retrieve structured data for VPCs, EC2 instances and IGWs as shown in the previous challenge. A link to the source code can be [found here](https://github.com/ansible-cloud/aws_demos/tree/master/roles/retrieve_info) + +2. The 2nd role will create an HTML report. This will install a web server, copy over CSS and images, and template out the structured data into an HTML website. A link to the source code can be [found here](https://github.com/ansible-cloud/aws_demos/tree/master/roles/build_report). + +When the job completes click the `Dynamic Report` tab at the top of your lab window. The report will be generated. + +**Make sure to refresh the window using the** + +Click on the gray boxes with the caret '>' to expand the tables with additional information. + +You will see a report similar to the following: +![picture of report](https://github.com/IPvSean/pictures_for_github/blob/master/cloud_report.png?raw=true) + + +☑️ Task 4 - Compare Regions +=== + +A cloud operator can quickly see how many instances are online in that region, and what VPCs they are on, as well as the associated IGW. This is combining several info modules which correspond to multiple AWS boto3 API calls. In the cloud report I can quickly gain awareness of my cloud footprint. + +Important considerations for a cloud operator: + +- How can I identify VPCs in Amazon EC2 that are not in use and can be safely deleted to free up resources for my team to provision additional VPCs? +- Which regions are running instances versus which ones that are empty? +- Which regions have stopped instances that may turn on at any moment? + + +✅ Finished! +=== +Press the `Check` button below to check your work. + +🐛 Encountered an issue? +==== + +If you have encountered an issue or have noticed something not quite right, please [open an issue](https://github.com/ansible/instruqt/issues/new?title=Issue+with+Ansible+Hybrid+Cloud+Automation+-+Infrastructure+visibility&assignees=ipvsean). + + diff --git a/tracks/cloud-visibility/03-cloudreport/check-controller b/tracks/cloud-visibility/03-cloudreport/check-controller new file mode 100755 index 00000000..73a52c79 --- /dev/null +++ b/tracks/cloud-visibility/03-cloudreport/check-controller @@ -0,0 +1,10 @@ +#!/bin/bash + +tower-cli config verify_ssl false +tower-cli login admin --password ansible123! + + +if ! tower-cli job_template list -f json | jq -e '.results[] | select(.name | match("Create Report";"i"))'; then + fail-message "You have not created the 'Create Report' job template" + exit 1 +fi \ No newline at end of file diff --git a/tracks/cloud-visibility/03-cloudreport/setup-controller b/tracks/cloud-visibility/03-cloudreport/setup-controller new file mode 100755 index 00000000..e9dcceeb --- /dev/null +++ b/tracks/cloud-visibility/03-cloudreport/setup-controller @@ -0,0 +1,125 @@ +#!/bin/bash + +# # ansible-playbook /tmp/setup-scripts/azure-lab-1/azure_creds.yml +# # +# # Create a playbook for the user to execute which will create a SN incident +# tee /tmp/setup-scripts/azure-lab-1/azure.yml << EOF +# --- +# - name: deploy azure credential +# hosts: localhost +# gather_facts: false +# become: true + +# tasks: + +# - name: add azure credential to automation controller +# awx.awx.credential: +# name: azure_credential +# description: Azure Instruqt Credential +# organization: "Default" +# state: present +# credential_type: Microsoft Azure Resource Manager +# controller_config_file: "{{ playbook_dir }}/../controller.cfg" +# inputs: +# subscription: "{{ lookup('env','INSTRUQT_AZURE_SUBSCRIPTION_AAPAZURELAB_SUBSCRIPTION_ID') }}" +# tenant: "{{ lookup('env','INSTRUQT_AZURE_SUBSCRIPTION_AAPAZURELAB_TENANT_ID') }}" +# username: "{{ lookup('env','INSTRUQT_AZURE_SUBSCRIPTION_AAPAZURELAB_USERNAME') }}" +# password: "{{ lookup('env','INSTRUQT_AZURE_SUBSCRIPTION_AAPAZURELAB_PASSWORD') }}" + +# - name: Add EE to the controller instance +# awx.awx.execution_environment: +# name: "Microsoft Azure Execution Environment" +# image: quay.io/acme_corp/azure_ee +# controller_config_file: "{{ playbook_dir }}/../controller.cfg" + +# - name: Add project +# awx.awx.project: +# name: "Azure Demos Project" +# description: "This is from github.com/ansible-cloud" +# organization: "Default" +# state: present +# scm_type: git +# scm_url: https://github.com/ansible-cloud/azure-demos +# default_environment: "Microsoft Azure Execution Environment" +# controller_config_file: "{{ playbook_dir }}/../controller.cfg" + +# - name: delete native job template +# awx.awx.job_template: +# name: "Demo Job Template" +# state: "absent" +# controller_config_file: "{{ playbook_dir }}/../controller.cfg" + +# - name: create job template +# awx.awx.job_template: +# name: "{{ item.name }}" +# job_type: "run" +# organization: "Default" +# inventory: "Demo Inventory" +# project: "Azure Demos Project" +# extra_vars: +# resource_group_name: "azure-demo" +# region: "eastus" +# vnet_cidr: "10.0.0.0/16" +# subnet_cidr: "10.0.1.0/24" +# vnet_name: "demo_vnet" +# subnet_name: "demo_subnet" +# network_sec_group_name: "demo_sec_group" +# win_vm_name: "WIN-ansible" +# win_vm_size: "Standard_DS1_v2" +# win_vm_sku: "2022-Datacenter" +# win_public_ip_name: "win_demo_ip" +# win_nic_name: "win_demo_nic" +# win_admin_user: "azureuser" +# win_admin_password: "ansible123!" +# playbook: "project/{{ item.playbook }}" +# credentials: +# - "azure_credential" +# state: "present" +# controller_config_file: "{{ playbook_dir }}/../controller.cfg" +# with_items: +# - { playbook: 'create_resource_group.yml', name: 'Create Azure Resource Group' } +# - { playbook: 'create_windows_vm_demo.yml', name: 'Create Windows Server 2022 VM' } +# - { playbook: 'destroy_resource_group.yml', name: 'Destroy Azure Resource Group' } + +# - name: create job template +# awx.awx.job_template: +# name: "{{ item.name }}" +# job_type: "run" +# organization: "Default" +# inventory: "Demo Inventory" +# project: "Azure Demos Project" +# extra_vars: +# resource_group_name: "azure-demo" +# region: "eastus" +# vnet_cidr: "10.0.0.0/16" +# subnet_cidr: "10.0.1.0/24" +# vnet_name: "demo_vnet" +# subnet_name: "demo_subnet" +# network_sec_group_name: "demo_sec_group" +# win_vm_name: "WIN-ansible" +# win_vm_size: "Standard_DS1_v2" +# win_vm_sku: "2022-Datacenter" +# win_public_ip_name: "win_demo_ip" +# win_nic_name: "win_demo_nic" +# win_admin_user: "azureuser" +# win_admin_password: "ansible123!" +# playbook: "workflow/{{ item.playbook }}" +# credentials: +# - "azure_credential" +# state: "present" +# controller_config_file: "{{ playbook_dir }}/../controller.cfg" +# with_items: +# - { playbook: '01-create_resource_group.yml', name: 'Workflow - 01 - Create Resource Group' } +# - { playbook: '02-create_virtual_network.yml', name: 'Workflow - 02 - Create Virtual Network' } +# - { playbook: '03-add_subnet.yml', name: 'Workflow - 03- Add Subnet' } +# - { playbook: '04-create_public_ip_address.yml', name: 'Workflow - 04 - Create Public IP Address' } +# - { playbook: '05-create_network_security_group.yml', name: 'Workflow - 05 - Create Network Security Group' } +# - { playbook: '06-create_virtual_network_interface_card.yml', name: 'Workflow - 06 - Create Virtual Network Interface Card' } +# - { playbook: '07-create_windows_2022_vm.yml', name: 'Workflow - 07 - Create Windows 2022 Virtual Machine' } + +# EOF + +# # Execute above playbook +# ansible-playbook /tmp/setup-scripts/azure-lab-1/azure.yml + +exit 0 \ No newline at end of file diff --git a/tracks/cloud-visibility/03-cloudreport/solve-controller b/tracks/cloud-visibility/03-cloudreport/solve-controller new file mode 100755 index 00000000..a9bf588e --- /dev/null +++ b/tracks/cloud-visibility/03-cloudreport/solve-controller @@ -0,0 +1 @@ +#!/bin/bash diff --git a/tracks/cloud-visibility/assets/Aug-09-2024_at_13.54.42-image.png b/tracks/cloud-visibility/assets/Aug-09-2024_at_13.54.42-image.png new file mode 100644 index 0000000000000000000000000000000000000000..939858be597a499615d58545a76f6e92b87dd7cf GIT binary patch literal 7498 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 literal 0 HcmV?d00001 diff --git a/tracks/cloud-visibility/assets/Aug-09-2024_at_13.55.38-image.png b/tracks/cloud-visibility/assets/Aug-09-2024_at_13.55.38-image.png new file mode 100644 index 0000000000000000000000000000000000000000..749db01632754a41586a55391a012af256dc387e GIT binary patch literal 6896 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 EAK90FHvj+t literal 0 HcmV?d00001 diff --git a/tracks/cloud-visibility/assets/Aug-09-2024_at_14.01.54-image.png b/tracks/cloud-visibility/assets/Aug-09-2024_at_14.01.54-image.png new file mode 100644 index 0000000000000000000000000000000000000000..6256f6adcbcd7db825ba08727f407bca19123921 GIT binary patch literal 15634 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 literal 0 HcmV?d00001 diff --git a/tracks/cloud-visibility/assets/Aug-09-2024_at_14.02.38-image.png b/tracks/cloud-visibility/assets/Aug-09-2024_at_14.02.38-image.png new file mode 100644 index 0000000000000000000000000000000000000000..08685cd1a3ccc9cc6871690ffabbe03b958663c6 GIT binary patch literal 7135 zcmc(CWmFtn)9&Ez?h**@7GSU-gF_&|;5xwIGK9e`xVr~;cb5Z-1)r>gd|XH9oUYiok=u&J>D005qfvVsmme@2K4COYD3?0X^# z0N_eP<>j?i;A;f4e^&^eBE&AapR@ z=ZOLMMPkzQ4C51k(IAa48tbOiKq7=YQa zL1L`+VfoQK_NjT&C<-7t^jUnt=tTGxBLGgO#r**znElIC#eOV=QooQV1nGINc7zaV zr)tDJDZF9rDQ^UxI~Tx4kJlgtDR>1kCWH;A(w46yuwo-JXGfOJM{3e?Ikk}lvY{%?{kpj!G5n&MF`QC5Bk_C0Ba_E=#I)TK~rz7*=lC?uZr@?~)ZB3$>Wx!mCT!{?RXg%D7O*JK z$jD@#qupr5SKzW~4EO$^I4f>VvI7N<6L%pw&Bi#fuqD<8MtyN|t+7ZPoub5w*o%@K zQum#3!?lm>ioh#DLi{C00Dmy)XJLLS8zf6VS9!i(-JhsPyh*{hi~xL9TQ`N`UJzAI2=Jn(E z>F{)nFH<3UpC8Yz<$g=P3svt-NyhiJsU$EWMu|omCbS})B^MhEaN`5gn%!G?z0d9( z-2(QnlDr|7z)Zwk#L9oYn)+HXrJ$G=N1`Y&Nst06vya>nnp58?bBgz=NU%PZ27s}K zc4N8S|FMP3W_i35VrY3+df!2H_gy&c6)79GDwWcYlBGMK&Xneqm$G8U5yM4El!!C? z=5f)Rg8P=BF=>W&OBrJ;oF0Q6V1j>9XBC4#`#?l)rwi-jGOKEP#d z&=o;Yn3jIV2VjL!1$_lyOuzqI;bk%EMz+`rwbxYH*SO?sM5wq4Q3uaLw~u#^k%OIr zUikNKC`?@9DRi7jiainldJ_q7acLi>!|5?B3MBpSbNf9-)jPc^0dDotZ0V%z&rDt= zpBR1nt}&1Cevo!)@cJ2w*cRHIEF&gbG9x}qSTz5QdgnB&1!or4eh9HPdPazz1>F*6 zdoZ1a*b)KtAdwq!9umb{h#TEncufUPFCbux?kbKE6RU^`robQ|$4%rnOl8R|t;|TA zFwFQtnKLCMijYH)Bs(#UX>UxzMo1^@SUx8yb&v3BEbL zi8o4$iX-YH@~lRRm4XJ4_;IszPfh|o>1v0nm8xdF(Hd2~%t{vnsUlzFUwH9KEydTf zI`-GCtgX~594ja*7$V&{CDfq!22oI*PMz6F%!-;AHr+bygWW&$IIm4AKtjrP;mg%MaCOuSpXTg~h8 zXyfC(@T5JZW0u8Iv8C6$dR)H-F_RfBtwMw94$xWm23tTxU}0eUgU3Dk{VjTDNWNU_ z+m~T@=oNUrk&XnH)YCL(68?|hB_k?}@-5@Gao_PoI7i$oy;pjxWL46pR1xPJ?-hR^ z*Aizy%^-9tP?UR>g{h&RLo4Pp{n4_KQany1PG6~@st6iYwE$~@_I$Mya%_ROFt+Xk!OR<9b(q%}MA&|D6dEaC+0Wsb&4A`Q_iX%brgJ!O$b=d|y+6>mdACrkG<2L%%293$JQptZ z9oE3m!^n^ik*|9v4>BEf8)Y6vAI*Hiqf{PeB7J^5=Bin*DXwXpf0{5yO(s!o|MH@8 zar)IX@Idvzu>@KYrZhvf{_G|_wl8)N5;nnO(0v46M62hiH(y^{XL0dzkvb(mtvb~^ z70X_kWZ$>i7bggf92lidd_vD4wGO-Y?h3vro*= z`-b0NCqVQXc9V1C5l|DraGibo`@SSz<$O4BiT! z3;r!zH+VJZ6+#d?87dg+5Ox!48fJ%DfXVdwbvQRc*9U=}@6SZ?`n4}V8Wz=AR$De% z9u3iluZF7)<&G9x%a7Jm`tc13J|~?e#9|gt=3+hr8GKZEYu) z!M?|(OZiP_J9l3)-mk}ZL}$M5V5ww_)2dW~7f>dF-z;Sd3qtkhMr^`tEIq8TIarw> z#;T8s=nWt>jVDbq~#J zt!|a3&+W*$3_Tk)|8PbG#~DYPnd_UMnC}tl71Fo)X>((%Z}S^_dB|(Xz>vw1re(tp zWa~OZKc+IdoT@ghG387Qjc!(~OO0pK%3Wh>r^t+wtbl78ij-*)KV8m<+|?L!oLr2M zId|5f`N}sJi6)Jfj>b^_R9%W+!!yU;XcgA;HMU%a3zzfG8C^O|tOQd2b<#(OVcKeH z1xS;fFWLi1xX#-VH}woVIL!j(XG)!2GFKFz7k6Bc9EefSkj?M}-l=`(Yh!g_O-aec z=_PkEiQ*&Wbut(Bon2AfRJ|^v7|$E$9Pj7e=js1`RB66=C(+0fpmM9zQAU$Nlo_3| z4nFPi2X)!{SYCf2vo=_0u&L!Xy?*tnRPTVxgj2M>ygsA;)P$tJ+`VpO1>!hRJ7MD8 zH#gv+m2UZ|xcc(w`l!L_`>J-wtiAQ}d#&8pxh~H58z$z?dZta`on;mi^L1FpGY{|Y z>TGl0wl_PQcf_`PpGGau8htU-ZJBpFm@{hCH(G6RysMw+L3t(iS$x5Hqok+8iEoK( z{np?7TR+Y1yWbtO7W9>p_CAf@2=BF_QaUny{S8blMJ)ndO(h(yRb|UH*B>oM->oKQ z(N_VhJz-x3zBTPwqm1GtUKS7*97<)opSw?#X7p5~Xqr04yEx0xy}DV;E)=SmZl0!> zIS4o%^O?EOpva=2=Iu7Eb@gUnV?$CSe-qmHTKH9|9Z=h+0*Xg@Y zeXufeM6@XBGQ8R8<#{(XZG30E-r?yo(5>rsaIxNXiFv7d=D5}Xx40_2Ay}394eR!z z51{%5qYfj zg}@Ml8|7yUuwMV@$2)a?QJ*h|yFnUev)WV^q0soAL(;)5av0#>or&;W2EY)k+u5;Xt~ zVId(z8j0o~TM3CBfby3g832fc0#N_X(M0G!D+wWgF#pjgDG>k+#2qn0;DyNlWPdJ1 z`Nwua!~k--@+v9_t!wQ8fw*|uyTYEozmGyVu-udlJpll6)<1%zqQmkXQU5daB^U_9SakYZ*!kyjz)BynD5(v{70<&a#pofjEgpPvJ-*Cj86tg`H<|e_%=k4vy>n+6V>S4zx zATBP>$1lhyD9D4z;PLcvfmyXpuj&~32i7G;$)}*bw+T8=pij2zz_T@ z|No2px8uK%;Qt~81%&^N{8!}vMe2D%Jmg)S5iMcT|2?k1!T%2a4FvN2+4;Yi_z%s0 zc@aEIV*~mAIWuW&xe=Q?#4*xB6|`O=G~!40*Ahcq*%9(bBLvN%hWnENLW`;>$i0Lk z9p^hbk?K)KZ1O07!Uij1v+|&k3WNDI%0dV^tQ6z0hY43hDT+fJqF&6VbaFV?$qYZG ze9pX4OvL;Gm1`qKANfvpLQ$g#kDLa}SX~80rS|s9+vcXo+;PE6D*(NXwOJN9LWDbzdq!Mh^gsv=$ zf)rDR#3`Qw7_q`j3PwjJRYQ3h!GaVsLd}SThsvITUWu!MXejcphOJS*_D63UJ+-6) zAKJ*)rTR+Mk?V;&9S#ZCL^;rK4s3U_@0RNmoN>!v)@n}}*0MjMf)d&&e_U%Kzah>N zWhFaHlMek+CDtiHP-Zn{-W9FWl_QOB8yTEbb8}L00@M2p$_DS8H|*3oKuD|^iM3S< zOYQq>GQ-D*ca~KlRQwqZ$SwtKY0>F{T2!ttE9=qU>nh2veYD@uE9c%QL*^iHbaMGn z_TEYo3$D7guz|h!z5-ldv@dH$QV2G)3;uG8*zGyQsEfS;L05y&;Ew=EoI%G=i;s@{tnG)DX~2=w5N}Q`x58X~5_uD*`&vYIYqs#y6SW8VQNG197ms=`Ux%v1Vj6F4jm>1vm)`x~ilTu-*SSRJjYR|01KL zy&5oCNtERULjP7Qqu_qGn>~U3=9v@wzRhOb1x2^Eu{Uzxw%dUFPIQ?S{XKrQ8`~MS zL~zy3{>b-Ig<8&DoNJtBH(d{6uhqf{MmsW%I z8eAB(@k?6Zg2&};YNgtXrn&aV8D~MQ=7Vn|2xG=OioP`PwoFM7xc3C?>l|G0hxIhd zHPOoIb7WkRKYX31;7h3*_XO*eC(x8kdeuwe zm9A7G-1^AA1dLxn@=Jo#CUb3RU$R<7j)8`5D)0bN4Ht-3jhEE^5-A)B;Q9{PmgvqsIoGOhL?k!(Vo*KIw?oTx~q^pIXSyh zq^Kx6A->GMld;k;Cq7)q$Y{<6TL?da24aDC8lSaWnU%&Rp28I~W_9U(Xu3J%w|3NX zDd0PBK(JvLczHK{y>`3jMDb?Tlp_iKZO15d3GnnC4dCB)&W3c|XaemOmMk8dRK= zb*ZfG3bGP;T8hu(v-baN3~9_OtX_=zrS2w)olHNT;LK3ee2zUXW1!sSgZA^wn=fh2 za9q6O`4_Felar)3KIU)MPz-RmI8Mo8Xn(%`UXYY0_kpH)uboz-KyfNZnDDFScI@Fw zyj7RFib8xNZJT^FpOh0LH(MoQ$hQHKvvXgG7UpU!)9X09bd|~=dkc+nQZLNrhi+_c z)JT8%H`>RxHS*f9CgtYRtaI=@8IZfEIZiB57a8(czz0eHmFYxr8$oE}Ri@nPTf&Ty`1xlcA{i)!`??j!^4FwN z2Y%h|Eeid``aELPmmUl`L{fz-M6nf#(kS~M7L7n@E@m$~+TDe9vM$*yl#$6cdD~nf z-U%ylN5Z+WnYeLiFNuM_B%3+(ZA`iX)sBbPx!U5yO|0)(PO!Td$thYHa+Jkl&%kDP zLE~gYs*nD_U*GoGfV^7Q;p9PmE#vJ=6R#VOlbfa@8=bPF@&E-5dS20fSnD>NA!-DdP z+EdsgBhX`7SU2i~(4@jY$w}}ovHqIaP242dYCo3rFru}({B{cJE44cK_;UExY~3LMnb)zn0fJ*QQNlTm9sAWCBPO|MSoe z@B&I-QHLVaTSXNKO=Ho)_r;DqIw1O)8(uOpHVpMEI@HJNlRlDMxxL*SLLF)bjf*}O zk&rj&Udi=uTJUn$m*`z6wOakg{6?|ss=K%6*kL~x`jVO_pC9Y00nrDZwh3_9;UT!;CMA|d@;zl z`oxOgG$A_QJ%ypTc7u_q>`0;TVw3*i{LrS^QVw#kJOBDBerIwbtpOyd?$xtHasaL` ztewLch+I5zciqv5fBw~Ua9unox-E0uVHn0K{46-8)Y&f(ZfGJxcjX*+;OkAedX|lG z{?hf`BJ4K(CbBUtC6o@ck`Z886^y1!sI3YZ(ow~J#aI{$cwL4}t}Z9bfrP2X!Lbw) zjEzi~feq$ILn=dMHye z%~>T_vCUya`P^}SvRU>Zt$awZExjWAt6>-HctO$0KC5tR9)b!lVQw_#ih;N1s#OH- z(=8~1_wflake(n|iGwfB+O1>Bg1etYp#1MU?l8nGiy7;9mX-c|%%~`8D%3x>2>m|| CvHDa1 literal 0 HcmV?d00001 diff --git a/tracks/cloud-visibility/config.yml b/tracks/cloud-visibility/config.yml new file mode 100644 index 00000000..ea38f294 --- /dev/null +++ b/tracks/cloud-visibility/config.yml @@ -0,0 +1,73 @@ +version: "3" +containers: +- name: cloud-client + image: gcr.io/instruqt/cloud-client + shell: /bin/bash + ports: + - 80 + memory: 256 +virtualmachines: +- name: controller + image: red-hat-mbu/automation-controller + shell: /bin/su - rhel -s /bin/bash + environment: + TERM: xterm + machine_type: n1-standard-4 +aws_accounts: +- name: awsaccount + iam_policy: |- + { + "Version": "2012-10-17", + "Statement": [ + { + "Sid":"EC2DefaultAllow", + "Effect": "Allow", + "Action": "ec2:*", + "Resource": "*" + } + ] + } + scp_policy: | + { + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "LimitInstanceTypeRun", + "Action": [ + "ec2:RunInstances" + ], + "Effect": "Deny", + "Resource": "arn:aws:ec2:*:*:instance/*", + "Condition": { + "StringNotEqualsIfExists": { + "ec2:InstanceType": [ + "t2.micro" + ] + } + } + }, + { + "Sid": "LimitInstanceTypeModify", + "Action": [ + "ec2:ModifyInstanceAttribute" + ], + "Effect": "Deny", + "Resource": "arn:aws:ec2:*:*:instance/*", + "Condition": { + "ForAnyValue:StringNotEquals": { + "ec2:Attribute/InstanceType": [ + "t2.micro" + ] + } + } + }, + { + "Sid": "AllowS3BucketCreation", + "Action": [ + "s3:CreateBucket" + ], + "Effect": "Allow", + "Resource": "arn:aws:s3:::*" + } + ] + } diff --git a/tracks/cloud-visibility/track.yml b/tracks/cloud-visibility/track.yml new file mode 100755 index 00000000..74ae814f --- /dev/null +++ b/tracks/cloud-visibility/track.yml @@ -0,0 +1,36 @@ +slug: cloud-visibility +id: a9reffypixbu +title: 'Hybrid cloud automation: AWS Infrastructure visibility' +teaser: Use Red Hat Ansible Automation Platform to retrieve structured data from public + clouds and provide dynamic documentation. +description: |- + The goal of this lab is to illustrate how Ansible info modules can retrieve from public clouds can provide us awareness of our cloud footprint easily and output it to anything. + + ![picture of lab diagram](https://github.com/IPvSean/pictures_for_github/blob/master/aws-diagram.png?raw=true) +icon: https://github.com/network-automation/networking-icons/raw/master/multi-cloud/multicloud-red.png +tags: +- hybridcloud +- ansible +- ansibleautomationplatform +- aap +owner: redhat +developers: +- seanc@redhat.com +instructors: +- sgallego@redhat.com +- zleblanc@redhat.com +- dlemons@redhat.com +show_timer: true +skipping_enabled: true +timelimit: 2700 +lab_config: + overlay: false + width: 33 + position: right + feedback_recap_enabled: true + feedback_tab_enabled: false + loadingMessages: true + lab_v2: false + override_challenge_layout: false + hideStopButton: false +checksum: "68337299409420722" diff --git a/tracks/cloud-visibility/track_scripts/setup-controller b/tracks/cloud-visibility/track_scripts/setup-controller new file mode 100755 index 00000000..af629e9a --- /dev/null +++ b/tracks/cloud-visibility/track_scripts/setup-controller @@ -0,0 +1,131 @@ +#!/bin/bash + + +# +# Create a playbook for the user to execute +tee /tmp/aws_setup.yml << EOF +--- +- name: deploy azure credential + hosts: localhost + gather_facts: false + become: true + vars: + username: admin + admin_password: ansible123! + + tasks: + + - name: add aws credential to automation controller + awx.awx.credential: + name: aws_credential + description: Amazon Web Services + organization: "Default" + state: present + credential_type: "Amazon Web Services" + controller_username: "{{ username }}" + controller_password: "{{ admin_password }}" + controller_host: "https://{{ ansible_host }}" + validate_certs: false + inputs: + username: "{{ lookup('env','INSTRUQT_AWS_ACCOUNT_AWSACCOUNT_AWS_ACCESS_KEY_ID') }}" + password: "{{ lookup('env','INSTRUQT_AWS_ACCOUNT_AWSACCOUNT_AWS_SECRET_ACCESS_KEY') }}" + register: controller_try + retries: 5 + until: controller_try is not failed + + - name: Add EE to the controller instance + awx.awx.execution_environment: + name: "AWS Execution Environment" + image: quay.io/acme_corp/aws_ee + controller_username: "{{ username }}" + controller_password: "{{ admin_password }}" + controller_host: "https://{{ ansible_host }}" + validate_certs: false + + - name: Add project + awx.awx.project: + name: "AWS Demos Project" + description: "This is from github.com/ansible-cloud" + organization: "Default" + state: present + scm_type: git + scm_url: https://github.com/ansible-cloud/aws_demos + default_environment: "AWS Execution Environment" + controller_username: "{{ username }}" + controller_password: "{{ admin_password }}" + controller_host: "https://{{ ansible_host }}" + validate_certs: false + + - name: delete native job template + awx.awx.job_template: + name: "Demo Job Template" + state: "absent" + controller_username: "{{ username }}" + controller_password: "{{ admin_password }}" + controller_host: "https://{{ ansible_host }}" + validate_certs: false + + - name: create job template + awx.awx.job_template: + name: "{{ item.name }}" + job_type: "run" + organization: "Default" + inventory: "Demo Inventory" + project: "AWS Demos Project" + playbook: "{{ item.playbook }}" + credentials: + - "aws_credential" + state: "present" + controller_username: "{{ username }}" + controller_password: "{{ admin_password }}" + controller_host: "https://{{ ansible_host }}" + validate_certs: false + with_items: + - { playbook: 'playbooks/aws_resources.yml', name: 'Create AWS Resources' } + - { playbook: 'playbooks/aws_instances.yml', name: 'Create AWS Instances' } + + - name: Launch a job template + awx.awx.job_launch: + job_template: "Create AWS Resources" + validate_certs: "false" + controller_username: "{{ username }}" + controller_password: "{{ admin_password }}" + controller_host: "https://{{ ansible_host }}" + register: job + + - name: Wait for job to finish + awx.awx.job_wait: + job_id: "{{ job.id }}" + controller_username: "{{ username }}" + controller_password: "{{ admin_password }}" + controller_host: "https://{{ ansible_host }}" + validate_certs: "false" + + - name: Launch a job template + awx.awx.job_launch: + job_template: "Create AWS Instances" + validate_certs: "false" + controller_username: "{{ username }}" + controller_password: "{{ admin_password }}" + controller_host: "https://{{ ansible_host }}" + + - name: Add ansible-1 host + awx.awx.host: + name: "ansible-1" + inventory: "Demo Inventory" + state: present + controller_username: "{{ username }}" + controller_password: "{{ admin_password }}" + controller_host: "https://{{ ansible_host }}" + validate_certs: false + variables: + note: in production these passwords would be encrypted in vault + ansible_user: rhel + ansible_password: ansible123! + ansible_host: controller +EOF + +# Execute above playbook +ansible-playbook /tmp/aws_setup.yml + +exit 0 \ No newline at end of file From 2b3ace6d3a4902777bd83cc14fa976727704086a Mon Sep 17 00:00:00 2001 From: sean cavanaugh Date: Fri, 4 Oct 2024 16:18:36 -0400 Subject: [PATCH 2/8] Update README.md --- README.md | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 060f37ad..ce911565 100644 --- a/README.md +++ b/README.md @@ -19,33 +19,33 @@ - + Event-Driven Ansible Technical Workshop - 🔬 Open Workshop + 🔬 Open Workshop - + Introduction to cloud automation - 🔬 Open Workshop + 🔬 Open Workshop - + Ansible Lightspeed and Development Technical Workshop - 🔬 Open Workshop + 🔬 Open Workshop - + Getting Started with Network Automation - 🔬 Open Workshop + 🔬 Open Workshop - + Getting Started with ServiceNow Automation - 🔬 Open Workshop + 🔬 Open Workshop - + Getting Started with Windows Automation - 🔬 Open Workshop + 🔬 Open Workshop - + Getting Started with Configuration as Code for Ansible Automation Platform 2 Technical Workshop - 🔬 Open Workshop + 🔬 Open Workshop @@ -60,17 +60,17 @@ - + Event-Driven Ansible & ServiceNow Technical Workshop - 🔬 Open Workshop + 🔬 Open Workshop - + Ansible Lightspeed and Development Technical Workshop - 🔬 Open Workshop + 🔬 Open Workshop - + Getting Started with Configuration as Code for Ansible Automation Platform 2 Technical Workshop - 🔬 Open Workshop + 🔬 Open Workshop From 39c4b5b73b07742ea97bc353732a8f3ea98e911d Mon Sep 17 00:00:00 2001 From: sean cavanaugh Date: Fri, 4 Oct 2024 16:26:51 -0400 Subject: [PATCH 3/8] Update README.md --- README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index ce911565..3621c7ce 100644 --- a/README.md +++ b/README.md @@ -19,31 +19,31 @@ - + Event-Driven Ansible Technical Workshop 🔬 Open Workshop - + Introduction to cloud automation 🔬 Open Workshop - + Ansible Lightspeed and Development Technical Workshop 🔬 Open Workshop - + Getting Started with Network Automation 🔬 Open Workshop - + Getting Started with ServiceNow Automation 🔬 Open Workshop - + Getting Started with Windows Automation 🔬 Open Workshop - + Getting Started with Configuration as Code for Ansible Automation Platform 2 Technical Workshop 🔬 Open Workshop @@ -60,15 +60,15 @@ - + Event-Driven Ansible & ServiceNow Technical Workshop 🔬 Open Workshop - + Ansible Lightspeed and Development Technical Workshop 🔬 Open Workshop - + Getting Started with Configuration as Code for Ansible Automation Platform 2 Technical Workshop 🔬 Open Workshop From 9f3153fba9b18315a57b712505f1c93b9736380a Mon Sep 17 00:00:00 2001 From: sean cavanaugh Date: Fri, 4 Oct 2024 16:33:25 -0400 Subject: [PATCH 4/8] Update README.md --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 3621c7ce..6e59f7ea 100644 --- a/README.md +++ b/README.md @@ -19,31 +19,31 @@ - + Event-Driven Ansible Technical Workshop 🔬 Open Workshop - + Introduction to cloud automation 🔬 Open Workshop - + Ansible Lightspeed and Development Technical Workshop 🔬 Open Workshop - + Getting Started with Network Automation 🔬 Open Workshop - + Getting Started with ServiceNow Automation 🔬 Open Workshop - + Getting Started with Windows Automation 🔬 Open Workshop - + Getting Started with Configuration as Code for Ansible Automation Platform 2 Technical Workshop 🔬 Open Workshop From ae8e73dbd64b33087fdef4796eca9f5c3a43887b Mon Sep 17 00:00:00 2001 From: sean cavanaugh Date: Fri, 4 Oct 2024 16:38:08 -0400 Subject: [PATCH 5/8] sync idea --- README.md | 2 +- assets/tablelink.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6e59f7ea..62db7254 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ Event-Driven Ansible Technical Workshop - 🔬 Open Workshop + 🔬 Open Workshop Introduction to cloud automation diff --git a/assets/tablelink.js b/assets/tablelink.js index 11dc2a35..bd0dd90e 100644 --- a/assets/tablelink.js +++ b/assets/tablelink.js @@ -2,6 +2,6 @@ const tableRows = document.querySelectorAll(".table-clickable tbody tr"); for (const tableRow of tableRows) { tableRow.addEventListener("click", function () { - window.open(this.dataset.href, "_blank"); + window.location.href = this.dataset.href; }); } \ No newline at end of file From 1f6f37a40887f01077c1ecf0bd054b5168e1b06a Mon Sep 17 00:00:00 2001 From: sean cavanaugh Date: Fri, 4 Oct 2024 16:45:27 -0400 Subject: [PATCH 6/8] Update tablelink.js --- assets/tablelink.js | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/assets/tablelink.js b/assets/tablelink.js index bd0dd90e..02d43b75 100644 --- a/assets/tablelink.js +++ b/assets/tablelink.js @@ -1,7 +1,19 @@ +// const tableRows = document.querySelectorAll(".table-clickable tbody tr"); + +// for (const tableRow of tableRows) { +// tableRow.addEventListener("click", function () { +// window.location.href = this.dataset.href; +// }); +// } + const tableRows = document.querySelectorAll(".table-clickable tbody tr"); for (const tableRow of tableRows) { - tableRow.addEventListener("click", function () { - window.location.href = this.dataset.href; + tableRow.addEventListener("click", function (event) { + // Prevent the link's default behavior if clicked + event.preventDefault(); + + // Ensure the row's data-href link always wins + window.open(this.dataset.href, "_blank"); }); -} \ No newline at end of file +} From c9706b596cd7b05dda431bdbfce7cb540f420bf2 Mon Sep 17 00:00:00 2001 From: sean cavanaugh Date: Fri, 4 Oct 2024 16:48:08 -0400 Subject: [PATCH 7/8] Update tablelink.js --- assets/tablelink.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/tablelink.js b/assets/tablelink.js index 02d43b75..bef76176 100644 --- a/assets/tablelink.js +++ b/assets/tablelink.js @@ -14,6 +14,6 @@ for (const tableRow of tableRows) { event.preventDefault(); // Ensure the row's data-href link always wins - window.open(this.dataset.href, "_blank"); + window.location.href = this.dataset.href; }); } From 838498b814349069a966d4d573988f21c786c7b8 Mon Sep 17 00:00:00 2001 From: sean cavanaugh Date: Fri, 4 Oct 2024 16:48:47 -0400 Subject: [PATCH 8/8] Update README.md --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 62db7254..35664a87 100644 --- a/README.md +++ b/README.md @@ -25,27 +25,27 @@ Introduction to cloud automation - 🔬 Open Workshop + 🔬 Open Workshop Ansible Lightspeed and Development Technical Workshop - 🔬 Open Workshop + 🔬 Open Workshop Getting Started with Network Automation - 🔬 Open Workshop + 🔬 Open Workshop Getting Started with ServiceNow Automation - 🔬 Open Workshop + 🔬 Open Workshop Getting Started with Windows Automation - 🔬 Open Workshop + 🔬 Open Workshop Getting Started with Configuration as Code for Ansible Automation Platform 2 Technical Workshop - 🔬 Open Workshop + 🔬 Open Workshop @@ -62,15 +62,15 @@ Event-Driven Ansible & ServiceNow Technical Workshop - 🔬 Open Workshop + 🔬 Open Workshop Ansible Lightspeed and Development Technical Workshop - 🔬 Open Workshop + 🔬 Open Workshop Getting Started with Configuration as Code for Ansible Automation Platform 2 Technical Workshop - 🔬 Open Workshop + 🔬 Open Workshop