--- hostname: dev-02.lab.alexpires.me ansible_user: "{{ lookup('env', 'ANSIBLE_USER') }}" ansible_host: "10.19.4.210" # Users login_disable_history: false login_users: - username: "{{ ansible_user }}" comment: "Managed by Ansible" sudoer: true sudoer_root_only: false sudoer_no_password: true pubkey: "{{ lookup('file', 'keys/ansible_user.pub') }}" password_disabled: true - username: devstation comment: "Managed by Ansible" pubkey: "{{ lookup('file', 'keys/localnetwork.pub') }}" shell: "/bin/zsh" groups: - "users" password_disabled: true linux_dev_station_service_user_enabled: true linux_dev_station_service_user: "devstation" linux_dev_station_service_home: "/home/devstation" linux_dev_station_workspace_dir: "/home/devstation/projects" linux_dev_station_scripts_dir: "/home/devstation/scripts" linux_dev_station_logs_dir: "/home/devstation/.local/state/logs" linux_dev_station_code_server_port: 3000 linux_dev_station_code_server_auth: "none" linux_dev_station_opencode_server_port: 4096 linux_dev_station_manage_systemd: true linux_dev_station_oh_my_zsh_enabled: true linux_dev_station_code_server_extensions_enabled: true linux_dev_station_code_server_extensions: - ms-python.python - ms-python.vscode-pylance - ms-python.debugpy - golang.go - ms-azuretools.vscode-docker - hashicorp.terraform - opentofu.vscode-opentofu - redhat.ansible - redhat.vscode-yaml - eamodio.gitlens linux_dev_station_ssh_agent_enabled: true linux_dev_station_mcp_bootstrap_commands: [] linux_dev_station_mcp_installers_enabled: true linux_dev_station_mcp_installers: - name: "chrome-devtools-mcp" kind: "npm" package: "chrome-devtools-mcp" version: "latest" - name: "playwright-mcp" kind: "npm" package: "@playwright/mcp" version: "latest" - name: "aws-documentation-mcp" kind: "uv" package: "awslabs.aws-documentation-mcp-server" version: "latest" binary: "awslabs.aws-documentation-mcp-server" - name: "gitea-mcp" kind: "go" module: "gitea.com/gitea/gitea-mcp" version: "latest" binary: "gitea-mcp" linux_dev_station_opencode_extra_environment: GITEA_MCP_HOST: "https://code.alexpires.me" GITEA_APP_TOKEN: "{{ lookup('env', 'GITEA_APP_TOKEN', default='') }}" linux_dev_station_opencode_config: "$schema": "https://opencode.ai/config.json" provider: alexpires-me: name: "alexpires.me" npm: "@ai-sdk/openai-compatible" options: baseURL: "https://llm.lab.alexpires.me/api/v1" apiKey: "{{ lookup('env', 'OPEN_WEBUI_API_KEY', default='') }}" timeout: 3000000 chunkTimeout: 3000000 models: qwen3-6-27b-mtp-q4-0: name: "qwen3-6-27b-mtp-q4-0" qwen3-6-35b-a3b-mtp-ud-q4-m: name: "qwen3-6-35b-a3b-mtp-ud-q4-m" scaleway: name: "scaleway" npm: "@ai-sdk/openai-compatible" options: baseURL: "https://api.scaleway.ai/{{ lookup('env', 'SCW_DEFAULT_ORGANIZATION_ID', default='') }}/v1" apiKey: "{{ lookup('env', 'SCW_INFERENCE_API_KEY', default='') }}" mcp: deepwiki: type: "remote" url: "https://mcp.deepwiki.com/mcp" enabled: true terraform: type: "remote" url: "http://terraform-mcp.lab.alexpires.me/mcp" enabled: true opentofu: type: "remote" url: "https://mcp.opentofu.org/mcp" enabled: true microsoft_learn: type: "remote" url: "https://learn.microsoft.com/api/mcp" enabled: true mozilla_developer: type: "remote" url: "https://mcp.mdn.mozilla.net/" enabled: true chrome_devtools: type: "local" command: - "npx" - "-y" - "chrome-devtools-mcp@latest" - "--headless" - "--isolated" enabled: true playwright: type: "local" command: - "npx" - "-y" - "@playwright/mcp@latest" - "--headless" - "--isolated" enabled: true aws_documentation: type: "local" command: - "uvx" - "awslabs.aws-documentation-mcp-server@latest" enabled: true gitea: type: "local" command: - "gitea-mcp" - "-t" - "stdio" - "-H" - "{env:GITEA_MCP_HOST}" - "-T" - "{env:GITEA_APP_TOKEN}" enabled: true compaction: auto: true prune: true reserved: 32768 linux_dev_station_service_user_ssh_enabled: true linux_dev_station_service_user_ssh_authorized_keys: [] # Bind services to localhost (nginx handles TLS+auth) linux_dev_station_code_server_bind_to_localhost: true linux_dev_station_opencode_bind_to_localhost: true # nginx_proxy: TLS + OAuth2/OIDC SSO nginx_proxy_certbot_email: "admin@alexpires.me" nginx_proxy_oauth2_proxy_enabled: true nginx_proxy_oauth2_proxy_provider: "oidc" nginx_proxy_oauth2_proxy_provider_url: "https://code.alexpires.me" nginx_proxy_oauth2_proxy_cookie_domain: ".lab.alexpires.me" nginx_proxy_oauth2_proxy_redirect_urls: - "https://ide.lab.alexpires.me/oauth2/callback" - "https://agent.lab.alexpires.me/oauth2/callback" nginx_proxy_oauth2_proxy_email_domains: - "*" nginx_proxy_oauth2_proxy_cookie_secret: "{{ lookup('env', 'OAUTH2_PROXY_COOKIE_SECRET', default='') }}" nginx_proxy_oauth2_proxy_client_id: "{{ lookup('env', 'OAUTH2_PROXY_CLIENT_ID', default='') }}" nginx_proxy_oauth2_proxy_client_secret: "{{ lookup('env', 'OAUTH2_PROXY_CLIENT_SECRET', default='') }}" nginx_proxy_sites: - name: ide server_name: "ide.lab.alexpires.me" upstream: host: "127.0.0.1" port: "{{ linux_dev_station_code_server_port }}" websocket: true - name: agent server_name: "agent.lab.alexpires.me" upstream: host: "127.0.0.1" port: "{{ linux_dev_station_opencode_server_port }}" websocket: true # Firewall ports ufw_enable: true fw_allowed_ports: - { rule: "allow", port: "22", proto: "tcp", from: "10.19.4.0/24" } # SSH (local network) - { rule: "allow", port: "443", proto: "tcp", from: "10.19.4.0/24" } # HTTPS (nginx reverse proxy) - { rule: "allow", port: "22", proto: "tcp", from: "10.5.5.0/24" } # SSH (VPN devices) - { rule: "allow", port: "443", proto: "tcp", from: "10.5.5.0/24" } # HTTPS (VPN devices) - { rule: "allow", port: "9090", proto: "tcp", from: "10.19.4.0/24" } # Cockpit linux_dev_station_oh_my_zsh_theme: "agnoster" linux_dev_station_oh_my_zsh_plugins: - git - fzf - common-aliases - sudo - tmux - extract - colored-man-pages - history-substring-search - kubectl - ansible - aws - golang - dnf - bgnotify linux_dev_station_zshrc_extra_env: EDITOR: "nano" MANPAGER: "less -R" LESS: "-R" BW_ORGANIZATION_ID: "{{ lookup('env', 'BW_ORGANIZATION_ID', default='') }}" BW_ACCESS_TOKEN: "{{ lookup('env', 'BW_ACCESS_TOKEN', default='') }}" ANSIBLE_USER: "{{ lookup('env', 'ANSIBLE_USER', default='') }}"