Introduction to DevOps - GeeksforGeeks
Question : How to install Oracle database
- Navigate to the Azure Portal and find your Ubuntu Virtual Machine.
- Under the left-hand menu, click Networking.
- Click Add inbound port rule.
- Set the Destination port ranges to
1521and Protocol toTCP. - Click Add to save.
# Update local package index
sudo apt-get update
# Install Docker
sudo apt-get install -y docker.io
# Start and enable the Docker service
sudo systemctl start docker
sudo systemctl enable docker
sudo docker run -d \
--name oracle23ai \
-p 1521:1521 \
-e ORACLE_PASSWORD=YourSecurePassword123 \
://oracle.com
banglamon/oracle193db:19.3.0-ee and map your variables accordingly. []sudo docker logs -f oracle23ai
DATABASE IS READY TO USE before proceeding. []# Access the container's bash environment
sudo docker exec -it oracle23ai bash
# Log into SQL*Plus as the System Administrator
sqlplus sys/YourSecurePassword123 as sysdba
- Connection Type: Basic
- Host:
<Your_Azure_VM_Public_IP> - Port:
1521 - Service Name / SID:
FREE(orFREEPDB1for the pluggable database. For 19c images, this is usuallyORCLorSE). - Username:
SYSTEM - Password:
YourSecurePassword123
A playbook is failing on a specific task. Describe your systematic approach to debugging the issue. What command-line flags and Ansible modules would you use?
To debug a failing Ansible task :
- Increase verbosity using
-vvv to get detailed output. - Isolate the issue with
--limit and --start-at-task. - Use
debug and register to inspect variables and task output. - Run in check mode with
--check --diff to preview changes.
-vvv to get detailed output.--limit and --start-at-task.debug and register to inspect variables and task output.--check --diff to preview changes.How Can You Programmatically Access A Variable Name Within An Ansible Playbook?
To access a variable name programmatically within an Ansible playbook, setup the `set_fact` module with a task like:
This task sets `var_name` based on the variable name corresponding to the specified value (`my_value`). Try on adjusting `my_variable` and `my_value` accordingly.
You have a playbook that takes an unacceptably long time to run against 500 hosts. What are the first three things you would investigate or tune to improve its performance?
To improve the performance of a slow playbook running against 500 hosts, I’d first investigate three key areas:
- Enable SSH Pipelining – Reduces overhead by reusing SSH connections, speeding up task execution.
- Increase Forks – Boosts parallelism by allowing Ansible to manage more hosts simultaneously (default is 5).
- Configure Fact Caching – Stores host facts to avoid re-gathering them on every run, saving time across large inventories.
Explain Ansible Inventory And Discuss Its Various Types.
Ansible Inventory is a collection of hosts (managed nodes) that Ansible targets during automation. It defines which machines to configure and how they are grouped.
Types of Inventory
- Static Inventory
Defined manually in an INI or YAML file. - Hosts and groups are explicitly listed.
- Simple and ideal for small or stable environments.
Dynamic Inventory
- Generated automatically using scripts or plugins.
- Pulls host data from external sources like AWS, Azure, GCP, or CMDBs.
- Ideal for cloud-native or large-scale environments with frequent changes.
Defined manually in an INI or YAML file.
Can You Automate Password Input In An Ansible Playbook Using Encrypted Files?
Yes, you can automate password input in Ansible playbooks using encrypted files through Ansible Vault. Vault allows you to securely store sensitive data like passwords, API keys, or private credentials in encrypted YAML files. These files can be referenced in your playbooks just like regular variables, ensuring secure automation without exposing secrets in plain text. You can create a Vault file using:
Then include it in your playbook with vars_files, and unlock it during execution using --ask-vault-pass or --vault-password-file.
vars_files, and unlock it during execution using --ask-vault-pass or --vault-password-file.Can You Automate Password Input In An Ansible Playbook Using Encrypted Files?
Yes, you can automate password input in Ansible playbooks using encrypted files through Ansible Vault. Vault allows you to securely store sensitive data like passwords, API keys, or private credentials in encrypted YAML files. These files can be referenced in your playbooks just like regular variables, ensuring secure automation without exposing secrets in plain text. You can create a Vault file using:
Then include it in your playbook with vars_files, and unlock it during execution using --ask-vault-pass or --vault-password-file.
vars_files, and unlock it during execution using --ask-vault-pass or --vault-password-file.What Command Will You Use To Run An Ansible Playbook With a Specific Inventory File?
To run an Ansible playbook with a specific inventory file, use the ansible-playbook command with the -i option to specify the inventory.
Example:
Replace /path/to/inventory/file with the actual path to your inventory file and myplaybook.yml with your playbook name. The -i flag tells Ansible which inventory to use during execution.
ansible-playbook command with the -i option to specify the inventory.Example:
/path/to/inventory/file with the actual path to your inventory file and myplaybook.yml with your playbook name. The -i flag tells Ansible which inventory to use during execution.Not all Ansible modules are inherently idempotent. How can a playbook author enforce idempotency when using modules like shell or command?
Modules like shell and command execute arbitrary commands without checking system state, risking unintended changes. To enforce idempotency, authors can use parameters like creates or removes to conditionally run tasks. More robustly, they can register command output and use changed when or when clauses to control execution based on actual system conditions. This discipline ensures predictable and resilient automation
How do Ansible roles promote modularity and collaboration in automation workflows? Describe the purpose of each key file in a standard role directory.
Ansible roles organize automation into reusable, modular units, making playbooks cleaner and easier to share.
tasks/main.yml: contains the core tasks the role performs.handlers/main.yml: defines actions triggered by task notifications.defaults/main.yml: sets low-priority, user-overridable variables.vars/main.yml: holds high-priority internal variables.meta/main.yml: includes role metadata and dependencies.
You’re tasked with deploying a new version of a multi-tier web application (web frontends, APIs, database) behind a load balancer. How would you design an Ansible-based rolling update strategy to ensure zero downtime? Describe the key plays, tasks, and features you'd use.
To ensure zero downtime during a rolling update of a multi-tier web application, Design a master orchestration playbook that sequences the deployment across tiers starting with database migrations, followed by API services, and finally the web frontends.
For the web and API tiers, Iuse the serial keyword (e.g., serial: 1 or serial: 25%) to update servers in controlled batches. Before updating each server, use the ansible.builtin.uri module to call the load balancer’s API and drain or disable the server from the active pool. Once isolated, run the application deployment role.
After deployment, Iperform health checks using either ansible.builtin.uri to hit a health endpoint or ansible.builtin.wait_for to confirm the service port is listening. If the server passes, re-enable it in the load balancer and proceed to the next one.
To handle failures gracefully, wrap the critical steps in a block with a rescue section. If anything fails like a health check. I could trigger a rollback, alert an operator, or re-add the server to the load balancer in its previous state to maintain capacity.
This strategy ensures safe, staged updates with minimal disruption to live traffic.
- Trigger: The event that tells the pipeline to run, such as pushing code to a branch or making a pull request.
- Stage: A major boundary in the pipeline (e.g., "Build Code", "Run QA Tests", "Deploy to Production").
- Job: A series of steps that runs on a single execution agent. Jobs can run sequentially or in parallel.
- Step/Task: The smallest building block, such as a script, command, or pre-built plugin that compiles code or copies files.
- Agent: The computing engine (hosted by Microsoft or managed by you) that executes the jobs.
- Artifact: The physical output generated by a build step (like a .zip or .war file) used for deployment. [
- YAML Pipelines (Recommended): Your pipeline is defined entirely as code inside a file named
azure-pipelines.ymlat the root of your repository. This allows you to track pipeline changes using version control. - Classic Editor: A visual, drag-and-drop user interface inside the Azure DevOps web portal. This option is generally used for simpler legacy systems or quick graphical proofs-of-concept.
main branch, running on a Microsoft-hosted Ubuntu environment: trigger:
- main
pool:
vmImage: ubuntu-latest
stages:
- stage: BuildStage
jobs:
- job: BuildJob
steps:
- script: echo "Compiling application source code..."
displayName: 'Compile Code'
- stage: DeployStage
dependsOn: BuildStage
jobs:
- job: DeployJob
steps:
- script: echo "Deploying artifact to hosting environment..."
displayName: 'Execute Deployment'
- Log into your organization via the Azure DevOps Portal.
- Select your target project, choose Pipelines from the left panel, and click New Pipeline.
- Point the wizard to your code repository (e.g., Azure Repos, GitHub, or Bitbucket).
- Select a preset configuration template matching your technology stack (such as Node.js, .NET Core, or Maven).
- Review the generated YAML schema, click Save and Run, and monitor the real-time build logs. [
ansible.builtin.import_tasks is a static reuse module in Ansible. It injects a list of external tasks into a playbook at parse time (before execution begins). Conditional statements or tags applied to an import_tasks line copy down to every individual child task inside the imported file. playbook.yml):- hosts: all
tasks:
- name: Import web server configuration tasks
ansible.builtin.import_tasks: web_tasks.yml
tags: ['web']
web_tasks.yml):- name: Install Nginx
ansible.builtin.apt:
name: nginx
state: present
- name: Start Nginx service
ansible.builtin.service:
name: nginx
state: started
ansible-playbook with a syntax check and dry run: # Check playbook syntax and verify static file resolution
ansible-playbook --syntax-check playbook.yml
# Run a dry-run check
ansible-playbook playbook.yml --check
web_tasks.yml during the initial parsing phase. If web_tasks.yml is missing, the command fails immediately even before connecting to any target hosts. - Missing File Errors (
ERROR! the file/tasks file could not be found):- Cause:
import_tasksevaluates paths at parse time. The target file must physically exist on the controller. - Fix: Ensure the relative path points accurately to the file location from the playbook root.
- Cause:
- Using Loops (
with_*orloop) Fails:- Cause: Loops are not supported directly on
import_tasks. - Fix: Switch the module to
ansible.builtin.include_tasksif you require runtime iteration loops.
- Cause: Loops are not supported directly on
- Dynamic Variable in File Path Fails:
- Cause: Host-level inventory variables are not resolved during the parse phase for file names.
- Fix: Pass variables via
--extra-varsor useinclude_tasksinstead for dynamic filenames.
failed_when conditional in Ansible overrides the default failure criteria of a task, allowing you to define exactly what constitutes a failure based on command output, return codes, or variable values. rc) is not 0. failed_when lets you change this logic. 0. - name: Run custom disk check script
ansible.builtin.command: /usr/local/bin/check_disk.sh
register: disk_result
failed_when: "'Error' in disk_result.stdout"
2 and the output contains the word critical.---
- name: Test Case for failed_when
hosts: localhost
gather_facts: false
tasks:
- name: Simulate a tool execution
ansible.builtin.shell: |
echo "Status: critical failure detected"
exit 3
register: tool_output
ignore_errors: true # Prevents the playbook from stopping completely so we can see the result
- name: Evaluate custom failure conditions
ansible.builtin.debug:
msg: "The previous task met custom failure criteria!"
failed_when:
- tool_output.rc > 2
- "'critical' in tool_output.stdout"
- Issue: The task crashes with an
"error": "The task includes an option with an undefined variable"message. - Cause: You tried to inspect
stdoutorrcon a task that skipped or did not register output. - Fix: Add a check to ensure the variable exists first.yaml
failed_when: disk_result.stdout is defined and "Error" in disk_result.stdout
and vs or)- Issue: The task fails when it should pass, or passes when it should fail.
- Cause: Listing conditions as a YAML array implies an
ANDoperation. - Fix: For an
ORoperation, write the condition explicitly on a single line.yaml# Fails if rc is 2 OR if stdout contains 'Failed' failed_when: tool_output.rc == 2 or "Failed" in tool_output.stdout
changed Status- Issue: The task reports
failedbut still shows a status ofchanged. - Fix: Combine
failed_whenwithchanged_whento cleanly manage the task lifecycle state.
ignore_unreachable: true ignore_unreachable: true is an Ansible keyword that prevents a playbook from failing entirely when a managed host cannot be reached via SSH or WinRMignore_unreachable at the play level or individual task level. ---
- name: Demonstrate ignore_unreachable at task level
hosts: all
gather_facts: no
tasks:
- name: Attempt to connect to a potentially offline server
ansible.builtin.ping:
ignore_unreachable: true
register: ping_result
- name: This task runs even if the host was unreachable above
ansible.builtin.debug:
msg: "The ping task completed. Unreachable status: {{ ping_result.unreachable | default(false) }}"
hosts.ini containing one real local host and one fake, unreachable IP address. [servers]
localhost ansible_connection=local
fake_server ansible_host=192.0.2.1 ansible_connection=ssh
test_unreachable.yml. It uses ignore_unreachable: true to prevent the fake_server failure from halting the execution setup.---
- name: Test Case for ignore_unreachable
hosts: servers
gather_facts: no
tasks:
- name: Execute a command on all hosts
ansible.builtin.command: echo "Checking connectivity"
ignore_unreachable: true
register: task_output
- name: Inspect the output variables
ansible.builtin.debug:
msg: "Host {{ inventory_hostname }} finished with unreachable status: {{ task_output.unreachable | default(false) }}"
ansible-playbook -i hosts.ini test_unreachable.yml
- Expected CLI Output:
Ansible will display a redUNREACHABLE!warning message forfake_server, but instead of halting, it will smoothly proceed to the "Inspect the output variables" task. - Variable State:
Forfake_server, thetask_outputvariable will contain"unreachable": trueand"failed": true. You can use this registered dictionary downstream withwhen: task_output.unreachableto conditionally trigger fallback tasks.
- Subsequent Tasks Fail: If a host is truly offline, setting
ignore_unreachable: trueon Task A means Task B will still attempt to run on that offline host. Task B will then fail with an "Unreachable" error unless you also add the keyword to Task B or add a conditional check likewhen: task_output.unreachable is not defined. - Play-level vs Task-level: If you set
ignore_unreachable: trueat the play level, it applies togather_facts. If the host is unreachable during fact gathering, Ansible ignores it and proceeds into the tasks section with an empty fact cache for that host. - Handlers are Skipped: If a host becomes unreachable during a task that notified a handler, that handler will not run for the unreachable host, even if
ignore_unreachableis enabled. - Differentiating from
ignore_errors: Do not confuse these two settings.ignore_errors: truehandles cases where the host is reachable, but a command returns a non-zero exit code.ignore_errorswill not catch SSH connection timeouts or connection refused errors; onlyignore_unreachablecan catch those.
block groups multiple tasks together to apply shared configurations or handle errors. It functions like a try-catch-finally block in traditional programming. [become or when to multiple tasks at once. ---
- name: Managed web server configuration
hosts: webservers
tasks:
- name: Setup Web Server Configuration
block:
- name: Install Apache
ansible.builtin.apt:
name: apache2
state: present
- name: Start Apache Service
ansible.builtin.systemd:
name: apache2
state: started
enabled: true
become: true
when: ansible_os_family == "Debian"
block, rescue, and always to handle task failures gracefully. block: Runs the main tasks.rescue: Runs only if a task in theblockfails.always: Runs no matter what happens in the previous sections.
---
- name: Test error handling with blocks
hosts: localhost
gather_facts: false
tasks:
- name: Attempt dangerous file operation
block:
- name: Read a non-existent file
ansible.builtin.command: cat /tmp/missing_file.txt
register: file_output
rescue:
- name: Handle the failure
ansible.builtin.debug:
msg: "The file was missing! Creating a backup file now..."
- name: Create fallback file
ansible.builtin.file:
path: /tmp/missing_file.txt
state: touch
always:
- name: Final cleanup task
ansible.builtin.debug:
msg: "This task always runs, regardless of success or failure."
- Invalid Directives: You cannot apply loops (
loop,with_items) to ablock. Apply the loop to individual tasks inside the block instead. - Variable Scope: Variables registered inside a failed
blocktask may be undefined in therescuesection. Useblock_failed_taskor check for variable existence usingis definedbefore referencing them. - Playbook Failure: If a task in the
rescuesection fails, the entire playbook run will fail immediately. Keep rescue tasks simple and safe. - Task Status: If the
rescuesection successfully resolves the issue, the overall play status will show asok(orchanged), notfailed. [
- Git: The modern standard, offering distributed version control where every developer has a full copy of the repository locally.
- Team Foundation Version Control (TFVC): A legacy, centralized version control system where history is maintained exclusively on a server.
- Unlimited Private Repos: Host unlimited repositories for small or enterprise-scale projects.
- Pull Requests (PRs): Facilitate asynchronous code reviews, inline discussions, and feedback loops before merging code.
- Branch Policies: Protect critical branches (like
main) by enforcing rules such as required reviewers, successful build validation, or mandatory work item linking. - Semantic Code Search: Locate specific classes, functions, or text across all repositories using advanced query syntax.
- IDE & Tooling Flexibility: Connect natively using Visual Studio, VS Code, Git CLI, or any standard Git client. [
- Create/Initialize: Set up a new repository in your project via the web portal or command line.
- Clone: Copy the remote repository locally using a secure HTTPS or SSH connection string.
- Branch: Create a feature branch to write your code changes safely away from production code.
- Commit & Push: Commit your local changes and push the branch back to Azure Repos.
- Merge: Open a pull request, complete code reviews, pass build pipelines, and merge changes. [
[ Developer ] ---> ( Git Push ) ---> [ Azure DevOps Repo ]
|
( Webhook Trigger )
v
[ Managed Infrastructure ] <--- [ Ansible AWX Project Sync & Job Execution ]
- Code Commit: A developer updates an Ansible playbook or inventory file locally and pushes it to Azure Repos.
- Automation Trigger: Azure DevOps fires a service hook (webhook) to AWX, or AWX polls the repository on a schedule.
- Project Sync: AWX pulls the latest code from the specific Git branch.
- Job Execution: AWX runs the playbook against target environments using secure credentials stored natively within AWX.
├── ansible.cfg
├── environments/
│ ├── dev/
│ │ └── hosts.yml
│ └── prod/
│ └── hosts.yml
├── playbooks/
│ └── deploy_web.yml
└── roles/
└── webserver/
└── tasks/
└── main.yml
playbooks/deploy_web.yml)---
- name: Configure Corporate Web Servers
hosts: webservers
become: yes
tasks:
- name: Ensure Apache is at the latest version
ansible.builtin.package:
name: httpd
state: latest
- name: Start and enable Apache service
ansible.builtin.service:
name: httpd
state: started
enabled: yes
- Generate Git Credentials: In Azure DevOps, go to User Settings > Personal Access Tokens (PAT). Create a token with Code (Read) permissions.
- Configure AWX Credentials:
- Log into AWX and navigate to Credentials > Add.
- Set Credential Type to Source Control.
- Input your Azure DevOps username and paste the PAT into the Password/Token field.
- Create AWX Project:
- Navigate to Projects > Add.
- Set Source Control Type to Git.
- Paste your Azure Repos HTTPS clone URL into the Source Control URL field.
- Select the Source Control credential you created above.
- Enable Update Revision on Launch to ensure AWX always pulls the newest code before running.
azure-pipelines.yml file. [azure-pipelines.yml) trigger:
- main
pr:
- main
pool:
vmImage: 'ubuntu-latest'
steps:
- task: UsePythonVersion@0
inputs:
versionSpec: '3.10'
displayName: 'Set up Python'
- script: |
python -m pip install --upgrade pip
pip install ansible ansible-lint
displayName: 'Install Ansible and Linting Tools'
- script: |
ansible-lint playbooks/deploy_web.yml
displayName: 'Run Ansible Lint (Static Code Analysis)'
- script: |
ansible-playbook --syntax-check playbooks/deploy_web.yml
displayName: 'Run Playbook Syntax Check'- Write Code in VS Code: Clone your Azure repo locally. Create a feature branch. Write your Ansible playbook (
site.yaml) and inventory files. - Commit and Push: Stage and commit your changes in VS Code. Push the feature branch to Azure Repos.
- Pull Request (PR): Create a PR in Azure DevOps to merge the feature branch into the
mainbranch. Peer review the YAML syntax. - AWX Sync: Configure Ansible AWX with a project pointing to your Azure Git repository via a Personal Access Token (PAT). AWX pulls the updated
mainbranch automatically or via webhook. - Run Job Template: Execute the job template in AWX using the synced playbook from Azure Repos. [
site.yaml)---
- hosts: webservers
become: yes
tasks:
- name: Ensure Nginx is installed
apt:
name: nginx
state: present
- name: Ensure Nginx is running
service:
name: nginx
state: started
- Syntax Test (Pre-commit): Run
ansible-playbook --syntax-check site.yamllocally inside VS Code terminal to verify YAML indentation and syntax rules. - Integration Test: Trigger an AWX job template in "Check Mode" (dry run) against a staging environment to confirm task viability before applying production changes.
- Q: How does Ansible AWX authenticate with a private Azure DevOps Git repository?
A: AWX authenticates using a Git Source Control credential configured with a Personal Access Token (PAT) generated from Azure DevOps. - Q: Why use VS Code for Ansible development instead of editing directly in AWX?
A: VS Code provides local extension linting, syntax validation (ansible-lint), and local Git staging control before changes affect production workflows. - Q: How do you automate AWX project updates when a change is merged into Azure Repos?
A: You can set the AWX Job Template to update the project on launch, or configure an Azure DevOps Service Hook / Webhook to call the AWX API whenever a push or merge occurs on the main branch.
- Generate an SSH key pair locally (
ssh-keygen -t rsa -b 4048). - Log into Azure DevOps.
- Click your User Profile Icon (top right) → User settings → SSH public keys.
- Click + New Key, paste your public key (
id_rsa.pub), and save. - Go to your repository and copy the SSH clone URL (e.g.,
git@://azure.com:v3/...). [
- Navigate to Credentials → Add.
- Name it
Azure DevOps SSH Key. - Set Credential Type to
Source Control. - Paste your private key (
id_rsa) into the SSH Private Key box. Save it. - Navigate to Projects → Add.
- Set Source Control Type to
Git. - Paste your Azure DevOps SSH clone URL into the Source Control URL field.
- Select the
Azure DevOps SSH Keycredential you created. Save and click Sync. [
- Navigate to Templates → Add → Add job template.
- Link your Inventory, the newly synced Project, and select your target Playbook.
- Under Variables, check the box Prompt on Launch for Extra Variables (this allows Azure DevOps to pass runtime parameters dynamically).
- Save the template. Note the ID number from the URL (e.g.,
/templates/job_template/42/). [
- In AWX, click on Users and select your automation user.
- Click the Tokens tab → Add.
- Set Scope to
Writeand save. - Copy the generated Bearer Token immediately.
azure-pipelines.yml file to send an API request to AWX. This triggers the template automatically when changes occur. azure-pipelines.yml)trigger:
- main
pool:
vmImage: 'ubuntu-latest'
variables:
# Map your secret token securely in the ADO library pipeline UI
AWX_TOKEN: $(AWX_API_TOKEN)
AWX_URL: 'https://your-awx-url.com'
TEMPLATE_ID: '42' # Replace with your template ID
steps:
- bash: |
echo "Triggering Ansible AWX Job Template..."
# Send the API request to launch the job
RESPONSE=$(curl -X POST \
-H "Authorization: Bearer $(AWX_TOKEN)" \
-H "Content-Type: application/json" \
-d '{"extra_vars": {"build_id": "$(Build.BuildId)", "environment": "production"}}' \
-s -k "$(AWX_URL)/api/v2/job_templates/$(TEMPLATE_ID)/launch/")
# Extract Job ID to track execution status
JOB_ID=$(echo $RESPONSE | grep -oP '"job":\s*\K[0-9]+')
if [ -z "$JOB_ID" ]; then
echo "Failed to initiate AWX Job."
echo "Response: $RESPONSE"
exit 1
fi
echo "AWX Job successfully launched. Job ID: $JOB_ID"
# Optional: Poll AWX API to track completion status
echo "Checking job status..."
while true; do
STATUS_RESP=$(curl -X GET -H "Authorization: Bearer $(AWX_TOKEN)" -s -k "$(AWX_URL)/api/v2/jobs/$JOB_ID/")
STATUS=$(echo $STATUS_RESP | grep -oP '"status":\s*"\K[^"]+')
echo "Current Status: $STATUS"
if [ "$STATUS" == "successful" ]; then
echo "Ansible Playbook completed successfully!"
break
elif [ "$STATUS" == "failed" ] || [ "$STATUS" == "error" ] || [ "$STATUS" == "canceled" ]; then
echo "Ansible Playbook failed."
exit 1
fi
sleep 10
done
displayName: 'Trigger and Monitor Ansible AWX Job'
- Open your pipeline in the Azure DevOps editor.
- Click Variables in the top right corner.
- Click New variable.
- Name it
AWX_API_TOKEN. - Paste your AWX token into the value box.
- Check Keep this value secret to mask it in logs.
main branch, the pipeline will auto-fire, send the build details to AWX as extra_vars, and watch the deployment succeed in real-time. - Navigate to Azure DevOps Services and click Start free.
- Sign in using your Microsoft account, GitHub account, or a Work/School account linked to Microsoft Entra ID. [
- Click New organization from the left pane or click Continue on the initial prompt.
- Enter an Organization Name following these constraints:
- Use English alphabet letters, numbers, or hyphens only.
- Must start and end with a letter or number.
- Keep the name under 50 characters.
- Select your closest hosting geography (e.g., United States, Europe, India) to reduce pipeline latency.
- Complete the CAPTCHA and click Continue.
- Click the New project button in the upper-right corner.
- Assign a specific Project Name and short description.
- Choose your visibility level (Public or Private).
- Select your preferred Version Control system (usually Git) and Work item process template (e.g., Agile, Scrum).
- Click Create. [
- For Cloud App Services / Kubernetes: Go to Pipelines > Environments > Create environment to group physical or virtual cloud resources for pipeline orchestration.
- For On-Premises VMs: Go to Pipelines > Deployment groups > New, select your OS target type, and execute the provided registration script on your target servers.
wsl command-line utility in Windows PowerShell or Command Prompt. The core shutdown command is wsl --shutdown, while maintenance tasks use options like --terminate, --export, and --set-version. - Shut down all running distributions and the WSL 2 lightweight utility VM:
wsl --shutdown - Stop a single specific Linux distribution:
wsl --terminate <DistributionName>(orwsl -t <DistributionName>)
- List all installed distributions and check if they are running or stopped:
wsl --list --verbose(orwsl -l -v) - Change a distribution version between WSL 1 and WSL 2:
wsl --set-version <DistributionName> <Version> - Backup or export a distribution to a tar file for maintenance:
wsl --export <DistributionName> <FileName.tar> - Restore or import a distribution from a tar backup file:
wsl --import <DistributionName> <InstallLocation> <FileName.tar> - Completely remove and delete a distribution and its data:
wsl --unregister <DistributionName>
To install Docker Engine on Ubuntu, the recommended approach is to set up Docker's official repository and install the native packages. This ensures you get the latest stable version and security updates.
sudo apt-get remove docker docker-engine docker.io containerd runc
# Update package index
sudo apt-get update
# Install prerequisites
sudo apt-get install ca-certificates curl gnupg -y
# Add the official GPG key
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository to APT sources
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y