diff --git a/.github/.vale.ini b/.github/.vale.ini new file mode 100644 index 00000000..4c66d7df --- /dev/null +++ b/.github/.vale.ini @@ -0,0 +1,5 @@ +StylesPath = styles +MinAlertLevel = suggestion + +[*.md] +BasedOnStyles = Vale, Custom diff --git a/.github/ISSUE_TEMPLATE/1-Bug_report.md b/.github/ISSUE_TEMPLATE/1-Bug_report.md index a75271b9..1dce3c52 100644 --- a/.github/ISSUE_TEMPLATE/1-Bug_report.md +++ b/.github/ISSUE_TEMPLATE/1-Bug_report.md @@ -1,7 +1,7 @@ --- name: Bug report about: You're having technical issues. 🐞 -labels: 'bug' +labels: "bug" --- diff --git a/.github/ISSUE_TEMPLATE/2-Question.md b/.github/ISSUE_TEMPLATE/2-Question.md index 11eb256e..7a401a3d 100644 --- a/.github/ISSUE_TEMPLATE/2-Question.md +++ b/.github/ISSUE_TEMPLATE/2-Question.md @@ -1,10 +1,9 @@ --- name: Question about: Ask a question.❓ -labels: 'question' +labels: "question" --- ## Summary - diff --git a/.github/ISSUE_TEMPLATE/3-Feature_request.md b/.github/ISSUE_TEMPLATE/3-Feature_request.md index a71ee83e..4147c895 100644 --- a/.github/ISSUE_TEMPLATE/3-Feature_request.md +++ b/.github/ISSUE_TEMPLATE/3-Feature_request.md @@ -1,5 +1,5 @@ --- name: Feature request about: You want something added to the boilerplate. 🎉 -labels: 'enhancement' +labels: "enhancement" --- diff --git a/.github/styles/config/vocabularies/Ansible/accept.txt b/.github/styles/config/vocabularies/Ansible/accept.txt index d5538ab1..d6d00cef 100644 --- a/.github/styles/config/vocabularies/Ansible/accept.txt +++ b/.github/styles/config/vocabularies/Ansible/accept.txt @@ -5,27 +5,27 @@ (?i)SELinux (?i)bootable (?i)bootloader -(?i)Ctrl -(?i)Subnet -(?i)Nameservers +(?i)ctrl +(?i)subnet +(?i)nameservers (?i)ufw -(?i)Ubuntu +(?i)ubuntu (?i)ntp (?i)update_cache (?i)inventory_docs -(?i)Pulumi +(?i)pulumi (?i)sudo(ers?)? (?i)linux -(?i)homebrew -(?i)Kubuntu -(?i)Lubuntu -(?i)VPNs +(?i)homebrew +(?i)kubuntu +(?i)lubuntu +(?i)vpn(s)? (?i)networkd (?i)virtualized (?i)systemd (?i)minimalistic (?i)netplan -(?i)Libvirts? +(?i)libvirts? (?i)v?lans? (?i)v?networks? (?i)ethernets? @@ -34,6 +34,11 @@ (?i)vms? (?i)macoss? (?i)oss? +(?i)hostname +(?i)ips +(?i)ryzen +(?i)nvme +(?i)uninstallation (?i)config (?i)configs (?i)Cirros @@ -44,3 +49,10 @@ (?i)OAuth (?i)APIs (?i)cirros + +// Notes: +// - All entries are case-insensitive using `(?i)` +// - Redundant prefixes/suffixes or improper comment syntax removed + + + diff --git a/.github/styles/config/vocabularies/Ansible/custom.yml b/.github/styles/config/vocabularies/Ansible/custom.yml new file mode 100644 index 00000000..b8a0518f --- /dev/null +++ b/.github/styles/config/vocabularies/Ansible/custom.yml @@ -0,0 +1,6 @@ +extends: spelling +message: "Possible spelling error" +level: suggestion +scope: raw +ignorecase: true +word_list: accept.txt diff --git a/.github/workflows/auto-assign.yml b/.github/workflows/auto-assign.yml index e412020a..2a65ad36 100644 --- a/.github/workflows/auto-assign.yml +++ b/.github/workflows/auto-assign.yml @@ -11,9 +11,9 @@ jobs: issues: write pull-requests: write steps: - - name: 'Auto-assign issue' + - name: "Auto-assign issue" uses: pozil/auto-assign-issue@v2 with: repo-token: ${{ secrets.GITHUB_TOKEN }} - assignees: stephane-segning:7, Marcjazz:3, Hermann-Core:1, USHER-PB:10, onelrian:10, Donemmanuelo:10, Jagoum:10 + assignees: stephane-segning:7, Marcjazz:3, Hermann-Core:1, USHER-PB:10, onelrian:10, Donemmanuelo:10, Jagoum:10 numOfAssignee: 1 diff --git a/.github/workflows/check-md.yaml b/.github/workflows/check-md.yaml index 9d74d2be..10b4e062 100644 --- a/.github/workflows/check-md.yaml +++ b/.github/workflows/check-md.yaml @@ -3,10 +3,10 @@ name: Documentation Review on: push: paths: - - '**/*.md' + - "**/*.md" pull_request: paths: - - '**/*.md' + - "**/*.md" jobs: lint-docs: @@ -14,13 +14,13 @@ jobs: steps: - uses: actions/checkout@v4 -# - name: Check commit message -# uses: ahmadnassri/action-commit-lint@v2 + # - name: Check commit message + # uses: ahmadnassri/action-commit-lint@v2 - name: Vale linting uses: errata-ai/vale-action@v2 with: - files: 'docs/*.md,*.md' + files: "docs/*.md,*.md" - name: markdownlint uses: DavidAnson/markdownlint-cli2-action@v20 @@ -32,5 +32,4 @@ jobs: - name: Check for typos uses: sobolevn/misspell-fixer-action@master with: - options: '-rsvn docs/' - \ No newline at end of file + options: "-rsvn docs/" diff --git a/.github/workflows/doc-deploy.yml b/.github/workflows/doc-deploy.yml index 35f42652..741beae1 100644 --- a/.github/workflows/doc-deploy.yml +++ b/.github/workflows/doc-deploy.yml @@ -21,7 +21,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.x' + python-version: "3.x" # Install dependencies (MkDocs and Material theme) - name: Install dependencies @@ -32,5 +32,5 @@ jobs: - name: Deploy to GitHub Pages run: | git remote set-url origin https://x-access-token:${GH_TOKEN}@github.com/adorsys-gis/openstack.git - - mkdocs gh-deploy --force -m "chore: deploy documentation #{sha}" --dirty \ No newline at end of file + + mkdocs gh-deploy --force -m "chore: deploy documentation #{sha}" --dirty diff --git a/.gitignore b/.gitignore index b4a35353..5946939c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ + ### JetBrains template # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 diff --git a/.markdownlint.json b/.markdownlint.json new file mode 100644 index 00000000..67d2ae55 --- /dev/null +++ b/.markdownlint.json @@ -0,0 +1,3 @@ +{ + "MD013": false +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..5d71af86 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "ansible.python.interpreterPath": "/bin/python3" +} \ No newline at end of file diff --git a/docs/OPENSTACK_SERVICES_UNINSTALL.md b/docs/OPENSTACK_SERVICES_UNINSTALL.md new file mode 100644 index 00000000..58227232 --- /dev/null +++ b/docs/OPENSTACK_SERVICES_UNINSTALL.md @@ -0,0 +1,260 @@ +# OpenStack Services Uninstallation Guide + +This document provides instructions for uninstalling OpenStack services that were implemented using Ansible in this repository. + +## OpenStack Services Implemented + +Based on the repository structure, the following OpenStack components were implemented: + +1. **DevStack Installation** + + - DevStack environment setup + - OpenStack services deployment + - Development environment configuration + +2. **Environment Setup** + - System prerequisites + - Network configuration + - User setup and permissions + +## Manual Uninstallation Instructions + +### 1. Stop OpenStack Services + +```bash +# Stop all OpenStack services +sudo systemctl stop devstack@* +sudo systemctl stop openstack-* +sudo systemctl stop neutron-* +sudo systemctl stop nova-* +sudo systemctl stop glance-* +sudo systemctl stop keystone +sudo systemctl stop mysql +sudo systemctl stop rabbitmq-server + +# Disable services from starting at boot +sudo systemctl disable devstack@* +sudo systemctl disable openstack-* +sudo systemctl disable neutron-* +sudo systemctl disable nova-* +sudo systemctl disable glance-* +sudo systemctl disable keystone +sudo systemctl disable mysql +sudo systemctl disable rabbitmq-server +``` + +### 2. Remove DevStack Installation + +```bash +# Navigate to DevStack directory +cd ~/devstack + +# Run unstack script +./unstack.sh + +# Clean up DevStack +./clean.sh + +# Remove DevStack directory +cd ~ +rm -rf devstack +``` + +### 3. Remove OpenStack Packages + +```bash +# Remove OpenStack packages +sudo apt remove python3-openstackclient openstack-* python3-keystone* \ + python3-nova* python3-glance* python3-neutron* +sudo apt purge python3-openstackclient openstack-* python3-keystone* \ + python3-nova* python3-glance* python3-neutron* + +# Remove database +sudo apt remove mysql-server mysql-client +sudo apt purge mysql-server mysql-client + +# Remove message queue +sudo apt remove rabbitmq-server +sudo apt purge rabbitmq-server + +# Clean up dependencies +sudo apt autoremove +``` + +### 4. Clean Up Network Configuration + +```bash +# Remove OpenStack network namespaces +sudo ip netns list | xargs -I {} sudo ip netns delete {} + +# Remove OpenStack bridges +sudo ovs-vsctl list-br | while read bridge; do + sudo ovs-vsctl del-br "$bridge" +done + +# Remove virtual network interfaces +sudo ip link show | grep -E 'ovs|br-' | awk -F': ' '{print $2}' | \ + while read interface; do + sudo ip link delete "$interface" + done +``` + +### 5. Remove OpenStack User and Groups + +```bash +# Remove OpenStack user +sudo userdel -r stack + +# Remove OpenStack groups +sudo groupdel stack +``` + +## Ansible-based Uninstallation + +Create a file named `openstack_services_uninstall.yml`: + +```yaml +--- +- name: Uninstall OpenStack services + hosts: all + become: true + tasks: + - name: Stop OpenStack services + service: + name: "{{ item }}" + state: stopped + enabled: false + loop: + - devstack@* + - openstack-* + - neutron-* + - nova-* + - glance-* + - keystone + - mysql + - rabbitmq-server + ignore_errors: true + + - name: Run DevStack unstack script + shell: | + cd ~/devstack + ./unstack.sh + ./clean.sh + ignore_errors: true + + - name: Remove DevStack directory + file: + path: ~/devstack + state: absent + + - name: Remove OpenStack packages + apt: + name: + - python3-openstackclient + - openstack-* + - python3-keystone* + - python3-nova* + - python3-glance* + - python3-neutron* + - mysql-server + - mysql-client + - rabbitmq-server + state: absent + autoremove: yes + purge: yes + + - name: Remove OpenStack network namespaces + shell: | + for ns in $(ip netns list); do + ip netns delete $ns + done + ignore_errors: true + + - name: Remove OVS bridges + shell: | + for bridge in $(ovs-vsctl list-br); do + ovs-vsctl del-br "$bridge" + done + ignore_errors: true + + - name: Remove virtual network interfaces + shell: | + for interface in $(ip link show | grep -E 'ovs|br-' | \ + awk -F': ' '{print $2}'); do + ip link delete "$interface" + done + ignore_errors: true + + - name: Remove OpenStack user and groups + user: + name: stack + state: absent + remove: yes + ignore_errors: true +``` + +To run the uninstallation playbook: + +```bash +ansible-playbook -i inventory.ini openstack_services_uninstall.yml +``` + +## Post-Uninstallation Cleanup + +After uninstallation, clean up any remaining configuration files: + +```bash +# Remove OpenStack configuration +sudo rm -rf /etc/openstack +sudo rm -rf /etc/keystone +sudo rm -rf /etc/nova +sudo rm -rf /etc/glance +sudo rm -rf /etc/neutron + +# Remove database files +sudo rm -rf /var/lib/mysql +sudo rm -rf /var/lib/rabbitmq + +# Remove log files +sudo rm -rf /var/log/openstack +sudo rm -rf /var/log/keystone +sudo rm -rf /var/log/nova +sudo rm -rf /var/log/glance +sudo rm -rf /var/log/neutron + +# Remove any remaining bridge configurations +sudo rm -f /etc/netplan/*-openstack.yaml +``` + +## Verification + +After uninstallation, verify that all services have been removed: + +```bash +# Check service status +systemctl status devstack@* +systemctl status openstack-* +systemctl status neutron-* +systemctl status nova-* +systemctl status glance-* +systemctl status keystone +systemctl status mysql +systemctl status rabbitmq-server + +# Check for any remaining OpenStack processes +ps aux | grep -E 'openstack|keystone|nova|glance|neutron' + +# Check network status +ip netns list +ovs-vsctl show +brctl show +``` + +## Note + +- Make sure to backup any important data before uninstalling +- Some commands may require sudo privileges +- The uninstallation process may vary depending on your specific setup and customizations +- If you encounter any errors during uninstallation, check the error messages and ensure all dependencies are properly removed +- After uninstallation, you may need to reboot your system to ensure all services are completely removed +- This guide assumes a standard DevStack installation. If you have a custom installation, you may need to modify some steps diff --git a/docs/Openstack_service.md b/docs/Openstack_service.md new file mode 100644 index 00000000..38e6214b --- /dev/null +++ b/docs/Openstack_service.md @@ -0,0 +1,117 @@ +# OpenStack Services Overview + +OpenStack is not a single cloud infrastructure but a collection of interoperable components (services) that together form a cloud computing platform. Each component provides a distinct function, working together to manage compute, storage, networking, identity, and more. + +## Core OpenStack Services + +### 1. Nova — Compute Service + +Nova is the compute component of OpenStack. It manages the lifecycle of virtual +machine instances, including: + +- Creating, scheduling, and terminating VMs +- Managing VM resources and networking (in collaboration with Neutron) +- Interfacing with hypervisors like KVM, Xen, or VMware + +Nova is essentially the "brain" behind launching and managing virtual servers in OpenStack. + +### 2. Keystone — Identity Service + +Keystone handles authentication and authorization for all OpenStack services. + +Its responsibilities include: + +- Authentication: Verifies user credentials (username/password, tokens, etc.) and + issues tokens. +- Authorization: Defines user roles and access scopes, determining what resources a + user can access. + +All OpenStack services require Keystone tokens for security and access control, making Keystone a central service for identity management. + +### 3. Neutron — Networking Service + +Neutron provides network connectivity and IP address management for OpenStack +services. + +It handles tasks such as: + +- Managing networks, subnets, routers, and floating IPs +- Integrating with Nova to connect virtual instances to networks +- Supporting advanced networking services like firewalls, load balancers, and VPNs + +Neutron ensures that instances can communicate securely and flexibly within the +cloud. + +### 4. Glance — Image Service + +Glance manages virtual machine images. + +It is responsible for: + +- Storing and cataloging VM images, snapshots, and metadata +- Providing APIs to upload, discover, and retrieve VM images +- Collaborating with Nova to deliver VM images when launching instances + +Glance is the repository of OS images and snapshots used to boot virtual machines. + +### 5. Swift — Object Storage Service + +Swift is a scalable, distributed object storage system that: + +- Stores and retrieves unstructured data (objects) such as backups, VM images, and + user files +- Provides high availability and durability through replication + +Swift is ideal for storing large amounts of static data and backups in a cloud-native +way. + +### 6. Cinder — Block Storage Service + +Cinder provides persistent block storage volumes for instances. + +It allows users to: + +- Create, attach, and detach block devices (like virtual hard drives) +- Supports various backend storage technologies (LVM, Ceph, NFS, SAN) +- Maintain data persistence independently of a VM's lifecycle + +Cinder is key for storing databases, logs, and files requiring persistent storage. + +## Additional Important OpenStack Components + +### 7. Horizon — Dashboard + +Horizon is the web-based user interface for OpenStack. It: + +- Provides administrators and users a graphical dashboard +- Allows management of compute, storage, networking, and identity resources +- Simplifies cloud operations without needing CLI access + +### 8. Heat — Orchestration Service + +Heat enables orchestration of cloud applications using templates. It: + +- Automates deployment of infrastructure (VMs, networks, storage) +- Supports complex application stacks and scaling policies +- Uses templates written in YAML or JSON (Heat Orchestration Templates - HOT) + +Heat helps manage complex deployments as code. + +### 9. Ceilometer — Telemetry + +Ceilometer collects usage and performance data for billing, monitoring, and +alerting. It: + +- Gathers metrics on resource consumption (CPU, disk, network) +- Supports integration with billing and monitoring systems + +### 10. Barbican — Key Management + +Barbican provides secure key and secret management for encryption. So it: + +- Stores encryption keys, certificates, and passwords +- Integrates with other OpenStack services for secure data handling + +All these components work together to provide a well-structured, scalable, and secure OpenStack cloud environment. + +Each service plays a distinct role but depends on others to deliver a fully functional Infrastructure-as-a-Service (IaaS) platform. diff --git a/docs/VLAN.md b/docs/VLAN.md index f58a860b..16d056d3 100644 --- a/docs/VLAN.md +++ b/docs/VLAN.md @@ -25,48 +25,48 @@ There are two types of VLANs: ```mermaid flowchart TD subgraph "Physical Network Infrastructure" - SW["Switch"] + SW["Switch"] end - + subgraph "VLAN 10 (Marketing)" PC1["Computer 1\nIP: 192.168.10.2\nVLAN 10"] PC2["Computer 2\nIP: 192.168.10.3\nVLAN 10"] end - + subgraph "VLAN 20 (Engineering)" PC3["Computer 3\nIP: 192.168.20.2\nVLAN 20"] PC4["Computer 4\nIP: 192.168.20.3\nVLAN 20"] end - + subgraph "VLAN 30 (Finance)" PC5["Computer 5\nIP: 192.168.30.2\nVLAN 30"] PC6["Computer 6\nIP: 192.168.30.3\nVLAN 30"] end - + SW --- PC1 SW --- PC2 SW --- PC3 SW --- PC4 SW --- PC5 SW --- PC6 - + RT["Router\n(Inter-VLAN Routing)"] SW --- RT - + PC1 <--> PC2 PC3 <--> PC4 PC5 <--> PC6 - + PC1 <-.-> |"Traffic Isolated\nUnless Routed"| PC3 PC3 <-.-> |"Traffic Isolated\nUnless Routed"| PC5 PC5 <-.-> |"Traffic Isolated\nUnless Routed"| PC1 - + classDef vlan10 fill:#ffcccc,stroke:#ff0000 classDef vlan20 fill:#ccffcc,stroke:#00ff00 classDef vlan30 fill:#ccccff,stroke:#0000ff classDef network fill:#f9f9f9,stroke:#666666 classDef router fill:#ffffcc,stroke:#ffcc00 - + class PC1,PC2 vlan10 class PC3,PC4 vlan20 class PC5,PC6 vlan30 diff --git a/docs/ansible_docs.md b/docs/ansible_docs.md index 940e6e19..1606de31 100644 --- a/docs/ansible_docs.md +++ b/docs/ansible_docs.md @@ -113,9 +113,9 @@ used for infrastructure automation and server management: Each tool has its specific strengths: -| Tools | Language | Best Used For | -|-----------|-------------|---------------------------------------------| -| Chef | Ruby | Complex enterprise environments | -| SaltStack | YAML | Large-scale deployments | -| Pulumi | Various | Cloud infrastructure and resource management | -| Puppet | Puppet DSL | Large-scale environments | +| Tools | Language | Best Used For | +| --------- | ---------- | -------------------------------------------- | +| Chef | Ruby | Complex enterprise environments | +| SaltStack | YAML | Large-scale deployments | +| Pulumi | Various | Cloud infrastructure and resource management | +| Puppet | Puppet DSL | Large-scale environments | diff --git a/docs/netplan_doc.md b/docs/netplan_doc.md index af97a415..135cbbe7 100644 --- a/docs/netplan_doc.md +++ b/docs/netplan_doc.md @@ -115,6 +115,7 @@ Explanation: NetworkManager. - ethernets: This block contains the Ethernet interfaces. In this example, eth0 is the interface being configured. + - dhcp4: Enables DHCP for IPv4, which assigns an IP address automatically. ## Typical Configurations with Netplan @@ -285,11 +286,11 @@ To configure any of these network interfaces manually using Ansible script, do the following: i. We need to install Ansible on our machine to be able to run Ansible scripts. - Run the following command to install Ansible: +Run the following command to install Ansible: ```sh sudo apt update && sudo apt upgrade -y -sudo apt install python3 +sudo apt install python3 sudo python3 venv my_venv | sudo source my_venv/bin/activate | cd my_venv sudo apt install -y build-essential libssl-dev libffi-dev python3-dev python3-pip python3 install ansible --user @@ -307,7 +308,7 @@ ii. Create a playbook.yml file, copy and paste the following: interface_name: "ens33" static_ip: "10.42.0.10/24" gateway4: "10.42.0.1" - nameservers: + nameservers: - "8.8.8.8" - "8.8.4.4" diff --git a/docs/ntp_docs.md b/docs/ntp_docs.md index 7a0af155..8fc31cde 100644 --- a/docs/ntp_docs.md +++ b/docs/ntp_docs.md @@ -19,29 +19,29 @@ servers are essential: - **Token-based authentication**: - In large cloud infrastructures like OpenStack, time synchronization is - critical because authentication tokens are time-sensitive. If a server's - system clock is not synchronized, it may reject valid tokens with errors such - as "not yet valid" or "expired." NTP ensures consistent and accurate time - across all nodes in the infrastructure, helping to prevent such - authentication failures. + In large cloud infrastructures like OpenStack, time synchronization is + critical because authentication tokens are time-sensitive. If a server's + system clock is not synchronized, it may reject valid tokens with errors such + as "not yet valid" or "expired." NTP ensures consistent and accurate time + across all nodes in the infrastructure, helping to prevent such + authentication failures. - **Logs consistency issues**: - In large cloud infrastructures, services often run across multiple servers. - Without proper time synchronization, each server may record log entries using - slightly different timestamps. This makes it difficult to trace errors across - multiple systems. By using NTP, all servers maintain a consistent system - time, ensuring logs are aligned and easier to interpret during debugging or - audits. + In large cloud infrastructures, services often run across multiple servers. + Without proper time synchronization, each server may record log entries using + slightly different timestamps. This makes it difficult to trace errors across + multiple systems. By using NTP, all servers maintain a consistent system + time, ensuring logs are aligned and easier to interpret during debugging or + audits. - **Scheduled jobs**: - Certain tasks or jobs may need to run simultaneously across multiple servers. - If server clocks are not synchronized, these actions may execute at - inconsistent times, leading to failures, data corruption, or unexpected - behavior. NTP ensures that all servers maintain a consistent system time, - enabling coordinated and predictable task execution. + Certain tasks or jobs may need to run simultaneously across multiple servers. + If server clocks are not synchronized, these actions may execute at + inconsistent times, leading to failures, data corruption, or unexpected + behavior. NTP ensures that all servers maintain a consistent system time, + enabling coordinated and predictable task execution. An NTP server is a fundamental component in any cloud or distributed infrastructure. It ensures reliable communication, secure authentication, diff --git a/docs/openstack-ansible-installation-guide.md b/docs/openstack-ansible-installation-guide.md new file mode 100644 index 00000000..771c0658 --- /dev/null +++ b/docs/openstack-ansible-installation-guide.md @@ -0,0 +1,194 @@ +# OpenStack Installation Guide + +## Overview + +This repository contains Ansible playbooks and documentation for installing and configuring OpenStack on a Mini PC. The installation is designed to work with Ubuntu 20.04/22.04 and uses DevStack for deployment. + +## Hardware Specifications + +### Mini PC Configuration + +- **CPU**: AMD Ryzen 7 5825U (8 cores, 16 threads) + - Base Frequency: 2.0 GHz + - Max Boost: 4.5 GHz + - Cache: L1 (512KB), L2 (4MB), L3 (16MB) +- **Memory**: 32GB DDR4 +- **Storage**: 1TB NVMe SSD +- **Network**: 2.5GbE Ethernet +- **Virtualization**: AMD-V enabled + +### Resource Requirements + +- **CPU**: Minimum 8 cores (16 threads) +- **RAM**: Minimum 16GB (32GB recommended) +- **Storage**: + - System: 100GB + - OpenStack: 200GB + - Available for VMs: ~700GB +- **Network**: 1GbE minimum (2.5GbE recommended) + +## System Requirements + +### Operating System + +- Ubuntu 20.04 LTS or Ubuntu 22.04 LTS +- 64-bit architecture +- Fresh installation recommended + +### Software Dependencies + +- Python 3.8 or later +- Ansible 2.9 or later +- Git +- OpenSSH Server +- Network Manager + +### Network Requirements + +- Static IP address +- DNS resolution +- Open ports: + - 22 (SSH) + - 80, 443 (Horizon) + - 5000 (Keystone) + - 8774 (Nova) + - 9696 (Neutron) + - 9292 (Glance) + +## Installation Process + +### 1. System Preparation + +```bash +# Update system +sudo apt update && sudo apt upgrade -y + +# Install required packages +sudo apt install -y python3-pip python3-dev git + +# Install Ansible +sudo pip3 install ansible +``` + +### 2. Clone Repository + +```bash +git clone https://github.com/ADORSYS-GIS/openstack.git +cd openstack && cd openstack-installation +``` + +### 3. Configure Inventory + +Edit `inventory.ini` to match your network configuration: + +```ini +[openstack] +node1 ansible_host=YOUR_IP ansible_user=YOUR_USER ansible_ssh_private_key_file=~/.ssh/id_rsa +``` + +### 4. Run Installation + +```bash +ansible-playbook -i playbooks/install_openstack/inventory.ini playbooks/install_openstack/playbook.yml +``` + +## Post-Installation Configuration + +### 1. Verify Installation + +Run the test playbook: + +```bash +ansible-playbook -i inventory.ini test-openstack.yml +``` + +### 2. Initial Setup + +1. Access Horizon dashboard at `http://YOUR_IP/dashboard` +2. Log in with: + - Username: admin + - Password: devstack + +### 3. Security Hardening + +1. Change default passwords +2. Configure firewall rules +3. Enable SSL/TLS +4. Set up backup procedures + +## Service Verification + +### Core Services + +- Keystone (Identity) +- Nova (Compute) +- Neutron (Networking) +- Glance (Image) +- Horizon (Dashboard) + +### Supporting Services + +- MySQL +- RabbitMQ +- Open vSwitch + +## Troubleshooting + +### Common Issues + +1. Service not starting +2. Network connectivity issues +3. Resource constraints +4. Permission problems + +### Logs Location + +- OpenStack logs: `/opt/stack/logs/` +- System logs: `/var/log/` +- Ansible logs: `./logs/` + +## Maintenance + +### Regular Tasks + +1. System updates +2. Backup procedures +3. Resource monitoring +4. Security patches + +### Monitoring + +- CPU usage +- Memory utilization +- Storage capacity +- Network traffic + +## Documentation Structure + +```sh +docs/ +├── tutorial/ +│ ├── 01-preparation.md +│ ├── 02-installation.md +│ ├── 03-configuration.md +│ ├── 04-verification.md +│ └── 05-troubleshooting.md +├── reference/ +│ ├── hardware.md +│ ├── networking.md +│ └── security.md +└── api/ + └── openstack-api.md +``` + +## Support + +For issues and support: + +1. Check the troubleshooting guide +2. Review the logs +3. Open an issue in the repository + +## License + +This project is licensed under the MIT License - see the LICENSE file for details. diff --git a/docs/tutorials/ansible_tuto.md b/docs/tutorials/ansible_tuto.md index e162d579..6e25dd7b 100644 --- a/docs/tutorials/ansible_tuto.md +++ b/docs/tutorials/ansible_tuto.md @@ -40,29 +40,29 @@ brew install ansible 1. Create SSH keys for authentication: - ```bash - ssh-keygen -t ed25519 -f ~/.ssh/personal_key -C "your_email@domain.com" - ``` + ```bash + ssh-keygen -t ed25519 -f ~/.ssh/personal_key -C "your_email@domain.com" + ``` - This command creates a key that will be used for automatic authentication when logging into your servers. + This command creates a key that will be used for automatic authentication when logging into your servers. 2. Create a new SSH key specifically for Ansible automation tasks: - ```bash - ssh-keygen -t ed25519 -f ~/.ssh/ansible_key -C "ansible@$(hostname)" - ``` + ```bash + ssh-keygen -t ed25519 -f ~/.ssh/ansible_key -C "ansible@$(hostname)" + ``` 3. Copy the SSH keys to your servers: - ```bash - ssh-copy-id -i ~/.ssh/ansible_key.pub lc@188.0.0.1 - ``` + ```bash + ssh-copy-id -i ~/.ssh/ansible_key.pub lc@188.0.0.1 + ``` - ```bash - ssh-copy-id -i ~/.ssh/personal.pub lc@188.0.0.1 - ``` + ```bash + ssh-copy-id -i ~/.ssh/personal.pub lc@188.0.0.1 + ``` - These commands copy your authentication and Ansible SSH keys to the server, simplifying configuration and management. + These commands copy your authentication and Ansible SSH keys to the server, simplifying configuration and management. ### Using Playbooks @@ -73,7 +73,7 @@ Here is an example of a playbook that installs and starts the Apache web server: ```yaml - name: Install and start Apache web server hosts: webservers - become: true # Use sudo + become: true # Use sudo tasks: - name: Install Apache apt: @@ -117,21 +117,21 @@ Ad-hoc commands are used to run single, simple tasks on your servers without the - **Ping All Servers** - ```bash - ansible all -i hosts.ini -m ping - ``` + ```bash + ansible all -i hosts.ini -m ping + ``` - **Reboot Web Servers** - ```bash - ansible web -i hosts.ini -a "reboot" -b - ``` + ```bash + ansible web -i hosts.ini -a "reboot" -b + ``` - **Install VLC on Web Servers** - ```bash - ansible web -i hosts.ini -b -m apt -a "name=vlc state=present" - ``` + ```bash + ansible web -i hosts.ini -b -m apt -a "name=vlc state=present" + ``` Ad-hoc commands are useful for performing quick tasks, such as installing a package or rebooting a server. diff --git a/docs/tutorials/boot_docs.md b/docs/tutorials/boot_docs.md index 6a021a39..63d63e08 100644 --- a/docs/tutorials/boot_docs.md +++ b/docs/tutorials/boot_docs.md @@ -12,15 +12,17 @@ Ubuntu Server is built for server environments, which is a lightweight and minim # Ubuntu Server vs Other Server OS/Distros -| **Aspect** | **Ubuntu Server** | **Debian** | **CentOS / RHEL** | **Windows Server** | -|-----------------|------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------|------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------| -| **Ability** | Full-featured Linux server OS; supports wide range of services and apps | Highly capable, but less user-friendly out of the box | Enterprise-focused capabilities; stable environments | Supports many enterprise tools, Active Directory, .NET, etc. | -| **Capacity** | Easily supports heavy workloads with proper configuration | Handles large workloads, but tuning may require more expertise | Designed for enterprise-scale operations | Capable of high capacity but with more resource overhead | -| **Performance** | Lightweight by default; minimal system load; high efficiency | Very lightweight; excellent performance, especially on older hardware | Moderate; built for stability over raw performance | Heavier footprint; performance affected by GUI and background services | -| **Safety** | Strong package integrity checks; frequent security patches | Conservative approach ensures safety, but slower update cycle | SELinux integration improves isolation and safety | Closed-source; safety reliant on Microsoft’s update cycle | -| **Security** | AppArmor, UFW firewall, automatic security updates available | Manual setup required for many security features | SELinux is powerful but complex; good enterprise controls | Proprietary model limits transparency; patching is slower | -| **Scalability** | Well-suited for cloud environments, containers, and large-scale deployments | Scalable, but lacks vendor-optimized tools for automation | Highly scalable; used in many large enterprise networks | Scales in enterprise settings but with higher resource and license costs | +| **Aspect** | **Ubuntu Server** | **Debian** | **CentOS / RHEL** | **Windows Server** | +| --------------- | --------------------------------------------------------------------------- | --------------------------------------------------------------------- | --------------------------------------------------------- | ------------------------------------------------------------------------ | +| **Ability** | Full-featured Linux server OS; supports wide range of services and apps | Highly capable, but less user-friendly out of the box | Enterprise-focused capabilities; stable environments | Supports many enterprise tools, Active Directory, .NET, etc. | +| **Capacity** | Easily supports heavy workloads with proper configuration | Handles large workloads, but tuning may require more expertise | Designed for enterprise-scale operations | Capable of high capacity but with more resource overhead | +| **Performance** | Lightweight by default; minimal system load; high efficiency | Very lightweight; excellent performance, especially on older hardware | Moderate; built for stability over raw performance | Heavier footprint; performance affected by GUI and background services | +| **Safety** | Strong package integrity checks; frequent security patches | Conservative approach ensures safety, but slower update cycle | SELinux integration improves isolation and safety | Closed-source; safety reliant on Microsoft’s update cycle | +| **Security** | AppArmor, UFW firewall, automatic security updates available | Manual setup required for many security features | SELinux is powerful but complex; good enterprise controls | Proprietary model limits transparency; patching is slower | +| **Scalability** | Well-suited for cloud environments, containers, and large-scale deployments | Scalable, but lacks vendor-optimized tools for automation | Highly scalable; used in many large enterprise networks | Scales in enterprise settings but with higher resource and license costs | + **Prerequisites** + - Minimal 4 GB of RAM - 2 GHz dual-core processor - 25 GB disk space @@ -31,36 +33,36 @@ Ubuntu Server is built for server environments, which is a lightweight and minim How you will make a Ubuntu server bootable key and also how to install Ubuntu server 24.04 on a computer. -## Get started +## Get started 1. **Download the Ubuntu Server ISO Image** The first step is to download the Ubuntu server 24.04 ISO image. So, head over to the official Ubuntu download page (https://ubuntu.com/download/server) and download the ISO file. With the ISO file at hand, prepare the installation media by burning the ISO file into USB. You can use a software utility such as Rufus if you are running Windows or UNetbootin or balenaEtcher for Linux, macOS, and Windows. In this tutor we'll use balenaEtcher, get to the balenaEtcher page (https://etcher-docs.balena.io/) to download balenaEtcher, here are the steps to burn the ISO image: - i. launch balenaEtcher click on the "balenaEtcher" icon to start balenaEtcher. + ![image0](./images/image0.png) ii. locating the image file click on "flash from file" to select your image file. + ![image1](./images/image1.png) iii. choosing the storage device click on "select target" to select your storage device. + ![image2](./images/image2.png) iv. flash the USB drive click on "flash" to make the bootable flash. -![image3](./images/image3.png) - - +![image3](./images/image3.png) 2. **Start Ubuntu Server Installation** @@ -88,7 +90,7 @@ Next, select your preferred layout. The default selection for the layout and var The next step will require you to select your preferred installation type. By default, the “Ubuntu Server” option is selected. In addition to that, you can also choose the “Ubuntu Server (“minimized”) option which is a version customized to have a small footprint in environments that do not require login by users. -In this guide, we will go with the “Ubuntu Server” option. +In this guide, we will go with the “Ubuntu Server” option. So we will hit ENTER. ![text](./images/img5.png) @@ -109,7 +111,7 @@ On the pop-up CLI that appears, select the `Manual` option and hit ENTER. ![text](./images/img8.png) -Be sure to fill in the IP details, i.e. Subnet, IP address, gateway, Nameservers, and Search domains, if any. Then select `Save` and hit ENTER. +Be sure to fill in the IP details, i.e. Subnet, IP address, gateway, Nameservers, and Search domains, if any. Then select `Save` and hit ENTER. ![text](./images/img9.png) @@ -119,7 +121,7 @@ Next, select `Done` and hit ENTER. 7. **Configure Proxy** -If you intend to connect to a Proxy server, here’s the chance to provide your Proxy server address. If you are not running a proxy server, leave it blank and hit `Done`. +If you intend to connect to a Proxy server, here’s the chance to provide your Proxy server address. If you are not running a proxy server, leave it blank and hit `Done`. ![text](./images/img11.png) @@ -157,15 +159,15 @@ Next, you will be required to create a user account. So, provide the required de Ubuntu Pro is an additional service on top of Ubuntu that provides extended support and maintenance including compliance for your OS. It provides 10 years of paid support and you can use up to 5 devices free for personal use. This, however, requires a Ubuntu One account. -For now, we will skip this – You can enable it later. So hit `Continue`. +For now, we will skip this – You can enable it later. So hit `Continue`. ![text](./images/img17.png) -11. **Select Whether to install the OpenSSH server & additional software** +11. **Select Whether to install the OpenSSH server & additional software** Next, select whether you want to install the OpenSSH server which will allow remote login to the server. In our case, we will select to install it. Once selected, select `Done` and hit ENTER. -![text](./images/img18.png) +![text](./images/img18.png) Next, you will be required to select whether to install some featured applications in the form of snaps. So go through the list and enable your preferred snap. Alternatively, you can skip and install them later. @@ -191,13 +193,14 @@ From now you can enjoy your Ubuntu server 24.04 LTS installation. If you are new to Ubuntu server, we'd recommend reading the [server guide](https://documentation.ubuntu.com/server/) ## Security measures - When installing an Ubuntu Server, several security considerations are important to ensure the system's safety. some steps are as follows: - 1. Ensuring that the system is updated regularly to apply the latest security patches and bug fixes. - 2. Using a firewall, such as Uncomplicated Firewall(ufw), to only allow necessary ports is also essential. - 3. securing shared memory by adding specific configurations to /etc/fstab can improve security. - 4. securing SSH service. - 5. Lastly, it is recommended to install security tools like Fail2ban to monitor and block malicious login attempts and to use security-enhancing features like AppArmor to restrict application permissions. +When installing an Ubuntu Server, several security considerations are important to ensure the system's safety. some steps are as follows: + +1. Ensuring that the system is updated regularly to apply the latest security patches and bug fixes. +2. Using a firewall, such as Uncomplicated Firewall(ufw), to only allow necessary ports is also essential. +3. securing shared memory by adding specific configurations to /etc/fstab can improve security. +4. securing SSH service. +5. Lastly, it is recommended to install security tools like Fail2ban to monitor and block malicious login attempts and to use security-enhancing features like AppArmor to restrict application permissions. ## Troubleshooting partition issues @@ -237,7 +240,7 @@ Suppose `sdb` is the disk you want to wipe and repartition. --- -### Using `fdisk` (for MBR/GPT) +### Using `fdisk` (for MBR/GPT) #### 2. Launch `fdisk` @@ -295,5 +298,3 @@ sudo mount /dev/sdb1 /mnt/newdisk ``` To mount it automatically at boot, you'd edit `/etc/fstab`. - - diff --git a/docs/tutorials/configuration.md b/docs/tutorials/configuration.md new file mode 100644 index 00000000..3039377e --- /dev/null +++ b/docs/tutorials/configuration.md @@ -0,0 +1,263 @@ +# OpenStack Configuration Guide + +## Overview + +This guide covers the configuration of OpenStack services after installation. It includes initial setup, security hardening, and service optimization. + +## Initial Configuration + +### 1. Access the Dashboard + +- URL: `http://YOUR_IP/dashboard` + +- Default credentials: + - Username: admin + - Password: devstack + +### 2. Change Default Passwords + +```bash +# Switch to stack user +sudo su - stack + +# Source credentials +source /opt/stack/devstack/openrc + +# Change admin password +openstack user password set --password NEW_PASSWORD admin +``` + +### 3. Configure Project and User + +```bash +# Create new project +openstack project create --description "My Project" myproject + +# Create new user +openstack user create --password NEW_PASSWORD --project myproject myuser + +# Assign role +openstack role add --project myproject --user myuser member +``` + +## Network Configuration + +### 1. Provider Network Setup + +```bash +# Create provider network +openstack network create --provider-network-type flat --provider-physical-network physnet1 --external provider + +# Create subnet +openstack subnet create --network provider --subnet-range 192.168.1.0/24 --gateway 192.168.1.1 --allocation-pool start=192.168.1.100,end=192.168.1.200 provider-subnet +``` + +### 2. Self-Service Network Setup + +```bash +# Create self-service network +openstack network create selfservice + +# Create self-service subnet +openstack subnet create --network selfservice \ + --dns-nameserver 8.8.8.8 --gateway 172.16.1.1 \ + --subnet-range 172.16.1.0/24 selfservice + +# Create router +openstack router create router + +# Add router interface +openstack router add subnet router selfservice + +# Set gateway +openstack router set --external-gateway provider router +``` + +## Compute Configuration + +### 1. Configure Nova + +```bash +# Check compute service +openstack compute service list + +# Configure flavors +openstack flavor create --ram 512 --disk 1 --vcpus 1 m1.tiny +openstack flavor create --ram 2048 --disk 20 --vcpus 2 m1.small +openstack flavor create --ram 4096 --disk 40 --vcpus 4 m1.medium + +# Configure compute node +openstack compute service set --enable nova-compute + +# Verify compute node +openstack compute service list +``` + +### 2. Configure + +```bash +# Download test image +wget http://download.cirros-cloud.net/0.4.0/cirros-0.4.0-x86_64-disk.img + +# Upload image +openstack image create "cirros" \ + --file cirros-0.4.0-x86_64-disk.img \ + --disk-format qcow2 --container-format bare \ + --public +``` + +## Security Configuration + +### 1. Firewall Rules + +```bash +# Configure UFW +sudo ufw default deny incoming +sudo ufw default allow outgoing +sudo ufw allow ssh +sudo ufw allow http +sudo ufw allow https +sudo ufw allow 5000/tcp # Keystone +sudo ufw allow 8774/tcp # Nova +sudo ufw allow 9696/tcp # Neutron +sudo ufw allow 9292/tcp # Glance +sudo ufw enable +``` + +### 2. SSL/TLS Configuration + +```bash +# Install certbot +sudo apt install certbot python3-certbot-apache + +# Obtain certificate +sudo certbot --apache -d your-domain.com +``` + +### 3. Security Groups + +```bash +# Create security group +openstack security group create --description "Basic security group" basic + +# Add rules +openstack security group rule create --protocol icmp basic +openstack security group rule create --protocol tcp --dst-port 22 basic +``` + +## Storage Configuration + +### 1. Configure Cinder + +```bash +# Check volume service +openstack volume service list + +# Create volume type +openstack volume type create --description "SSD" ssd +``` + +### 2. Configure Swift (if enabled) + +```bash +# Create container +openstack container create mycontainer + +# Upload object +openstack object create mycontainer myfile.txt +``` + +## Monitoring Configuration + +### 1. Enable Telemetry + +```bash +# Check telemetry service +openstack metric list + +# Configure alarms +openstack alarm create \ + --name cpu_high \ + --description "CPU usage high" \ + --meter-name cpu_util \ + --threshold 80.0 \ + --comparison-operator gt \ + --statistic avg \ + --period 60 \ + --evaluation-periods 2 \ + --alarm-action "log://" \ + --ok-action "log://" +``` + +### 2. Configure Logging + +```bash +# Configure rsyslog +sudo nano /etc/rsyslog.d/30-openstack.conf + +# Add logging configuration +local0.* /var/log/openstack/openstack.log +local1.* /var/log/openstack/nova.log +local2.* /var/log/openstack/neutron.log +``` + +## Backup Configuration + +### 1. Database Backup + +```bash +# Create backup script +sudo nano /usr/local/bin/backup-openstack.sh + +#!/bin/bash +BACKUP_DIR="/var/backups/openstack" +DATE=$(date +%Y%m%d) +mkdir -p $BACKUP_DIR + +# Backup MySQL +mysqldump -u root -p --all-databases > $BACKUP_DIR/mysql-$DATE.sql + +# Backup configuration +tar -czf $BACKUP_DIR/config-$DATE.tar.gz /etc/openstack/ +``` + +### 2. Automate Backups + +```bash +# Add to crontab +sudo crontab -e + +# Add backup schedule +0 2 * * * /usr/local/bin/backup-openstack.sh +``` + +## Performance Tuning + +### 1. Nova Configuration + +```bash +# Edit nova.conf +sudo nano /etc/nova/nova.conf + +# Add performance settings +[DEFAULT] +cpu_allocation_ratio = 16.0 +ram_allocation_ratio = 1.5 +disk_allocation_ratio = 1.0 +``` + +### 2. Neutron Configuration + +```bash +# Edit neutron.conf +sudo nano /etc/neutron/neutron.conf + +# Add performance settings +[DEFAULT] +max_fixed_ips_per_port = 5 +max_routes = 100 +``` + +## Next Steps + +1. [Verification Guide](verification.md) diff --git a/docs/tutorials/installation.md b/docs/tutorials/installation.md new file mode 100644 index 00000000..4864850b --- /dev/null +++ b/docs/tutorials/installation.md @@ -0,0 +1,39 @@ +# OpenStack Installation Steps + +## Clone Repository + +```bash +git clone https://github.com/ADORSYS-GIS/openstack.git +cd openstack && cd openstack-installation +``` + +## Configure Inventory + +Edit `inventory.ini`: + +```ini +[openstack] +controller ansible_host=10.0.0.10 ansible_user=ubuntu +compute1 ansible_host=10.0.0.11 ansible_user=ubuntu +compute2 ansible_host=10.0.0.12 ansible_user=ubuntu +``` + +## Run Installation + +```bash +ansible-playbook -i inventory.ini main.yml +``` + +## Verify Installation + +```bash +# Check services +openstack service list + +# Check endpoints +openstack endpoint list +``` + +## Next Steps + +1. [Configuration Guide](configuration.md) diff --git a/docs/tutorials/minimal_kvm_setup.md b/docs/tutorials/minimal_kvm_setup.md index 043f5037..efb691ed 100644 --- a/docs/tutorials/minimal_kvm_setup.md +++ b/docs/tutorials/minimal_kvm_setup.md @@ -18,4 +18,4 @@ This guide documents how to use Ansible to install and configure QEMU, KVM, and - Ubuntu 20.04+ servers with SSH access - A control node with Ansible installed -- SSH key-based authentication to target servers \ No newline at end of file +- SSH key-based authentication to target servers diff --git a/docs/tutorials/ntp_setup_tuto.md b/docs/tutorials/ntp_setup_tuto.md index 6144088f..0a69a2c7 100644 --- a/docs/tutorials/ntp_setup_tuto.md +++ b/docs/tutorials/ntp_setup_tuto.md @@ -2,7 +2,7 @@ As discussed in the [NTP documentation](/docs/ntp_docs.md), NTP (Network Time Protocol) is used to synchronize time across all servers in an infrastructure. In this tutorial, we'll learn how to install and configure NTP using an Ansible playbook. -Ansible automates tasks through *playbooks*, which define the desired state of systems. We'll write a playbook to install NTP on all servers. +Ansible automates tasks through _playbooks_, which define the desired state of systems. We'll write a playbook to install NTP on all servers. ## Prerequisites diff --git a/docs/tutorials/prerequisites.md b/docs/tutorials/prerequisites.md new file mode 100644 index 00000000..e7dc0f9e --- /dev/null +++ b/docs/tutorials/prerequisites.md @@ -0,0 +1,31 @@ +# OpenStack Installation Prerequisites + +## Hardware Requirements + +- CPU: 4+ cores +- RAM: 8GB minimum +- Storage: 100GB minimum +- Network: 1Gbps + +## Software Requirements + +- Ubuntu 22.04 LTS +- Python 3.8+ +- Git +- Ansible 2.9+ + +## Network Setup + +- Static IP for controller +- DNS resolution +- Open ports: 80, 443, 5000, 9696, 9292 + +## Storage Planning + +- Root partition: 50GB +- OpenStack data: 50GB +- Swap: 8GB + +## Next Steps + +1. [Installation Guide](installation.md) diff --git a/docs/tutorials/setupvswitch.md b/docs/tutorials/setupvswitch.md index 5c29359a..95d5c376 100644 --- a/docs/tutorials/setupvswitch.md +++ b/docs/tutorials/setupvswitch.md @@ -90,34 +90,34 @@ Now we'll configure the VLAN tags. VLAN uses the 802.1Q standard, adding a 12-bi 1. First, check available interfaces in your VMs: - ```sh - multipass exec "test-vm1" -- ip -o link show | awk -F ': ' '!/lo/ {print $2; exit}' - # Repeat for other VMs. Use your interface name if not ens3 - ``` + ```sh + multipass exec "test-vm1" -- ip -o link show | awk -F ': ' '!/lo/ {print $2; exit}' + # Repeat for other VMs. Use your interface name if not ens3 + ``` 2. Add machines to VLAN0: - ```sh - multipass stop test-vm1 test-vm2 # stop VMs before adding ports - sudo ovs-vsctl set port test-vm2-ens3 tag=0 - sudo ovs-vsctl set port test-vm1-ens3 tag=0 - multipass start test-vm1 test-vm2 - ``` + ```sh + multipass stop test-vm1 test-vm2 # stop VMs before adding ports + sudo ovs-vsctl set port test-vm2-ens3 tag=0 + sudo ovs-vsctl set port test-vm1-ens3 tag=0 + multipass start test-vm1 test-vm2 + ``` 3. Add machines to VLAN1: - ```sh - multipass stop test-vm3 test-vm4 - sudo ovs-vsctl set port test-vm3-ens3 tag=1 - sudo ovs-vsctl set port test-vm4-ens3 tag=1 - multipass start test-vm3 test-vm4 - ``` + ```sh + multipass stop test-vm3 test-vm4 + sudo ovs-vsctl set port test-vm3-ens3 tag=1 + sudo ovs-vsctl set port test-vm4-ens3 tag=1 + multipass start test-vm3 test-vm4 + ``` 4. Verify port settings: - ```sh - sudo ovs-vsctl show | grep -A 2 "Port" - ``` + ```sh + sudo ovs-vsctl show | grep -A 2 "Port" + ``` ### Network Interface Configuration @@ -125,17 +125,17 @@ Now we'll configure static IPs for each VM: 1. For VLAN0 (test-vm1 and test-vm2): - ```sh - multipass exec test-vmX -- sudo ip link set ens3 up - sudo ip addr add 192.168.100.10X dev ens3 - ``` + ```sh + multipass exec test-vmX -- sudo ip link set ens3 up + sudo ip addr add 192.168.100.10X dev ens3 + ``` 2. For VLAN1 (test-vm3 and test-vm4): - ```sh - multipass exec test-vmX -- sudo ip link set ens3 up - sudo ip addr add 192.168.200.10X dev ens3 - ``` + ```sh + multipass exec test-vmX -- sudo ip link set ens3 up + sudo ip addr add 192.168.200.10X dev ens3 + ``` ### Testing Connectivity diff --git a/docs/tutorials/troubleshooting.md b/docs/tutorials/troubleshooting.md new file mode 100644 index 00000000..a3508bb7 --- /dev/null +++ b/docs/tutorials/troubleshooting.md @@ -0,0 +1,175 @@ +# OpenStack Troubleshooting Guide + +## Quick Reference + +### Service Status Commands + +```bash +# List all services +openstack service list + +# List all endpoints +openstack endpoint list + +# Check service status +sudo systemctl status + +# View service logs +sudo tail -f /var/log//.log +``` + +### Common Log Locations + +```bash +/var/log/keystone/ # Identity service +/var/log/nova/ # Compute service +/var/log/neutron/ # Network service +/var/log/glance/ # Image service +/var/log/cinder/ # Block storage +``` + +## Common Issues & Solutions + +### 1. Service Endpoint Issues + +#### Missing Service Endpoints + +```bash +# Register missing service +openstack service create --name --description "" + +# Create missing endpoint +openstack endpoint create --region RegionOne public http://: +``` + +#### Service Not Responding + +```bash +# Restart service +sudo systemctl restart + +# Verify service status +sudo systemctl status +``` + +### 2. Authentication Issues + +#### Token Validation Fails + +```bash +# Source credentials +source /opt/stack/devstack/openrc + +# Verify token +openstack token issue +``` + +#### Connection Refused + +```bash +# Check service status +sudo systemctl status + +# Verify firewall +sudo ufw status + +# Check port +sudo netstat -tulpn | grep +``` + +### 3. Resource Issues + +#### High CPU/Memory Usage + +```bash +# Check resource usage +top -b -n 1 +free -h +df -h + +# Check service resource usage +ps aux | grep +``` + +#### Storage Issues + +```bash +# Check storage +df -h /var/lib/ + +# Verify volumes +openstack volume list +``` + +### 4. Network Issues + +#### Instance Network Problems + +```bash +# Check network configuration +openstack network show +openstack subnet show +openstack router show + +# Verify security groups +openstack security group list +``` + +#### DNS Resolution Issues + +```bash +# Check DNS +cat /etc/resolv.conf +nslookup google.com +``` + +## Test Playbook Failures + +### 1. Missing Service Endpoints + +```bash +# Error: public endpoint for service in RegionOne region not found + +# Solution: +openstack service create --name --description "" +openstack endpoint create --region RegionOne public http://: +``` + +### 2. Service Not Available + +```bash +# Error: service not available + +# Solution: +sudo systemctl restart +sudo systemctl status +``` + +## Recovery Procedures + +### 1. Service Recovery + +```bash +# Restart all services +sudo systemctl restart keystone nova-compute neutron-server glance-api + +# Verify recovery +openstack service list +openstack endpoint list +``` + +### 2. Data Recovery + +```bash +# Database recovery +mysql -u root -p < /var/backups/openstack/mysql-$(date +%Y%m%d).sql + +# Configuration recovery +sudo tar -xzf /var/backups/openstack/config-$(date +%Y%m%d).tar.gz -C / +``` + +## Next Steps + +1. [Verification Guide](04-verification.md) +2. [Maintenance Guide](../reference/maintenance.md) +3. [Security Guide](../reference/security.md) diff --git a/docs/tutorials/verification.md b/docs/tutorials/verification.md new file mode 100644 index 00000000..eef122a1 --- /dev/null +++ b/docs/tutorials/verification.md @@ -0,0 +1,44 @@ +# OpenStack Verification Guide + +## Service Verification + +```bash +# Check all services +openstack service list + +# Check endpoints +openstack endpoint list + +# Check compute services +openstack compute service list +``` + +## Network Verification + +```bash +# Check networks +openstack network list + +# Check routers +openstack router list + +# Check security groups +openstack security group list +``` + +## Instance Verification + +```bash +# Create test instance +openstack server create --image cirros --flavor m1.tiny --network provider test-instance + +# Check instance status +openstack server list + +# Test connectivity +openstack server ssh test-instance +``` + +## Next Steps + +1. [Troubleshooting Guide](troubleshooting.md) diff --git a/mkdocs.yml b/mkdocs.yml index a57f23cc..a4e74a29 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,7 +1,7 @@ # Project information site_name: Adorsys OpenStack -site_description: 'OpenStack project backed by adorsys' -site_url: 'https://openstack.github.io/adorsys-gis' +site_description: "OpenStack project backed by adorsys" +site_url: "https://openstack.github.io/adorsys-gis" # Theme settings theme: diff --git a/playbooks/install_openstack/ansible.cfg b/playbooks/install_openstack/ansible.cfg new file mode 100644 index 00000000..408a625f --- /dev/null +++ b/playbooks/install_openstack/ansible.cfg @@ -0,0 +1,24 @@ +[defaults] +inventory = inventory.ini +remote_tmp = /tmp +local_tmp = /tmp +host_key_checking = False +retry_files_enabled = False +roles_path = roles +log_path = logs/ansible.log +stdout_callback = yaml +bin_ansible_callbacks = True +callback_whitelist = profile_tasks +timeout = 30 +forks = 10 + +[ssh_connection] +pipelining = True +control_path = /tmp/ansible-ssh-%%h-%%p-%%r +ssh_args = -o ControlMaster=auto -o ControlPersist=60s + +[privilege_escalation] +become = True +become_method = sudo +become_user = root +become_ask_pass = False diff --git a/playbooks/install_openstack/group_vars/all.yml b/playbooks/install_openstack/group_vars/all.yml new file mode 100644 index 00000000..90e0fb70 --- /dev/null +++ b/playbooks/install_openstack/group_vars/all.yml @@ -0,0 +1,63 @@ +--- +# OpenStack host configuration +openstack_host_ip: "{{ ansible_host | default(inventory_hostname) }}" + +# Host IP for DevStack (used as HOST_IP) +host_ip: "{{ ansible_default_ipv4.address }}" + +# Local IP used for Neutron tunneling (VXLAN endpoint) +local_ip: "{{ ansible_default_ipv4.address }}" + +admin_password: "devstack" +database_password: "devstack" +rabbit_password: "devstack" +service_password: "devstack" + +# Network configuration +fixed_range: "10.0.0.0/24" +floating_range: "172.24.4.0/24" +public_network_gateway: "172.24.4.225" +public_network_allocation_pool_start: "172.24.4.2" +public_network_allocation_pool_end: "172.24.4.254" +allocation_pools: "start={{ public_network_allocation_pool_start }},end={{ public_network_allocation_pool_end }}" +public_interface: "{{ neutron_public_interface }}" + +# User configuration +stack_user: "stack" + +# DevStack configuration +devstack_branch: "master" +devstack_repo: "https://github.com/openstack/devstack.git" + +# System configuration +system_timezone: "UTC" +timezone: "{{ system_timezone }}" +log_dir: "/opt/stack/logs" + +# Node roles +is_controller: "{{ inventory_hostname == 'node1' }}" +is_compute: "{{ inventory_hostname in ['node2', 'node3'] }}" + +# Logging configuration +enable_logging: true + +# Storage configuration +cinder_volume_size: "20G" +swift_hash_suffix: "devstack-suffix" +swift_replicas: 1 + +# Network configuration +neutron_use_security_groups: true +neutron_public_interface: "{{ ansible_default_ipv4.interface }}" +neutron_private_interface: >- + {{ ansible_interfaces | difference(['lo', ansible_default_ipv4.interface]) | first | default(ansible_default_ipv4.interface) }} +neutron_network_type: "flat" +neutron_physical_network: "public" + +# OVN configuration +ovn_enable_tls: true +ovn_sb_port: 6642 +ovn_nb_port: 6641 +ovn_metadata_port: 9697 +ovn_enable_chassis_as_gw: true +ovn_enable_tls_routing: true diff --git a/playbooks/install_openstack/group_vars/all/main.yml b/playbooks/install_openstack/group_vars/all/main.yml new file mode 100644 index 00000000..7847beef --- /dev/null +++ b/playbooks/install_openstack/group_vars/all/main.yml @@ -0,0 +1,36 @@ +--- +# OpenStack host configuration +openstack_host_ip: "{{ ansible_host | default(inventory_hostname) }}" +admin_password: "devstack" + +# Network configuration +fixed_range: "10.0.0.0/24" +floating_range: "172.24.4.0/24" +public_network_gateway: "172.24.4.225" + +# User configuration +stack_user: "stack" + +# DevStack configuration +devstack_branch: "master" +devstack_repo: "https://github.com/openstack/devstack.git" + +# System configuration +system_timezone: "UTC" + +# Node roles +is_controller: "{{ inventory_hostname == 'node1' }}" +is_compute: "{{ inventory_hostname in ['node2', 'node3'] }}" + +# Logging configuration +enable_logging: true + +# Storage configuration +cinder_volume_size: "20G" +swift_hash_suffix: "66a3d6b56c1f479c8b4e70ab5c2000f5" +swift_replicas: 1 + +# Network configuration +neutron_use_security_groups: true +neutron_public_interface: "eth0" +neutron_private_interface: "eth1" diff --git a/playbooks/install_openstack/inventory.ini b/playbooks/install_openstack/inventory.ini new file mode 100644 index 00000000..572c9223 --- /dev/null +++ b/playbooks/install_openstack/inventory.ini @@ -0,0 +1,11 @@ +[openstack] +#node1 ansible_host=10.203.98.58 ansible_user=ubuntu ansible_ssh_private_key_file=~/.ssh/id_ed25519 +Demo ansible_host=10.35.64.106 ansible_user=ubuntu ansible_ssh_private_key_file=~/.ssh/id_ed25519 +#node3 ansible_host=10.203.98.93 ansible_user=ubuntu ansible_ssh_private_key_file=~/.ssh/id_ed25519 + +# For local testing +# localhost ansible_connection=local + +[openstack:vars] +# Common variables for all OpenStack nodes +ansible_python_interpreter=/usr/bin/python3 diff --git a/playbooks/install_openstack/playbook.yml b/playbooks/install_openstack/playbook.yml new file mode 100644 index 00000000..e005b75b --- /dev/null +++ b/playbooks/install_openstack/playbook.yml @@ -0,0 +1,12 @@ +--- +- name: Install OpenStack via DevStack + hosts: all + become: yes + + roles: + - prerequisites + - create-user + - setup-env + - clone-devstack + - run-devstack + - post-install diff --git a/playbooks/install_openstack/requirements.yml b/playbooks/install_openstack/requirements.yml new file mode 100644 index 00000000..1b41aebc --- /dev/null +++ b/playbooks/install_openstack/requirements.yml @@ -0,0 +1,8 @@ +--- +# This file lists all role dependencies for the project +# Currently, all roles are local to the project +# Add external role dependencies here if needed in the future +# Example: +# - src: https://github.com/example/ansible-role-example +# version: master +# name: example-role diff --git a/playbooks/install_openstack/roles/clone-devstack/handlers/main.yml b/playbooks/install_openstack/roles/clone-devstack/handlers/main.yml new file mode 100644 index 00000000..52df5399 --- /dev/null +++ b/playbooks/install_openstack/roles/clone-devstack/handlers/main.yml @@ -0,0 +1,4 @@ +--- +- name: log_git_clone + debug: + msg: "Git clone result: {{ git_clone_result }}" diff --git a/playbooks/install_openstack/roles/clone-devstack/tasks/main.yml b/playbooks/install_openstack/roles/clone-devstack/tasks/main.yml new file mode 100644 index 00000000..b786af4a --- /dev/null +++ b/playbooks/install_openstack/roles/clone-devstack/tasks/main.yml @@ -0,0 +1,29 @@ +- name: Ensure /opt/stack directory exists + file: + path: /opt/stack + state: directory + owner: "{{ stack_user }}" + group: "{{ stack_user }}" + mode: "0755" + become: yes + +- name: Clone DevStack repository + git: + repo: "{{ devstack_repo }}" + dest: /opt/stack/devstack + version: "{{ devstack_branch }}" + force: yes + become: yes + become_user: "{{ stack_user }}" + register: git_clone_result + notify: log_git_clone + +- name: Set proper permissions on DevStack directory + file: + path: /opt/stack/devstack + state: directory + owner: "{{ stack_user }}" + group: "{{ stack_user }}" + mode: "0755" + recurse: yes + become: yes diff --git a/playbooks/install_openstack/roles/create-user/handlers/main.yml b/playbooks/install_openstack/roles/create-user/handlers/main.yml new file mode 100644 index 00000000..2c53659b --- /dev/null +++ b/playbooks/install_openstack/roles/create-user/handlers/main.yml @@ -0,0 +1,20 @@ +--- +# Handlers for create-user role + +- name: reload bashrc + shell: | + . /opt/stack/.bashrc + become: yes + become_user: "{{ stack_user }}" + +- name: reload bash_profile + shell: | + . /opt/stack/.bash_profile + become: yes + become_user: "{{ stack_user }}" + +- name: reload profile + shell: | + . /opt/stack/.profile + become: yes + become_user: "{{ stack_user }}" diff --git a/playbooks/install_openstack/roles/create-user/tasks/main.yml b/playbooks/install_openstack/roles/create-user/tasks/main.yml new file mode 100644 index 00000000..5867d389 --- /dev/null +++ b/playbooks/install_openstack/roles/create-user/tasks/main.yml @@ -0,0 +1,141 @@ +--- +# Create stack user with passwordless sudo + +- name: Check if stack user exists + command: id -u {{ stack_user }} + register: user_check + ignore_errors: yes + changed_when: false + +- name: Stop any processes running as stack user + shell: pkill -u {{ stack_user }} || true + become: yes + when: user_check.rc == 0 + +- name: Wait for processes to stop + wait_for: + timeout: 5 + when: user_check.rc == 0 + +- name: Check if /opt/stack exists + stat: + path: /opt/stack + register: opt_stack_dir + +- name: Remove existing /opt/stack if it exists + file: + path: /opt/stack + state: absent + become: yes + when: opt_stack_dir.stat.exists + +- name: Create or modify stack user + user: + name: "{{ stack_user }}" + home: /opt/stack + shell: /bin/bash + create_home: yes + move_home: yes + state: present + become: yes + +- name: Ensure /opt/stack directory exists + file: + path: /opt/stack + state: directory + owner: "{{ stack_user }}" + group: "{{ stack_user }}" + mode: "0755" + become: yes + +- name: Set up sudoers for stack user + copy: + dest: /etc/sudoers.d/stack + content: "{{ stack_user }} ALL=(ALL) NOPASSWD: ALL" + mode: "0440" + become: yes + +- name: Ensure .ssh directory exists + file: + path: /opt/stack/.ssh + state: directory + owner: "{{ stack_user }}" + group: "{{ stack_user }}" + mode: "0700" + become: yes + +- name: Generate SSH key for stack user + shell: | + if [ ! -f /opt/stack/.ssh/id_rsa ]; then + ssh-keygen -t rsa -N "" -f /opt/stack/.ssh/id_rsa + fi + become: yes + become_user: "{{ stack_user }}" + +- name: Get SSH public key content + slurp: + src: /opt/stack/.ssh/id_rsa.pub + register: ssh_pub_key + become: yes + become_user: "{{ stack_user }}" + +- name: Set up authorized_keys for stack user + copy: + dest: /opt/stack/.ssh/authorized_keys + content: "{{ ssh_pub_key['content'] | b64decode }}" + mode: "0600" + owner: "{{ stack_user }}" + group: "{{ stack_user }}" + become: yes + +- name: Ensure stack user has correct shell environment in .bashrc + copy: + dest: /opt/stack/.bashrc + content: | + # .bashrc + export PATH=$PATH:/usr/local/bin + export PYTHONPATH=/opt/stack + export DEVSTACK_DIR=/opt/stack/devstack + export OS_AUTH_URL=http://{{ openstack_host_ip }}/identity + export OS_IDENTITY_API_VERSION=3 + export OS_IMAGE_API_VERSION=2 + export OS_PROJECT_DOMAIN_ID=default + export OS_PROJECT_NAME=admin + export OS_TENANT_NAME=admin + export OS_USERNAME=admin + export OS_USER_DOMAIN_ID=default + export OS_REGION_NAME=RegionOne + export OS_PASSWORD={{ admin_password }} + mode: "0644" + owner: "{{ stack_user }}" + group: "{{ stack_user }}" + become: yes + notify: reload bashrc + +- name: Ensure stack user has correct shell environment in .bash_profile + copy: + dest: /opt/stack/.bash_profile + content: | + # .bash_profile + if [ -f /opt/stack/.bashrc ]; then + . /opt/stack/.bashrc + fi + mode: "0644" + owner: "{{ stack_user }}" + group: "{{ stack_user }}" + become: yes + notify: reload bash_profile + +- name: Ensure stack user has correct shell environment in .profile + copy: + dest: /opt/stack/.profile + content: | + # .profile + if [ -f /opt/stack/.bashrc ]; then + . /opt/stack/.bashrc + fi + mode: "0644" + owner: "{{ stack_user }}" + group: "{{ stack_user }}" + become: yes + notify: reload profile diff --git a/playbooks/install_openstack/roles/post-install/handlers/main.yml b/playbooks/install_openstack/roles/post-install/handlers/main.yml new file mode 100644 index 00000000..949ca93c --- /dev/null +++ b/playbooks/install_openstack/roles/post-install/handlers/main.yml @@ -0,0 +1,4 @@ +--- +- name: log_service_status + debug: + msg: "Service status: {{ service_status }}" diff --git a/playbooks/install_openstack/roles/post-install/tasks/main.yml b/playbooks/install_openstack/roles/post-install/tasks/main.yml new file mode 100644 index 00000000..e6a0d259 --- /dev/null +++ b/playbooks/install_openstack/roles/post-install/tasks/main.yml @@ -0,0 +1,33 @@ +--- +- name: Output Horizon dashboard URL and admin credentials + debug: + msg: "Horizon dashboard URL: http://{{ openstack_host_ip }}/dashboard, Admin credentials: admin/{{ admin_password }}" + +- name: Check if UFW is installed + command: which ufw + register: ufw_check + ignore_errors: yes + changed_when: false + +- name: Optionally open firewall ports + ufw: + rule: allow + port: "{{ item }}" + proto: tcp + loop: + - 80 + - 443 + when: ufw_check.rc == 0 and enable_logging | default(false) + +- name: Validate OpenStack services + command: > + systemctl status {{ item }} + loop: + - apache2 + - mysql + - rabbitmq-server + - openvswitch-switch + register: service_status + failed_when: service_status.rc != 0 + changed_when: service_status.changed + notify: log_service_status diff --git a/playbooks/install_openstack/roles/prerequisites/handlers/main.yml b/playbooks/install_openstack/roles/prerequisites/handlers/main.yml new file mode 100644 index 00000000..17f6102c --- /dev/null +++ b/playbooks/install_openstack/roles/prerequisites/handlers/main.yml @@ -0,0 +1,8 @@ +--- +# Handlers for prerequisites role + +- name: restart ntp + systemd: + name: ntp + state: restarted + become: yes diff --git a/playbooks/install_openstack/roles/prerequisites/tasks/main.yml b/playbooks/install_openstack/roles/prerequisites/tasks/main.yml new file mode 100644 index 00000000..8c213cc3 --- /dev/null +++ b/playbooks/install_openstack/roles/prerequisites/tasks/main.yml @@ -0,0 +1,155 @@ +--- +# Install system prerequisites for OpenStack + +- name: Check for KVM support + block: + - name: Verify KVM support + command: egrep -q '(vmx|svm)' /proc/cpuinfo + register: kvm_check + failed_when: false + changed_when: false + - name: Fail if KVM not supported + fail: + msg: "KVM virtualization is not supported on this system" + when: kvm_check.rc != 0 + +- name: Verify network interfaces + block: + - name: Check network interfaces + shell: | + for iface in ens3; do + ip link show $iface >/dev/null 2>&1 + done + register: network_check + failed_when: false + changed_when: false + - name: Fail if interfaces missing + fail: + msg: "Required network interfaces are not available" + when: network_check.rc != 0 + +- name: Update apt cache + apt: + update_cache: yes + cache_valid_time: 3600 + become: yes + +- name: Enable universe repository + apt_repository: + repo: "deb http://archive.ubuntu.com/ubuntu {{ ansible_distribution_release }} universe" + state: present + become: yes + +- name: Install required packages + apt: + name: + - git + - python3-pip + - python3-dev + - python3-venv + - python3-setuptools + - python3-wheel + - libffi-dev + - libssl-dev + - libxml2-dev + - libxslt1-dev + - libjpeg8-dev + - zlib1g-dev + - libmysqlclient-dev + - libpq-dev + - libsqlite3-dev + - libvirt-dev + - libvirt-daemon-system + - qemu-kvm + - qemu-utils + - libguestfs-tools + - openvswitch-switch + - openvswitch-common + - bridge-utils + - ntp + - ntpdate + state: present + become: yes + register: package_install + retries: 3 + delay: 5 + until: package_install is success + +- name: Get Python version + command: python3 --version + register: python_version + changed_when: false + +- name: Create Python virtual environment + command: "python3 -m venv /opt/stack/venv" + args: + creates: /opt/stack/venv + become: yes + +- name: Install Python packages in virtual environment + pip: + name: + - virtualenv + - setuptools + - wheel + executable: /opt/stack/venv/bin/pip + state: present + become: yes + +- name: Configure NTP + template: + src: ntp.conf.j2 + dest: /etc/ntp.conf + owner: root + group: root + mode: "0644" + become: yes + notify: restart ntp + +- name: Enable and start NTP service + systemd: + name: ntp + state: started + enabled: yes + become: yes + +- name: Configure timezone + timezone: + name: "{{ system_timezone }}" + become: yes + +- name: Enable and start libvirt service + systemd: + name: libvirtd + state: started + enabled: yes + become: yes + +- name: Load Open vSwitch kernel module + modprobe: + name: openvswitch + state: present + become: yes + +- name: Enable and start Open vSwitch services + systemd: + name: "{{ item }}" + state: started + enabled: yes + loop: + - openvswitch-switch + become: yes + +- name: Add stack user to libvirt group + user: + name: "{{ stack_user }}" + groups: libvirt + append: yes + become: yes + +- name: Ensure DNS resolver is set (Multipass/VM safe) + become: yes + copy: + dest: /etc/resolv.conf + content: | + nameserver 8.8.8.8 diff --git a/playbooks/install_openstack/roles/prerequisites/templates/ntp.conf.j2 b/playbooks/install_openstack/roles/prerequisites/templates/ntp.conf.j2 new file mode 100644 index 00000000..2ce9bf0a --- /dev/null +++ b/playbooks/install_openstack/roles/prerequisites/templates/ntp.conf.j2 @@ -0,0 +1,59 @@ +# /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help + +driftfile /var/lib/ntp/ntp.drift + +# Leap seconds definition provided by tzdata +leapfile /usr/share/zoneinfo/leap-seconds.list + +# Enable this if you want statistics to be logged. +#statsdir /var/log/ntpstats/ + +statistics loopstats peerstats clockstats +filegen loopstats file loopstats type day enable +filegen peerstats file peerstats type day enable +filegen clockstats file clockstats type day enable + +# Specify one or more NTP servers. + +# Use servers from the NTP Pool Project. Approved by Ubuntu Technical Board +# on 2011-02-08 (LP: #104525). See http://www.pool.ntp.org/join.html for +# more information. +pool 0.ubuntu.pool.ntp.org iburst +pool 1.ubuntu.pool.ntp.org iburst +pool 2.ubuntu.pool.ntp.org iburst +pool 3.ubuntu.pool.ntp.org iburst + +# Use Ubuntu's ntp server as a fallback. +pool ntp.ubuntu.com + +# Access control configuration; see /usr/share/doc/ntp-doc/html/accopt.html for +# details. The web page +# might also be helpful. +# +# Note that "restrict" applies to both servers and clients, so a configuration +# that might be intended to block requests from certain clients could also end +# up blocking replies from your own upstream servers. + +# By default, exchange time with everybody, but don't allow configuration. +restrict -4 default kod notrap nomodify nopeer noquery limited +restrict -6 default kod notrap nomodify nopeer noquery limited + +# Local users may interrogate the ntp server more closely. +restrict 127.0.0.1 +restrict ::1 + +# Needed for adding pool entries +restrict source notrap nomodify noquery + +# Clients from this (example!) subnet have unlimited access, but only if +# cryptographically authenticated. +#restrict 192.168.123.0 mask 255.255.255.0 notrust + +# If you want to provide time to your local subnet, change the next line. +# (Again, the address is an example only.) +#broadcast 192.168.123.255 + +# If you want to listen to time broadcasts on your local subnet, de-comment the +# next lines. Please do this only if you trust everybody on the network! +#disable auth +#broadcastclient \ No newline at end of file diff --git a/playbooks/install_openstack/roles/run-devstack/handlers/main.yml b/playbooks/install_openstack/roles/run-devstack/handlers/main.yml new file mode 100644 index 00000000..28a69d8c --- /dev/null +++ b/playbooks/install_openstack/roles/run-devstack/handlers/main.yml @@ -0,0 +1,8 @@ +--- +- name: log_stack_result + debug: + msg: "DevStack installer result: {{ stack_result }}" + +- name: log_service_check + debug: + msg: "OpenStack services status: {{ service_check.stdout_lines }}" diff --git a/playbooks/install_openstack/roles/run-devstack/tasks/main.yml b/playbooks/install_openstack/roles/run-devstack/tasks/main.yml new file mode 100644 index 00000000..748b5773 --- /dev/null +++ b/playbooks/install_openstack/roles/run-devstack/tasks/main.yml @@ -0,0 +1,127 @@ +--- +- name: Clean up previous installation + shell: | + cd /opt/stack/devstack + ./unstack.sh || true + ./clean.sh || true + become: yes + become_user: "{{ stack_user }}" + ignore_errors: yes + +- name: Ensure /opt/stack/devstack ownership and permissions + file: + path: /opt/stack/devstack + state: directory + owner: "{{ stack_user }}" + group: "{{ stack_user }}" + mode: "0755" + become: true + +- name: Get Python version + command: python3 --version + register: python_version + changed_when: false + +- name: Set derived facts for floating IP + set_fact: + floating_base: "{{ floating_range.split('/')[0] }}" + floating_end: "{{ floating_range.split('/')[0].rsplit('.', 1)[0] }}.254" + floating_subnet: "{{ floating_range.split('/')[0] }}/24" + python3_short_version: "{{ python_version.stdout.split()[1].split('.')[0] }}.{{ python_version.stdout.split()[1].split('.')[1] }}" + +- name: Copy local.conf template + template: + src: local.conf.j2 + dest: /opt/stack/devstack/local.conf + owner: "{{ stack_user }}" + group: "{{ stack_user }}" + mode: "0644" + +- name: Create logs directory + file: + path: /opt/stack/logs + state: directory + owner: "{{ stack_user }}" + group: "{{ stack_user }}" + mode: "0755" + become: true + +- name: Create pip config directory + file: + path: "/home/{{ stack_user }}/.pip" + state: directory + owner: "{{ stack_user }}" + group: "{{ stack_user }}" + mode: "0755" + become: true + +- name: Set pip timeout and retry settings + copy: + dest: "/home/{{ stack_user }}/.pip/pip.conf" + content: | + [global] + timeout = 60 + retries = 3 + owner: "{{ stack_user }}" + group: "{{ stack_user }}" + mode: "0644" + become: true + +- name: Start Open vSwitch using service + service: + name: openvswitch-switch + state: started + enabled: yes + become: yes + +- name: Wait until Open vSwitch DB socket is available + stat: + path: /var/run/openvswitch/db.sock + register: ovs_socket + retries: 10 + delay: 3 + until: ovs_socket.stat.exists + become: yes + +- name: Fail if Open vSwitch DB socket is still missing after retries + fail: + msg: "Open vSwitch DB socket not found. openvswitch-switch may not have started correctly." + when: not ovs_socket.stat.exists + +- name: Try fetching Kubernetes stable version + uri: + url: https://dl.k8s.io/release/stable.txt + return_content: yes + validate_certs: yes + register: kubectl_version + ignore_errors: yes + +- name: Set fallback kubectl version + set_fact: + MAGNUM_KUBECTL_TAG: "{{ kubectl_version.content | default('v1.30.1') }}" + +- name: Run DevStack installation with logging + shell: | + cd /opt/stack/devstack + export PIP_DEFAULT_TIMEOUT=60 + export PIP_RETRIES=3 + ./stack.sh 2>&1 | tee /opt/stack/logs/stack_install.log + become: yes + become_user: "{{ stack_user }}" + args: + creates: /opt/stack/devstack/.stack + register: stack_output + +- name: Display DevStack installation output + debug: + var: stack_output.stdout_lines + when: stack_output.stdout_lines is defined + +- name: Create Swift data directory + file: + path: /opt/stack/data/swift + state: directory + owner: "{{ stack_user }}" + group: "{{ stack_user }}" + mode: "0755" + become: true diff --git a/playbooks/install_openstack/roles/run-devstack/templates/local.conf.j2 b/playbooks/install_openstack/roles/run-devstack/templates/local.conf.j2 new file mode 100644 index 00000000..151a21b8 --- /dev/null +++ b/playbooks/install_openstack/roles/run-devstack/templates/local.conf.j2 @@ -0,0 +1,168 @@ +[[local|localrc]] + +# =================================== +# Credentials +# =================================== +ADMIN_PASSWORD={{ admin_password }} +DATABASE_PASSWORD={{ database_password }} +RABBIT_PASSWORD={{ rabbit_password }} +SERVICE_PASSWORD={{ service_password }} +SWIFT_HASH={{ swift_hash_suffix | default('devstack-suffix') }} +# =================================== +# System Configuration +# =================================== +export TERM=xterm +RECLONE=yes +OFFLINE=false +USE_PYTHON3=true +TIMEZONE={{ system_timezone | default('UTC') }} +HOST_IP={{ host_ip }} + +# =================================== +# Logging Configuration +# =================================== +ENABLE_LOGGING=True +ENABLE_DEBUG_LOG_LEVEL=True +ENABLE_VERBOSE_LOGGING=True +VERBOSE=True +DEBUG=True +LOG_COLOR=True +LOGFILE={{ log_dir }}/stack.sh.log +LOGDIR={{ log_dir }} +SCREEN_LOGDIR={{ log_dir }}/screen +USE_SCREEN=True + +# =================================== +# Network Configuration +# =================================== +FIXED_RANGE={{ fixed_range | default("10.0.0.0/24") }} +FLOATING_RANGE={{ floating_range | default("172.24.4.0/24") }} +PUBLIC_NETWORK_GATEWAY={{ public_network_gateway | default("172.24.4.1") }} +PUBLIC_NETWORK_ALLOCATION_POOL_START={{ public_network_allocation_pool_start | default("172.24.4.10") }} +PUBLIC_NETWORK_ALLOCATION_POOL_END={{ public_network_allocation_pool_end | default("172.24.4.254") }} + +PUBLIC_INTERFACE={{ public_interface | default(neutron_public_interface) }} +NEUTRON_PUBLIC_INTERFACE={{ neutron_public_interface }} +NEUTRON_PRIVATE_INTERFACE={{ neutron_private_interface }} +Q_TUNNEL_INTERFACE={{ neutron_private_interface }} +Q_TUNNEL_LOCAL_IP={{ local_ip }} + +# =================================== +# Core Services +# =================================== +enable_service mysql +enable_service rabbit +enable_service etcd3 +enable_service key +enable_service g-api +enable_service g-reg # optional +enable_service n-api +enable_service n-cpu +enable_service n-cond +enable_service n-sch +enable_service n-novnc +enable_service n-xvnc # optional +enable_service c-api +enable_service c-vol +enable_service placement-api +enable_service placement-client +enable_service horizon +enable_service apache2 +enable_service keystone +enable_service glance + +# =================================== +# Storage Configuration +# =================================== +VOLUME_BACKING_FILE_SIZE={{ cinder_volume_size | default("20G") }} +SWIFT_HASH_SUFFIX={{ swift_hash_suffix | default("devstack-suffix") }} +SWIFT_REPLICAS={{ swift_replicas | default("1") }} +enable_service s-proxy s-object s-container s-account + +# =================================== +# Neutron Configuration (ML2 + OVS) +# =================================== +enable_service neutron +enable_service neutron-api +enable_service neutron-dhcp +enable_service neutron-l3 +enable_service neutron-metadata +enable_service neutron-qos +enable_service neutron-segments +enable_service neutron-sfc + +disable_service ovn +disable_service ovn-northd +disable_service ovn-controller +disable_service ovn-sb +disable_service ovn-nb +disable_service ovn-metadata-agent + +enable_plugin neutron https://opendev.org/openstack/neutron +Q_PLUGIN=ml2 +Q_AGENT=openvswitch +Q_ML2_PLUGIN_MECHANISM_DRIVERS=openvswitch +Q_ML2_PLUGIN_TYPE_DRIVERS=flat,vlan,vxlan +Q_ML2_PLUGIN_EXT_DRIVERS=port_security,qos,trunk +Q_ML2_TENANT_NETWORK_TYPE={{ neutron_network_type | default("vxlan") }} + +OVS_BRIDGE_MAPPINGS=physnet1:br-ex +PHYSICAL_NETWORK=physnet1 +OVS_PHYSICAL_BRIDGE=br-ex + +NEUTRON_OVS_BRIDGE=br-int +NEUTRON_OVS_BRIDGE_IFACES=$NEUTRON_PUBLIC_INTERFACE +NEUTRON_OVS_BRIDGE_IFACES_EXTRA=$NEUTRON_PRIVATE_INTERFACE +NEUTRON_OVS_BRIDGE_IFACES_EXTRA_OPTIONS="type=internal" + +Q_TUNNEL_TYPES=vxlan +Q_TUNNELING=True +Q_USE_PROVIDERNET_FOR_PUBLIC=True +Q_USE_SECGROUP=True +Q_L3_ENABLED=True + +NEUTRON_DHCP_AGENT_EXTRA_OPTS="--enable-metadata" +NEUTRON_L3_AGENT_EXTRA_OPTS="--enable-metadata" +NEUTRON_METADATA_AGENT_EXTRA_OPTS="--enable-metadata" + +# =================================== +# Heat (Required for Magnum) +# =================================== +enable_service heat +enable_service h-api +enable_service h-api-cfn +enable_service h-api-cw +enable_service h-eng + +# =================================== +# Magnum (Container Orchestration) +# =================================== +enable_plugin magnum https://opendev.org/openstack/magnum +enable_service magnum +enable_service magnum-api +enable_service magnum-cond + +# =================================== +# Barbican (Optional - TLS Certificates) +# =================================== +enable_plugin barbican https://opendev.org/openstack/barbican +enable_service barbican-api +enable_service barbican-keystone-listener +enable_service barbican-worker +enable_service barbican-retry + +# =================================== +# Post-script: Download Kubernetes-compatible image +# =================================== +[[post-script|$TOP_DIR/tools/magnum-setup.sh]] +args="k8s" + +# =================================== +# Magnum config overrides +# =================================== +[[post-config|$MAGNUM_CONF]] +[certificates] +cert_manager_type = barbican + +[drivers] +default_driver = kubernetes diff --git a/playbooks/install_openstack/roles/setup-env/tasks/main.yml b/playbooks/install_openstack/roles/setup-env/tasks/main.yml new file mode 100644 index 00000000..24e05065 --- /dev/null +++ b/playbooks/install_openstack/roles/setup-env/tasks/main.yml @@ -0,0 +1,61 @@ +--- +- name: Ensure stack user owns /opt/stack + file: + path: /opt/stack + state: directory + owner: "{{ stack_user }}" + group: "{{ stack_user }}" + mode: "0755" + become: yes + +- name: Ensure stack user has correct shell environment in .bashrc + copy: + dest: /opt/stack/.bashrc + content: | + # .bashrc + export PATH=$PATH:/usr/local/bin + export PYTHONPATH=/opt/stack + export DEVSTACK_DIR=/opt/stack/devstack + export OS_AUTH_URL=http://{{ openstack_host_ip }}/identity + export OS_IDENTITY_API_VERSION=3 + export OS_IMAGE_API_VERSION=2 + export OS_PROJECT_DOMAIN_ID=default + export OS_PROJECT_NAME=admin + export OS_TENANT_NAME=admin + export OS_USERNAME=admin + export OS_USER_DOMAIN_ID=default + export OS_REGION_NAME=RegionOne + export OS_PASSWORD={{ admin_password }} + owner: "{{ stack_user }}" + group: "{{ stack_user }}" + mode: "0644" + become: yes + notify: reload bashrc + +- name: Ensure stack user has correct shell environment in .bash_profile + copy: + dest: /opt/stack/.bash_profile + content: | + # .bash_profile + if [ -f /opt/stack/.bashrc ]; then + . /opt/stack/.bashrc + fi + owner: "{{ stack_user }}" + group: "{{ stack_user }}" + mode: "0644" + become: yes + notify: reload bash_profile + +- name: Ensure stack user has correct shell environment in .profile + copy: + dest: /opt/stack/.profile + content: | + # .profile + if [ -f /opt/stack/.bashrc ]; then + . /opt/stack/.bashrc + fi + owner: "{{ stack_user }}" + group: "{{ stack_user }}" + mode: "0644" + become: yes + notify: reload profile diff --git a/playbooks/install_openstack/test-openstack.yml b/playbooks/install_openstack/test-openstack.yml new file mode 100644 index 00000000..0e1c293d --- /dev/null +++ b/playbooks/install_openstack/test-openstack.yml @@ -0,0 +1,141 @@ +--- +- name: Test OpenStack Installation + hosts: all + become: yes + become_user: "{{ stack_user }}" + vars_files: + - "{{ playbook_dir }}/group_vars/all.yml" + tasks: + - name: Check if openstack client is installed + command: which openstack + register: openstack_client + ignore_errors: yes + changed_when: false + + - name: Install openstack client if not present + apt: + name: python3-openstackclient + state: present + update_cache: yes + become: yes + become_user: root + when: openstack_client.rc != 0 + + - name: Source OpenStack credentials + shell: | + source /opt/stack/devstack/openrc admin admin + env | grep OS_ + args: + executable: /bin/bash + register: openrc_output + changed_when: false + + - name: Display OpenStack environment + debug: + msg: "OpenStack environment: {{ openrc_output.stdout_lines }}" + + - name: Test Keystone (Identity Service) + shell: | + source /opt/stack/devstack/openrc admin admin + openstack token issue + args: + executable: /bin/bash + register: keystone_test + changed_when: false + + - name: Display Keystone test results + debug: + msg: "Keystone is working: {{ keystone_test.stdout }}" + + - name: Test Nova (Compute Service) + shell: | + source /opt/stack/devstack/openrc admin admin + openstack compute service list + args: + executable: /bin/bash + register: nova_test + changed_when: false + + - name: Display Nova test results + debug: + msg: "Nova services status: {{ nova_test.stdout }}" + + - name: Test Neutron (Network Service) + shell: | + source /opt/stack/devstack/openrc admin admin + openstack network agent list + args: + executable: /bin/bash + register: neutron_test + changed_when: false + ignore_errors: yes + + - name: Display Neutron test results + debug: + msg: "Neutron agents status: {{ neutron_test.stdout if neutron_test.rc == 0 else 'Neutron service not available' }}" + + - name: Test Glance (Image Service) + shell: | + source /opt/stack/devstack/openrc admin admin + openstack image list + args: + executable: /bin/bash + register: glance_test + changed_when: false + ignore_errors: yes + + - name: Display Glance test results + debug: + msg: "Glance images: {{ glance_test.stdout if glance_test.rc == 0 else 'Glance service not available' }}" + + - name: Test Horizon (Dashboard) + uri: + url: "http://{{ openstack_host_ip }}/dashboard" + method: GET + return_content: yes + status_code: 200 + register: horizon_test + ignore_errors: yes + + - name: Display Horizon test results + debug: + msg: "Horizon dashboard is {{ 'accessible' if horizon_test.status == 200 else 'not accessible' }}" + + - name: Test RabbitMQ + shell: | + sudo rabbitmqctl cluster_status + args: + executable: /bin/bash + register: rabbitmq_test + changed_when: false + ignore_errors: yes + + - name: Display RabbitMQ test results + debug: + msg: "RabbitMQ cluster status: {{ rabbitmq_test.stdout if rabbitmq_test.rc == 0 else 'RabbitMQ not available' }}" + + - name: Test MySQL + shell: | + sudo mysql -u root -p{{ admin_password }} -e "SHOW DATABASES;" + args: + executable: /bin/bash + register: mysql_test + changed_when: false + ignore_errors: yes + + - name: Display MySQL test results + debug: + msg: "MySQL databases: {{ mysql_test.stdout if mysql_test.rc == 0 else 'MySQL not available' }}" + + - name: Test Open vSwitch + shell: | + sudo ovs-vsctl show + args: + executable: /bin/bash + register: ovs_test + changed_when: false + ignore_errors: yes + + - name: Display Open vSwitch test results + debug: + msg: "Open vSwitch status: {{ ovs_test.stdout if ovs_test.rc == 0 else 'Open vSwitch not available' }}" diff --git a/playbooks/minimal_kvm_setup.yml b/playbooks/minimal_kvm_setup.yml new file mode 100644 index 00000000..2e95c556 --- /dev/null +++ b/playbooks/minimal_kvm_setup.yml @@ -0,0 +1,28 @@ +--- +- name: Install QEMU, KVM, and Libvirt on Ubuntu Server + hosts: all # This playbook is designed to run on all hosts in the inventory but can be limited to specific groups or hosts as needed + become: true + tasks: + - name: Install required packages + apt: + name: + - qemu-kvm + - libvirt-daemon-system + - libvirt-clients + - bridge-utils + - virtinst + - virt-manager + state: present + update_cache: true + + - name: Ensure libvirtd service is running and enabled + systemd: + name: libvirtd + enabled: true + state: started + + - name: Add current user to libvirt and kvm groups + user: + name: "{{ ansible_user }}" + groups: libvirt,kvm + append: yes diff --git a/playbooks/ntp_setup.yml b/playbooks/ntp_setup.yml new file mode 100644 index 00000000..d7bf0b38 --- /dev/null +++ b/playbooks/ntp_setup.yml @@ -0,0 +1,9 @@ +- name: Install Ntp using ansible playbook + hosts: all + become: yes + tasks: + - name: install ntp package + apt: + name: ntp + state: present + update_cache: yes diff --git a/playbooks/openstack-devstack-ansible/.vscode/settings.json b/playbooks/openstack-devstack-ansible/.vscode/settings.json new file mode 100644 index 00000000..3a9326b1 --- /dev/null +++ b/playbooks/openstack-devstack-ansible/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "ansible.python.interpreterPath": "/usr/bin/python3" +} \ No newline at end of file diff --git a/playbooks/openstack-devstack-ansible/ansible.cfg b/playbooks/openstack-devstack-ansible/ansible.cfg new file mode 100644 index 00000000..12e18b28 --- /dev/null +++ b/playbooks/openstack-devstack-ansible/ansible.cfg @@ -0,0 +1,14 @@ +[defaults] +inventory = inventory/hosts.ini +remote_user = root +host_key_checking = False +retry_files_enabled = False +timeout = 30 +deprecation_warnings = False +roles_path = ./roles +# vault_password_file = .vault_pass.txt + +[privilege_escalation] +become = True +become_method = sudo +become_ask_pass = False diff --git a/playbooks/openstack-devstack-ansible/group_vars/all.yml b/playbooks/openstack-devstack-ansible/group_vars/all.yml new file mode 100644 index 00000000..e4b9ba36 --- /dev/null +++ b/playbooks/openstack-devstack-ansible/group_vars/all.yml @@ -0,0 +1,60 @@ +# OpenStack release +openstack_branch: "stable/2025.1" + +# General system +stack_user: stack +stack_home: /opt/stack +devstack_repo: https://opendev.org/openstack/devstack.git +devstack_dir: "{{ stack_home }}/devstack" +devstack_marker_file: "{{ stack_home }}/.stack_installed" + +# Interface detection fallback +default_interface: "{{ ansible_default_ipv4.interface }}" +default_ip: "{{ ansible_default_ipv4.address }}" +# public_network_gateway: +# floating_ip_range: + +# Core services +enable_keystone: true +enable_glance: true +enable_nova: true +enable_neutron: true +enable_cinder: true +enable_placement: true +enable_horizon: true +enable_magnum: true +magnum_kubectl_version: "v1.28.6" +neutron_plugin: ml2 # or 'ovn' to enable OVN mode + +# Optional compute/storage/network services +enable_swift: false +enable_manila: false +enable_glusterfs: false +enable_heat: false +enable_barbican: false +enable_octavia: false +enable_designate: false +enable_trove: false +enable_zaqar: false +enable_masakari: false +enable_blazar: false +enable_ironic: false +enable_senlin: false +enable_sahara: false + +# Telemetry +enable_ceilometer: false +enable_gnocchi: false +enable_aodh: false +enable_panko: false + +# Security and workflow +enable_congress: false +enable_mistral: false + +# Custom services for future extensibility +custom_services: + - name: tempest + enabled: false + - name: kuryr + enabled: false \ No newline at end of file diff --git a/playbooks/openstack-devstack-ansible/inventory/hosts.ini b/playbooks/openstack-devstack-ansible/inventory/hosts.ini new file mode 100644 index 00000000..391c2dbd --- /dev/null +++ b/playbooks/openstack-devstack-ansible/inventory/hosts.ini @@ -0,0 +1,5 @@ +[devstack] +multipass-vm ansible_user=ubuntu ansible_host=10.138.101.66 ansible_ssh_private_key_file=~/.ssh/ansible ansible_ssh_common_args='-o ProxyJump=goats4rust@10.42.0.11' + +[devstack:vars] +ansible_python_interpreter=auto diff --git a/playbooks/openstack-devstack-ansible/roles/clone-devstack/tasks/main.yml b/playbooks/openstack-devstack-ansible/roles/clone-devstack/tasks/main.yml new file mode 100644 index 00000000..1b58c281 --- /dev/null +++ b/playbooks/openstack-devstack-ansible/roles/clone-devstack/tasks/main.yml @@ -0,0 +1,15 @@ +--- +- name: Ensure /opt/stack/devstack is not already cloned + stat: + path: "{{ devstack_dir }}/.git" + register: devstack_git_dir_status + +- name: Clone DevStack repository + git: + repo: "{{ devstack_repo }}" + dest: "{{ devstack_dir }}" + version: "{{ openstack_branch }}" + force: no + become: yes + become_user: "{{ stack_user }}" + when: not devstack_git_dir_status.stat.exists diff --git a/playbooks/openstack-devstack-ansible/roles/configure-devstack/tasks/main.yml b/playbooks/openstack-devstack-ansible/roles/configure-devstack/tasks/main.yml new file mode 100644 index 00000000..e9456973 --- /dev/null +++ b/playbooks/openstack-devstack-ansible/roles/configure-devstack/tasks/main.yml @@ -0,0 +1,8 @@ +--- +- name: Template local.conf + template: + src: local.conf.j2 + dest: /opt/stack/devstack/local.conf + owner: stack + group: wheel + mode: '0644' diff --git a/playbooks/openstack-devstack-ansible/roles/configure-devstack/templates/local.conf.j2 b/playbooks/openstack-devstack-ansible/roles/configure-devstack/templates/local.conf.j2 new file mode 100644 index 00000000..03498dd9 --- /dev/null +++ b/playbooks/openstack-devstack-ansible/roles/configure-devstack/templates/local.conf.j2 @@ -0,0 +1,367 @@ +[[local|localrc]] + +# ============================================================================== +# Core DevStack Settings +# ============================================================================== +DEST={{ stack_home }} +DATA_DIR=$DEST/data +USE_SYSTEMD=True +OS_BRANCH={{ openstack_branch | default('stable/2025.1') }} +RECLONE={{ 'yes' if devstack_reclone | default(false) else 'no' }} + +# --- Logging --- +LOGFILE=$DEST/logs/stack.sh.log +LOGDAYS=7 +VERBOSE=True +LOG_COLOR=True +SCREEN_LOGDIR=$DEST/logs + +# ============================================================================== +# Security Credentials (Vault/vars) +# ============================================================================== +ADMIN_PASSWORD={{ ADMIN_PASSWORD }} +DATABASE_PASSWORD={{ DATABASE_PASSWORD }} +RABBIT_PASSWORD={{ RABBIT_PASSWORD }} +SERVICE_PASSWORD={{ SERVICE_PASSWORD }} +SERVICE_TOKEN={{ service_token | default(SERVICE_PASSWORD) }} + +KEYSTONE_PASSWORD={{ KEYSTONE_PASSWORD | default(SERVICE_PASSWORD) }} +GLANCE_PASSWORD={{ GLANCE_PASSWORD | default(SERVICE_PASSWORD) }} +NOVA_PASSWORD={{ NOVA_PASSWORD | default(SERVICE_PASSWORD) }} +NEUTRON_PASSWORD={{ NEUTRON_PASSWORD | default(SERVICE_PASSWORD) }} +CINDER_PASSWORD={{ CINDER_PASSWORD | default(SERVICE_PASSWORD) }} +PLACEMENT_PASSWORD={{ PLACEMENT_PASSWORD | default(SERVICE_PASSWORD) }} + +# ============================================================================== +# Network Configuration +# ============================================================================== +HOST_IP={{ default_ip }} +PUBLIC_INTERFACE={{ default_interface }} +FIXED_RANGE={{ fixed_range | default("10.4.0.0/24") }} +NETWORK_GATEWAY={{ network_gateway | default("10.4.0.1") }} +FLOATING_RANGE={{ floating_ip_range | default("172.24.4.0/24") }} +PUBLIC_NETWORK_GATEWAY={{ public_network_gateway | default("172.24.4.1") }} +MULTI_HOST=True + +# Region Fix (helps with 503s) +REGION_NAME=RegionOne +KEYSTONE_REGION_NAME=RegionOne + +# ============================================================================== +# Core Services +# ============================================================================== +enable_service mysql rabbitmq etcd3 + +{% if enable_keystone | default(true) %} enable_service key {% endif %} +{% if enable_placement | default(true) %} enable_service placement-api placement-client {% endif %} +{% if enable_glance | default(true) %} enable_service g-api g-reg {% endif %} +{% if enable_nova | default(true) %} enable_service n-api n-cauth n-cpu n-cond n-sch n-novnc {% endif %} +{% if enable_horizon | default(true) %} enable_service horizon {% endif %} + +{% if enable_cinder | default(false) %} +enable_service cinder c-api c-vol c-sch +CINDER_DRIVER=lvm +VOLUME_GROUP_NAME="cinder-volumes" +VOLUME_BACKING_FILE_SIZE={{ cinder_volume_file_size | default("20G") }} +{% endif %} + +# ============================================================================== +# Neutron: ML2/OVS or OVN +# ============================================================================== +{% if enable_neutron | default(true) %} +disable_service n-net +enable_service neutron q-svc q-metering + +{% if neutron_plugin | default('ovs') == 'ovn' %} +enable_service q-ovn-metadata-agent ovn-controller ovn-northd +disable_service q-agt q-dhcp q-l3 q-meta +Q_AGENT=ovn +Q_PLUGIN=ml2 +Q_ML2_PLUGIN_MECHANISM_DRIVERS=ovn,logger +Q_ML2_PLUGIN_TYPE_DRIVERS=geneve,vlan,flat +Q_ML2_TENANT_NETWORK_TYPE=geneve +OVN_L3_MODE=True +ENABLE_TENANT_VLANS=True +{% else %} +enable_service ovsdb-server ovs-vswitchd +enable_service q-agt q-dhcp q-l3 q-meta +Q_PLUGIN=ml2 +Q_AGENT=openvswitch +Q_ML2_PLUGIN_MECHANISM_DRIVERS=openvswitch,l2population +Q_ML2_PLUGIN_TYPE_DRIVERS=vxlan,flat,vlan +Q_ML2_TENANT_NETWORK_TYPE=vxlan +Q_ML2_PLUGIN_EXT_DRIVERS=port_security +OVS_BRIDGE_MAPPINGS="public:{{ public_bridge | default('br-ex') }}" +PUBLIC_BRIDGE={{ public_bridge | default('br-ex') }} +ENABLE_TENANT_VLANS=True +{% endif %} +{% endif %} + +# ============================================================================== +# Optional Services +# ============================================================================== +{% if enable_heat | default(false) %} +enable_plugin heat https://opendev.org/openstack/heat +enable_plugin heat-dashboard https://opendev.org/openstack/heat-dashboard +{% endif %} + +{% if enable_swift | default(false) %} +enable_plugin swift https://opendev.org/openstack/swift +enable_service s-proxy s-object s-container s-account +SWIFT_HASH={{ swift_hash_path_suffix | default("$(od -t x8 -N 8 -A n /dev/urandom)") }} +SWIFT_REPLICAS={{ swift_replicas | default(1) }} +SWIFT_DATA_DIR=$DEST/data/swift +{% endif %} + +{% if enable_manila | default(false) %} +enable_plugin manila https://opendev.org/openstack/manila +enable_plugin manila-ui https://opendev.org/openstack/manila-ui +enable_service manila m-api m-sch m-shr +{% endif %} + +{% if enable_octavia | default(false) %} +enable_plugin octavia https://opendev.org/openstack/octavia +enable_plugin octavia-dashboard https://opendev.org/openstack/octavia-dashboard +enable_service octavia o-api o-hk o-hm o-cw +{% endif %} + +{% if enable_barbican | default(false) %} +enable_plugin barbican https://opendev.org/openstack/barbican +enable_plugin barbican-dashboard https://opendev.org/openstack/barbican-dashboard +{% endif %} + +{% if enable_designate | default(false) %} +enable_plugin designate https://opendev.org/openstack/designate +enable_plugin designate-dashboard https://opendev.org/openstack/designate-dashboard +enable_service designate designate-api designate-central designate-mdns designate-pool-manager designate-worker designate-zone-manager +{% endif %} + +{% if enable_trove | default(false) %} +enable_plugin trove https://opendev.org/openstack/trove +enable_plugin trove-dashboard https://opendev.org/openstack/trove-dashboard +enable_service tr-api tr-cond tr-taskmgr +{% endif %} + +{% if enable_sahara | default(false) %} +enable_plugin sahara https://opendev.org/openstack/sahara +enable_plugin sahara-dashboard https://opendev.org/openstack/sahara-dashboard +enable_service sahara-api sahara-engine +{% endif %} + +{% if enable_magnum | default(false) %} +enable_plugin magnum https://opendev.org/openstack/magnum +enable_plugin magnum-ui https://opendev.org/openstack/magnum-ui +MAGNUM_IMAGE_NAME={{ magnum_image_name | default('fedora-coreos-stable') }} +MAGNUM_KUBECTL_VERSION={{ magnum_kubectl_version | default("v1.28.6") }} +MAGNUM_KUBECTL_TAG={{ magnum_kubectl_version | default("v1.28.6") }} +{% endif %} + +{% if enable_ironic | default(false) %} +enable_plugin ironic https://opendev.org/openstack/ironic +enable_plugin ironic-ui https://opendev.org/openstack/ironic-ui +enable_service ir-api ir-cond +IRONIC_DEFAULT_DEPLOY_INTERFACE=direct +IRONIC_ENABLED_HARDWARE_TYPES=ipmi,redfish,idrac,ilo +IRONIC_ENABLED_DEPLOY_INTERFACES=direct,ansible +IRONIC_ENABLED_MANAGEMENT_INTERFACES=ipmitool,redfish,idrac,ilo +IRONIC_ENABLED_POWER_INTERFACES=ipmitool,redfish,idrac,ilo +{% endif %} + +{% if enable_senlin | default(false) %} +enable_plugin senlin https://opendev.org/openstack/senlin +enable_plugin senlin-dashboard https://opendev.org/openstack/senlin-dashboard +enable_service senlin senlin-api senlin-engine +{% endif %} + +{% if enable_zaqar | default(false) %} +enable_plugin zaqar https://opendev.org/openstack/zaqar +enable_service zaqar-server +{% endif %} + +{% if enable_blazar | default(false) %} +enable_plugin blazar https://opendev.org/openstack/blazar +enable_plugin blazar-dashboard https://opendev.org/openstack/blazar-dashboard +enable_service blazar blazar-api blazar-manager +{% endif %} + +{% if enable_masakari | default(false) %} +enable_plugin masakari https://opendev.org/openstack/masakari +enable_plugin masakari-dashboard https://opendev.org/openstack/masakari-dashboard +enable_service masakari masakari-api masakari-engine +{% endif %} + +# ============================================================================== +# Telemetry Services +# ============================================================================== +{% if enable_gnocchi | default(false) %} +enable_plugin gnocchi https://opendev.org/openstack/gnocchi +enable_service gnocchi-api gnocchi-metricd +{% endif %} + +{% if enable_ceilometer | default(false) %} +enable_plugin ceilometer https://opendev.org/openstack/ceilometer +enable_service ceilometer-acentral ceilometer-acompute ceilometer-anotification ceilometer-collector +{% if enable_gnocchi | default(false) %} +CEILOMETER_PIPELINE_PUBLISHERS=gnocchi:// +{% endif %} +{% endif %} + +{% if enable_aodh | default(false) %} +enable_plugin aodh https://opendev.org/openstack/aodh +enable_service aodh-api aodh-evaluator aodh-notifier aodh-listener +{% endif %} + +{% if enable_panko | default(false) %} +enable_plugin panko https://opendev.org/openstack/panko +enable_service panko-api +{% endif %} + +# ============================================================================== +# Security and Workflow Services +# ============================================================================== +{% if enable_congress | default(false) %} +enable_plugin congress https://opendev.org/openstack/congress +enable_plugin congress-dashboard https://opendev.org/openstack/congress-dashboard +enable_service congress-api congress-policy-engine +{% endif %} + +{% if enable_mistral | default(false) %} +enable_plugin mistral https://opendev.org/openstack/mistral +enable_service mistral-api mistral-engine mistral-executor +{% endif %} + +{% if custom_services is defined %} +{% for svc in custom_services %} +{% if svc.name == 'tempest' and svc.enabled %} +enable_plugin tempest https://opendev.org/openstack/tempest +{% endif %} +{% if svc.name == 'kuryr' and svc.enabled %} +enable_plugin kuryr-libnetwork https://opendev.org/openstack/kuryr-libnetwork +enable_service kuryr +{% endif %} +{% endfor %} +{% endif %} + +# ============================================================================== +# Post-Config Overrides +# ============================================================================== +{% if enable_keystone | default(true) %} +[[post-config|$KEYSTONE_CONF]] +[DEFAULT] +public_endpoint = http://{{ default_ip }}:5000/ +admin_endpoint = http://{{ default_ip }}:5000/ +{% endif %} + +{% if enable_nova | default(true) %} +[[post-config|$NOVA_CONF]] +[DEFAULT] +force_config_drive = True +[vnc] +server_listen = {{ default_ip }} +server_proxyclient_address = {{ default_ip }} +[neutron] +auth_url = http://{{ default_ip }}/identity +auth_type = password +username = neutron +password = {{ NEUTRON_PASSWORD }} +project_name = service +project_domain_name = Default +user_domain_name = Default +region_name = RegionOne +service_metadata_proxy = True +metadata_proxy_shared_secret = {{ SERVICE_PASSWORD }} +{% endif %} + +{% if enable_neutron | default(true) %} +[[post-config|$NEUTRON_CONF]] +[DEFAULT] +debug = {{ 'True' if verbose_logging | default(true) else 'False' }} +core_plugin = ml2 +service_plugins = router +allow_overlapping_ips = True +notify_nova_on_port_status_changes = True +notify_nova_on_port_data_changes = True +api_workers = 2 +rpc_workers = 2 +[keystone_authtoken] +auth_url = http://{{ default_ip }}/identity +www_authenticate_uri = http://{{ default_ip }}/identity +memcached_servers = {{ default_ip }}:11211 +auth_type = password +username = neutron +password = {{ NEUTRON_PASSWORD }} +project_name = service +project_domain_name = Default +user_domain_name = Default + +[[post-config|/etc/neutron/plugins/ml2/ml2_conf.ini]] +[ml2] +{% if neutron_plugin | default('ovs') == 'ovn' %} +type_drivers = geneve,vlan,flat +tenant_network_types = geneve +mechanism_drivers = ovn,logger +extension_drivers = port_security +path_mtu = 1442 +{% else %} +type_drivers = vxlan,flat,vlan +tenant_network_types = vxlan +mechanism_drivers = openvswitch,l2population +extension_drivers = port_security +[ml2_type_vxlan] +vni_ranges = 1:1000 +[ovs] +local_ip = {{ default_ip }} +bridge_mappings = public:{{ public_bridge | default('br-ex') }} +[agent] +tunnel_types = vxlan +l2_population = True +[securitygroup] +firewall_driver = neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver +enable_ipset = True +{% endif %} +{% endif %} + +# ============================================================================== +# Post-Extra: Health Checks, Network Delays +# ============================================================================== +[[post-extra]] +#!/bin/bash +echo "Creating ML2 config directory if missing..." +mkdir -p "{{ stack_home }}/etc/neutron/plugins/ml2" + +echo "Waiting for Keystone to stabilize..." +sleep 10 + +function check_api { + local svc="$1"; local url="$2"; local timeout=180; local count=0 + echo -n "Checking $svc API at $url..." + while ! curl -fs "$url" >/dev/null; do + sleep 2; count=$((count+2)) + if [ $count -ge $timeout ]; then echo " FAIL."; exit 1; fi + echo -n "."; + done + echo " OK" +} + +{% if enable_keystone | default(true) %} check_api "Keystone" "http://{{ default_ip }}/identity" {% endif %} +{% if enable_glance | default(true) %} check_api "Glance" "http://{{ default_ip }}:9292" {% endif %} +{% if enable_nova | default(true) %} check_api "Nova" "http://{{ default_ip }}:8774" {% endif %} +{% if enable_neutron | default(true) %} check_api "Neutron" "http://{{ default_ip }}:9696" {% endif %} + +echo "Testing CLI authentication..." +source "{{ stack_home }}/openrc" admin admin +if ! openstack endpoint list > /dev/null; then + echo "FAIL: CLI endpoint list failed"; exit 1 +fi + +echo "Ensuring OVSDB is ready..." +for i in {1..10}; do + if sudo ovs-vsctl show &>/dev/null; then + echo "OVSDB is ready." + break + fi + echo "Waiting..." + sleep 3 +done + +sudo ovs-vsctl set-manager ptcp:6640:127.0.0.1 || true diff --git a/playbooks/openstack-devstack-ansible/roles/create-user/tasks/main.yml b/playbooks/openstack-devstack-ansible/roles/create-user/tasks/main.yml new file mode 100644 index 00000000..986b8537 --- /dev/null +++ b/playbooks/openstack-devstack-ansible/roles/create-user/tasks/main.yml @@ -0,0 +1,28 @@ +--- +- name: Create 'stack' user + user: + name: "{{ stack_user }}" + comment: DevStack user + shell: /bin/bash + home: /opt/stack + create_home: yes + group: wheel + state: present + +- name: Ensure /opt/stack directory exists with correct permissions + file: + path: /opt/stack + state: directory + owner: stack + group: wheel + mode: '0755' + +- name: Allow 'stack' user passwordless sudo + copy: + dest: /etc/sudoers.d/stack + content: | + stack ALL=(ALL) NOPASSWD:ALL + owner: root + group: root + mode: '0440' + validate: '/usr/sbin/visudo -cf %s' diff --git a/playbooks/openstack-devstack-ansible/roles/detect-system/tasks/main.yml b/playbooks/openstack-devstack-ansible/roles/detect-system/tasks/main.yml new file mode 100644 index 00000000..421ae87e --- /dev/null +++ b/playbooks/openstack-devstack-ansible/roles/detect-system/tasks/main.yml @@ -0,0 +1,42 @@ +--- +- name: Gather full Ansible facts + setup: + +- name: Assert minimum memory + assert: + that: + - ansible_memtotal_mb >= 6000 + fail_msg: "Minimum 6GB RAM is required to run DevStack reliably" + when: ansible_memtotal_mb is defined + +- name: Assert minimum CPU cores + assert: + that: + - ansible_processor_vcpus >= 2 + fail_msg: "At least 2 vCPUs are required" + when: ansible_processor_vcpus is defined + +- name: Detect active interfaces (fallback-capable) + set_fact: + active_interfaces: >- + {{ ansible_interfaces | + select('match', '^(en|eth|ens|eno|wl)') | + difference(['lo']) | list }} + +- name: Detect default interface and IP + set_fact: + detected_interface: "{{ ansible_default_ipv4.interface | default(active_interfaces[0] | default('unknown')) }}" + detected_ip: "{{ ansible_default_ipv4.address | default('0.0.0.0') }}" + +- name: Warn if default interface or IP is not reliably detected + debug: + msg: >- + {{ 'Warning: Default interface or IP not reliably detected.' + if detected_interface == 'unknown' or detected_ip == '0.0.0.0' + else 'Interface and IP successfully detected.' }} + +- name: Show interface detection results + debug: + msg: + - "Interface: {{ detected_interface }}" + - "IP Address: {{ detected_ip }}" diff --git a/playbooks/openstack-devstack-ansible/roles/fix-dns/tasks/main.yml b/playbooks/openstack-devstack-ansible/roles/fix-dns/tasks/main.yml new file mode 100644 index 00000000..e38b1d36 --- /dev/null +++ b/playbooks/openstack-devstack-ansible/roles/fix-dns/tasks/main.yml @@ -0,0 +1,17 @@ +--- +- name: Ensure /etc/resolv.conf has valid DNS servers + become: true + copy: + dest: /etc/resolv.conf + content: | + nameserver 8.8.8.8 + nameserver 1.1.1.1 + owner: root + group: root + mode: '0644' + when: fix_devstack_dns | default(true) + +- name: Optionally lock resolv.conf to prevent overwrite + become: true + command: chattr +i /etc/resolv.conf + when: lock_resolv_conf | default(false) diff --git a/playbooks/openstack-devstack-ansible/roles/post-install/tasks/main.yml b/playbooks/openstack-devstack-ansible/roles/post-install/tasks/main.yml new file mode 100644 index 00000000..64218d6a --- /dev/null +++ b/playbooks/openstack-devstack-ansible/roles/post-install/tasks/main.yml @@ -0,0 +1,12 @@ +--- +- name: Show final DevStack install summary + debug: + msg: | + DevStack installation complete. + + Horizon URL : http://{{ ansible_default_ipv4.address }}/dashboard + Admin Username : admin + Admin Password : {{ ADMIN_PASSWORD }} + User Password : {{ ADMIN_PASSWORD }} + + Check logs at: /opt/stack/devstack-install.log diff --git a/playbooks/openstack-devstack-ansible/roles/prerequisites/tasks/main.yml b/playbooks/openstack-devstack-ansible/roles/prerequisites/tasks/main.yml new file mode 100644 index 00000000..adb916a1 --- /dev/null +++ b/playbooks/openstack-devstack-ansible/roles/prerequisites/tasks/main.yml @@ -0,0 +1,142 @@ +--- +- name: Ensure apt cache is up to date + ansible.builtin.apt: + update_cache: yes + cache_valid_time: 3600 + +- name: Install PyMySQL + pip: + name: PyMySQL + state: present + become: yes + +- name: Install mysqlclient + pip: + name: mysqlclient + state: present + become: yes + +- name: Install required base packages + ansible.builtin.apt: + name: "{{ item }}" + state: present + loop: + - git + - python3 + - python3-pip + - python3-venv + - python3-dev + - python3-setuptools + - python3-wheel + - sudo + - net-tools + - curl + - wget + - vim + - dnsutils + - lvm2 + - thin-provisioning-tools + - software-properties-common + - build-essential + - jq + - libffi-dev + - libssl-dev + - libxml2-dev + - libxslt1-dev + - libjpeg8-dev + - zlib1g-dev + - libmysqlclient-dev + - libpq-dev + - libsqlite3-dev + - libvirt-dev + - libvirt-daemon-system + - qemu-kvm + - qemu-utils + - libguestfs-tools + - openvswitch-switch + - openvswitch-common + - bridge-utils + - ntp + - ntpdate + register: package_install + retries: 3 + delay: 5 + until: package_install is success + +- name: Ensure MySQL root password is set for automatic installation + ansible.builtin.debconf: + name: mysql-server + question: "mysql-server/root_password" + value: "{{ DATABASE_PASSWORD }}" + vtype: "string" + become: yes + +- name: Ensure MySQL root password is set for automatic installation (again) + ansible.builtin.debconf: + name: mysql-server + question: "mysql-server/root_password_again" + value: "{{ DATABASE_PASSWORD }}" + vtype: "string" + become: yes + +- name: Install MySQL Server + ansible.builtin.apt: + name: mysql-server + state: present + update_cache: yes + become: yes + +- name: Install RabbitMQ + ansible.builtin.apt: + name: rabbitmq-server + state: present + update_cache: yes + become: yes + +- name: Set MySQL root user authentication method to mysql_native_password + community.mysql.mysql_user: + name: root + host: localhost + password: "{{ DATABASE_PASSWORD }}" + login_user: root + login_password: "{{ DATABASE_PASSWORD }}" + state: present + become: yes + +- name: Create Python virtual environment for DevStack + ansible.builtin.command: + cmd: python3 -m venv /opt/stack/venv + creates: /opt/stack/venv + become: yes + +- name: Ensure MySQL service is running + ansible.builtin.service: + name: mysql + state: started + enabled: yes + become: yes + +- name: Ensure RabbitMQ service is running + ansible.builtin.service: + name: rabbitmq-server + state: started + enabled: yes + become: yes + +- name: Install Python packages inside virtual environment + ansible.builtin.pip: + name: + - netaddr + - shade + - openstacksdk + - virtualenv + - setuptools + - wheel + executable: /opt/stack/venv/bin/pip + state: present + become: yes + +- name: Ensure 'wheel' group exists + ansible.builtin.group: + name: wheel + state: present diff --git a/playbooks/openstack-devstack-ansible/roles/run-devstack/tasks/main.yml b/playbooks/openstack-devstack-ansible/roles/run-devstack/tasks/main.yml new file mode 100644 index 00000000..1350367e --- /dev/null +++ b/playbooks/openstack-devstack-ansible/roles/run-devstack/tasks/main.yml @@ -0,0 +1,73 @@ +--- +- name: Check if DevStack has already been run + stat: + path: /opt/stack/.devstack_installed + register: devstack_marker + +# --- Open vSwitch setup (OVN/ML2 precondition) --- +- name: Install Open vSwitch + become: true + apt: + name: openvswitch-switch + state: present + update_cache: yes + +- name: Enable and start OVS systemd service + become: true + systemd: + name: openvswitch-switch + enabled: yes + state: started + +- name: Check if ovs-vsctl exists + become: true + command: which ovs-vsctl + register: ovs_vsctl_check + changed_when: false + ignore_errors: true + +- name: Set OVS to listen on TCP:6640 + become: true + command: ovs-vsctl set-manager ptcp:6640:127.0.0.1 + when: ovs_vsctl_check.rc == 0 + +- name: Verify OVSDB manager is set + become: true + command: ovs-vsctl get-manager + register: ovs_manager_result + when: ovs_vsctl_check.rc == 0 + +- name: Show OVSDB manager result + debug: + var: ovs_manager_result.stdout + when: ovs_vsctl_check.rc == 0 + +- name: Ensure OVSDB is listening on TCP:6640 + become: true + shell: ss -tlpn | grep ':6640' + register: ovs_tcp_check + failed_when: ovs_tcp_check.rc != 0 + changed_when: false + when: ovs_vsctl_check.rc == 0 + +# --- DevStack Installation --- +- name: Run DevStack stack.sh + shell: ./stack.sh > /opt/stack/devstack-install.log 2>&1 + args: + chdir: /opt/stack/devstack + executable: /bin/bash + become: true + become_user: stack + when: not devstack_marker.stat.exists + register: devstack_result + failed_when: devstack_result.rc != 0 + +- name: Create marker file to indicate DevStack was installed + become: true + file: + path: /opt/stack/.devstack_installed + state: touch + owner: stack + group: stack + mode: '0644' + when: not devstack_marker.stat.exists diff --git a/playbooks/openstack-devstack-ansible/roles/setup-env/tasks/main.yml b/playbooks/openstack-devstack-ansible/roles/setup-env/tasks/main.yml new file mode 100644 index 00000000..3c86b1bc --- /dev/null +++ b/playbooks/openstack-devstack-ansible/roles/setup-env/tasks/main.yml @@ -0,0 +1,30 @@ +--- +- name: Create environment setup script for stack user + copy: + dest: /opt/stack/.devstack_env + content: | + export FORCE=yes + export DEST=/opt/stack + export HOST_IP={{ ansible_default_ipv4.address }} + export PATH="$HOME/.local/bin:$PATH" + owner: stack + group: wheel + mode: '0644' + +- name: Ensure .bashrc exists for stack user + file: + path: /opt/stack/.bashrc + state: touch + owner: stack + group: wheel + mode: '0644' + +- name: Ensure .bashrc sources environment script + lineinfile: + path: /opt/stack/.bashrc + line: 'source $HOME/.devstack_env' + state: present + insertafter: EOF + owner: stack + group: wheel + create: yes diff --git a/playbooks/openstack-devstack-ansible/site.yml b/playbooks/openstack-devstack-ansible/site.yml new file mode 100644 index 00000000..7523afd4 --- /dev/null +++ b/playbooks/openstack-devstack-ansible/site.yml @@ -0,0 +1,16 @@ +--- +- name: Modular DevStack Deployment + hosts: devstack + become: yes + vars_files: + - vault.yml + roles: + - detect-system + - prerequisites + - create-user + - setup-env + - clone-devstack + - configure-devstack + - fix-dns + - run-devstack + - post-install diff --git a/playbooks/openstack-devstack-ansible/vault.yml b/playbooks/openstack-devstack-ansible/vault.yml new file mode 100644 index 00000000..a8f2f403 --- /dev/null +++ b/playbooks/openstack-devstack-ansible/vault.yml @@ -0,0 +1,17 @@ +ADMIN_PASSWORD: adminpass +DATABASE_PASSWORD: dbpass +RABBIT_PASSWORD: rabbitpass +SERVICE_PASSWORD: servicepass + +# Per-service passwords +KEYSTONE_PASSWORD: keystonepass +GLANCE_PASSWORD: glancepass +NOVA_PASSWORD: novapass +NEUTRON_PASSWORD: neutronpass +CINDER_PASSWORD: cinderpass +HORIZON_PASSWORD: horizonpass +HEAT_PASSWORD: heatpass +SWIFT_PASSWORD: swiftpass +BARBICAN_PASSWORD: barbicanpass +OCTAVIA_PASSWORD: octaviapass +MAGNUM_PASSWORD: magnumpass diff --git a/playbooks/setup-ovs-multipass/create_lab.yml b/playbooks/setup-ovs-multipass/create_lab.yml new file mode 100644 index 00000000..5f2fd337 --- /dev/null +++ b/playbooks/setup-ovs-multipass/create_lab.yml @@ -0,0 +1,26 @@ +- name: Create Multipass instances + hosts: localhost + connection: local + tasks: + - name: Launch control node + command: multipass launch --name ansible-vm1 --cpus 2 --mem 2G --disk 10G + + - name: Launch managed nodes + command: multipass launch --name {{ item }} --cpus 1 --mem 1G --disk 5G + loop: + - node1 + - node2 + +- name: Configure Ansible control node + hosts: ansible-vm1 + tasks: + - name: Install Ansible + apt: + name: ansible + state: present + update_cache: yes + + - name: Ensure Python is installed + apt: + name: python3 + state: present diff --git a/playbooks/setup-ovs-multipass/inventory.ini b/playbooks/setup-ovs-multipass/inventory.ini new file mode 100644 index 00000000..6dad638b --- /dev/null +++ b/playbooks/setup-ovs-multipass/inventory.ini @@ -0,0 +1,10 @@ +[control] +localhost ansible_connection=local + +# this will be configured when the server is ok +[unconfigured_nodes] +future_node1 ansible_host=192.168.1.100 # +# The nodes will be configured as soon as the server is ready + +[multipass_vms:children] +unconfigured_nodes \ No newline at end of file diff --git a/playbooks/setup-ovs-multipass/playbook1.yml b/playbooks/setup-ovs-multipass/playbook1.yml new file mode 100644 index 00000000..6ee6ca7d --- /dev/null +++ b/playbooks/setup-ovs-multipass/playbook1.yml @@ -0,0 +1,93 @@ +--- +- name: Setup OVS and Multipass VMs + hosts: control + become: true + vars_files: + - vars.yml + + tasks: + # This will install the packages wer needed + - name: Install required packages + apt: + name: + - openvswitch-switch + - openvswitch-common + - multipass + - bridge-utils + state: present + update_cache: yes + failed_when: false + register: pkg_status + changed_when: pkg_status.changed + + # Creating OVS bridge to act as vswitch + - name: Create OVS bridge + command: ovs-vsctl add-br {{ ovs_bridge }} + changed_when: false + register: ovs_bridge_create + failed_when: false + + # Setting the bridge up to connect different vms on it + - name: Bring up OVS bridge + command: ip link set {{ ovs_bridge }} up + changed_when: false + + # Creating different multipass vm + - name: Create Multipass instances + command: | + multipass launch --name {{ item.name }} \ + --cpus {{ item.cpus }} \ + --mem {{ item.mem }} \ + --disk {{ item.disk }} + loop: "{{ vlan_config.vlan100.vms + vlan_config.vlan200.vms }}" + register: multipass_launch + changed_when: multipass_launch.rc == 0 + + - name: Get Multipass instance network info + command: multipass info {{ item.name }} + loop: "{{ vlan_config.vlan100.vms + vlan_config.vlan200.vms }}" + register: multipass_info + + - name: Extract MAC addresses + set_fact: + vm_macs: | + {% set macs = {} %} + {% for info in multipass_info.results %} + {% set vm_name = info.item.name %} + {% set mac = info.stdout | regex_search('MAC:\s+([a-f0-9:]+)') %} + {% if mac %} + {% set _ = macs.update({vm_name: mac[1]}) %} + {% endif %} + {% endfor %} + {{ macs }} + changed_when: false + + - name: Create OVS ports with VLANs + command: | + ovs-vsctl add-port {{ ovs_bridge }} {{ item.name }}-port \ + tag={{ item.vlan }} \ + -- set interface {{ item.name }}-port \ + type=internal + loop: "{{ vlan_config.vlan100.vms + vlan_config.vlan200.vms }}" + + - name: Configure VLAN interfaces + command: | + ip link set {{ item.name }}-port up && \ + dhclient {{ item.name }}-port + loop: "{{ vlan_config.vlan100.vms + vlan_config.vlan200.vms }}" + + - name: Show final OVS configuration + command: ovs-vsctl show + register: ovs_show + + - name: Display OVS configuration + debug: + var: ovs_show.stdout + +- name: Configure future nodes (placeholder) + hosts: unconfigured_nodes + gather_facts: false + tasks: + - name: Placeholder for future node configuration + debug: + msg: "This node will be configured later - {{ inventory_hostname }}" diff --git a/playbooks/setup-ovs-multipass/vars.yml b/playbooks/setup-ovs-multipass/vars.yml new file mode 100644 index 00000000..2523eef8 --- /dev/null +++ b/playbooks/setup-ovs-multipass/vars.yml @@ -0,0 +1,27 @@ +--- +# OVS Configuration +ovs_bridge: ansible-ovs-br0 +vlan_ids: [100, 200, 300, 400] + +# Multipass Configuration +multipass_vms: + - name: ovs-vm1 + cpus: 1 + mem: 1G + disk: 5G + vlan: 100 + - name: ovs-vm2 + cpus: 1 + mem: 1G + disk: 5G + vlan: 200 + - name: ovs-vm3 + cpus: 1 + mem: 1G + disk: 5G + vlan: 300 + - name: ovs-vm4 + cpus: 1 + mem: 1G + disk: 5G + vlan: 400 diff --git a/playbooks/setup_vswitch.yml b/playbooks/setup_vswitch.yml new file mode 100644 index 00000000..92bda819 --- /dev/null +++ b/playbooks/setup_vswitch.yml @@ -0,0 +1,42 @@ +--- +- name: Create a vswitch and connect Multipass VMs + hosts: localhost + connection: local + vars: + bridge_name: "multipass_br0" + vm1: "test-vm1" + vm2: "test-vm2" + subnet: "192.168.100.0/24" + vm1_ip: "192.168.100.2" + vm2_ip: "192.168.100.3" + + tasks: + - name: Create a virtual bridge (vswitch) + ansible.builtin.command: "brctl addbr {{ bridge_name }}" + changed_when: false + ignore_errors: true # In case bridge already exists + + - name: Bring up the bridge + ansible.builtin.command: "ip link set {{ bridge_name }} up" + + - name: Assign IP to bridge (optional) + ansible.builtin.command: "ip addr add {{ subnet | replace('0/24', '1/24') }} dev {{ bridge_name }}" + + - name: Stop VMs to modify network settings + ansible.builtin.command: "multipass stop {{ item }}" + loop: "{{ [vm1, vm2] }}" + + - name: Attach VMs to the bridge + ansible.builtin.command: "multipass set local.{{ item }}.network.bridge={{ bridge_name }}" + loop: "{{ [vm1, vm2] }}" + + - name: Start VMs + ansible.builtin.command: "multipass start {{ item }}" + loop: "{{ [vm1, vm2] }}" + + - name: Configure static IPs inside VMs (optional) + ansible.builtin.command: | + multipass exec {{ item.vm }} -- sudo ip addr add {{ item.ip }}/24 dev eth0 + loop: + - { vm: "{{ vm1 }}", ip: "{{ vm1_ip }}" } + - { vm: "{{ vm2 }}", ip: "{{ vm2_ip }}" } diff --git a/scripts/ansible_scripts/setting_up_multipass_vlan/setup_vswitch.yml b/scripts/ansible_scripts/setting_up_multipass_vlan/setup_vswitch.yml index 68e1e503..92bda819 100644 --- a/scripts/ansible_scripts/setting_up_multipass_vlan/setup_vswitch.yml +++ b/scripts/ansible_scripts/setting_up_multipass_vlan/setup_vswitch.yml @@ -14,7 +14,7 @@ - name: Create a virtual bridge (vswitch) ansible.builtin.command: "brctl addbr {{ bridge_name }}" changed_when: false - ignore_errors: true # In case bridge already exists + ignore_errors: true # In case bridge already exists - name: Bring up the bridge ansible.builtin.command: "ip link set {{ bridge_name }} up" diff --git a/scripts/ansible_scripts/setup_environment/minimal_kvm_setup.yml b/scripts/ansible_scripts/setup_environment/minimal_kvm_setup.yml index b8c1a654..16502f72 100644 --- a/scripts/ansible_scripts/setup_environment/minimal_kvm_setup.yml +++ b/scripts/ansible_scripts/setup_environment/minimal_kvm_setup.yml @@ -1,5 +1,6 @@ --- - name: Install QEMU, KVM, and Libvirt on Ubuntu Server + hosts: kvm_hosts become: true tasks: