diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 0000000..27b1e99 --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,31 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : +Vagrant.configure("2") do |config| + config.vm.box = "bento/ubuntu-24.04" + config.vm.box_version = "202404.26.0" + + # Configure VM provider resources (optional) + config.vm.provider :virtualbox do |v| + v.memory = 4096 + v.cpus = 2 + end + + + config.vm.define "test" do |v| + v.vm.hostname = "test" + v.vm.network :private_network, ip: "192.168.56.123" + + v.vm.provision "bootstrap", type: "shell" do |s| + s.inline = "sudo apt install ansible -y" + end + # + # Use Ansible for provisioning + v.vm.provision "ansible" do |ansible| + ansible.playbook = "playbook.yml" # Path to the Ansible playbook relative to the Vagrantfile + ansible.inventory_path = "inventory" # Path to the inventory file + # Extra vars can be defined if needed + # ansible.extra_vars = { some_var: "value" } + end + + end +end diff --git a/inventory/production b/inventory/production index ad976af..935bad2 100644 --- a/inventory/production +++ b/inventory/production @@ -51,5 +51,8 @@ docker-host[00:02] [docker_lb] docker-lb +[local] +localhost ansible_connection=local + [vm:vars] ansible_ssh_common_args='-o ProxyCommand="ssh -p 22 -W %h:%p -q aya01"' diff --git a/inventory/test b/inventory/test new file mode 100644 index 0000000..ecd25f6 --- /dev/null +++ b/inventory/test @@ -0,0 +1,2 @@ +[local] +test ansible_connection=local ansible_become_pass=vagrant diff --git a/playbooks/ubuntu.yml b/playbooks/ubuntu.yml new file mode 100644 index 0000000..142e56b --- /dev/null +++ b/playbooks/ubuntu.yml @@ -0,0 +1,5 @@ +- name: Provision Local Ubuntu Machine + hosts: local + gather_facts: true + roles: + - ubuntu diff --git a/roles/ubuntu/tasks/apt.yml b/roles/ubuntu/tasks/apt.yml new file mode 100644 index 0000000..01bb0e8 --- /dev/null +++ b/roles/ubuntu/tasks/apt.yml @@ -0,0 +1,16 @@ +--- +- name: Install dependencies + ansible.builtin.apt: + name: "{{ apt_dependencies }}" + state: present + update_cache: true + become: true + +- name: Install tools + ansible.builtin.apt: + name: "{{ apt_tools }}" + state: present + become: true + +- name: Update tldr database + ansible.builtin.command: tldr --update diff --git a/roles/ubuntu/tasks/atuin.yml b/roles/ubuntu/tasks/atuin.yml new file mode 100644 index 0000000..e51a2ea --- /dev/null +++ b/roles/ubuntu/tasks/atuin.yml @@ -0,0 +1,5 @@ +--- +- name: Install atuin + ansible.builtin.shell: yes | bash -c "curl --proto '=https' --tlsv1.2 -LsSf https://setup.atuin.sh" + args: + creates: "{{ ansible_env.HOME }}/.config/atuin" # Adjust based on atuin installation diff --git a/roles/ubuntu/tasks/docker.yml b/roles/ubuntu/tasks/docker.yml new file mode 100644 index 0000000..4582136 --- /dev/null +++ b/roles/ubuntu/tasks/docker.yml @@ -0,0 +1,51 @@ +--- +- name: Update cache + ansible.builtin.apt: + update_cache: true + become: true + +- name: Install dependencies for apt to use repositories over HTTPS + ansible.builtin.apt: + name: + - ca-certificates + - curl + - gnupg + - lsb-release + state: present + become: true + +- name: Add Docker apt key. + ansible.builtin.get_url: + url: "{{ docker.url }}/{{ ansible_distribution | lower }}/gpg" + dest: /etc/apt/trusted.gpg.d/docker.asc + mode: "0664" + force: true + become: true + +- name: Add Docker repository. + ansible.builtin.apt_repository: + repo: "deb [arch={{ aarch }}] {{ docker.url }}/{{ ansible_distribution | lower }} {{ ansible_distribution_release }} {{ docker.apt_release_channel }}" + state: present + become: true + +- name: Update cache + ansible.builtin.apt: + update_cache: true + become: true + +- name: Install Docker Engine, containerd, and Docker Compose. + ansible.builtin.apt: + name: + - docker-ce + - docker-ce-cli + - docker-compose-plugin + - containerd.io + state: present + become: true + +- name: Add current user to docker group + ansible.builtin.user: + name: "{{ ansible_user_id }}" + groups: docker + append: true + become: true diff --git a/roles/ubuntu/tasks/eurkey.yml b/roles/ubuntu/tasks/eurkey.yml new file mode 100644 index 0000000..166b3a0 --- /dev/null +++ b/roles/ubuntu/tasks/eurkey.yml @@ -0,0 +1,16 @@ +--- +- name: Download EurKey deb + ansible.builtin.get_url: + url: https://eurkey.steffen.bruentjen.eu/download/debian/eurkey.deb + dest: "/tmp/eurkey.deb" + +- name: Install EurKey + ansible.builtin.apt: + deb: "/tmp/eurkey.deb" + state: present + become: true + +- name: Remove EurKey deb + ansible.builtin.file: + path: "/tmp/eurkey.deb" + state: absent diff --git a/roles/ubuntu/tasks/fira_code_fonts.yml b/roles/ubuntu/tasks/fira_code_fonts.yml new file mode 100644 index 0000000..87e9a84 --- /dev/null +++ b/roles/ubuntu/tasks/fira_code_fonts.yml @@ -0,0 +1,25 @@ +--- +- name: Create fonts directory + ansible.builtin.file: + path: "{{ ansible_env.HOME }}/.fonts" + state: directory + mode: "0755" + +- name: Download FiraCode Nerd Font zip + ansible.builtin.get_url: + url: https://github.com/ryanoasis/nerd-fonts/releases/download/v3.3.0/FiraMono.zip + dest: "/tmp/FiraMono.zip" + +- name: Extract FiraCode from zip + ansible.builtin.unarchive: + src: "/tmp/FiraMono.zip" + dest: "{{ ansible_env.HOME }}/.fonts" + remote_src: true + +- name: Remove FiraMono.zip + ansible.builtin.file: + path: "/tmp/FiraMono.zip" + state: absent + +- name: Refresh font cache + ansible.builtin.shell: fc-cache -fv diff --git a/roles/ubuntu/tasks/ghostty.yml b/roles/ubuntu/tasks/ghostty.yml new file mode 100644 index 0000000..f1f47a5 --- /dev/null +++ b/roles/ubuntu/tasks/ghostty.yml @@ -0,0 +1,31 @@ +--- +- name: Get OS release info + ansible.builtin.shell: source /etc/os-release && echo $VERSION_ID + args: + executable: /bin/bash + register: version_id + changed_when: false + +- name: Get Ghostty DEB URL + ansible.builtin.shell: | + curl -s https://api.github.com/repos/mkasberg/ghostty-ubuntu/releases/latest | + grep -oP "https://github.com/mkasberg/ghostty-ubuntu/releases/download/[^\s/]+/ghostty_[^\s/_]+_{{ aarch }}_{{ version_id.stdout }}.deb" + register: ghostty_deb_url + changed_when: false + +- name: Download Ghostty deb file + ansible.builtin.get_url: + url: "{{ ghostty_deb_url.stdout }}" + dest: "/tmp/{{ ghostty_deb_url.stdout | basename }}" + mode: "0755" + +- name: Install Ghostty + ansible.builtin.apt: + deb: "/tmp/{{ ghostty_deb_url.stdout | basename }}" + state: present + become: true + +- name: Remove Ghostty deb file + ansible.builtin.file: + path: "/tmp/{{ ghostty_deb_url.stdout | basename }}" + state: absent diff --git a/roles/ubuntu/tasks/git_delta.yml b/roles/ubuntu/tasks/git_delta.yml new file mode 100644 index 0000000..80ab0e9 --- /dev/null +++ b/roles/ubuntu/tasks/git_delta.yml @@ -0,0 +1,16 @@ +--- +- name: Download git-delta deb + ansible.builtin.get_url: + url: "https://github.com/dandavison/delta/releases/download/0.18.2/git-delta-musl_0.18.2_{{ aarch }}.deb" + dest: "/tmp/git-delta-musl_0.18.2_{{ aarch }}.deb" + +- name: Install git-delta + ansible.builtin.apt: + deb: "/tmp/git-delta-musl_0.18.2_{{ aarch }}.deb" + state: present + become: true + +- name: Remove git-delta deb + ansible.builtin.file: + path: "/tmp/git-delta-musl_0.18.2_{{ aarch }}.deb" + state: absent diff --git a/roles/ubuntu/tasks/hashicorp_vagrant.yml b/roles/ubuntu/tasks/hashicorp_vagrant.yml new file mode 100644 index 0000000..be70214 --- /dev/null +++ b/roles/ubuntu/tasks/hashicorp_vagrant.yml @@ -0,0 +1,45 @@ +--- +- name: Download Hashicorp GPG key + ansible.builtin.get_url: + url: https://apt.releases.hashicorp.com/gpg + dest: /tmp/hashicorp_gpg + mode: "0644" + register: hashicorp_gpg_download + +- name: Dearmor Hashicorp GPG key + ansible.builtin.command: + cmd: gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg /tmp/hashicorp_gpg + args: + creates: /usr/share/keyrings/hashicorp-archive-keyring.gpg + when: hashicorp_gpg_download.changed + become: true + +- name: Remove temporary Hashicorp GPG key file + ansible.builtin.file: + path: /tmp/hashicorp_gpg + state: absent + when: hashicorp_gpg_download.changed + +- name: Add Hashicorp APT repository + ansible.builtin.apt_repository: + repo: "deb [arch={{ ansible_architecture }} signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com {{ ansible_lsb.codename }} main" + filename: hashicorp + state: present + vars: + ansible_lsb: + codename: "{{ ansible_facts['lsb']['codename'] }}" + ansible_architecture: "{{ ansible_facts['architecture'] }}" + when: hashicorp_gpg_download.changed + become: true + +- name: Update apt cache after adding Hashicorp repository + ansible.builtin.apt: + update_cache: true + cache_valid_time: 3600 # Cache validity in seconds + become: true + +- name: Install Vagrant + ansible.builtin.apt: + name: vagrant + state: present + become: true diff --git a/roles/ubuntu/tasks/lazygit.yml b/roles/ubuntu/tasks/lazygit.yml new file mode 100644 index 0000000..7f2d681 --- /dev/null +++ b/roles/ubuntu/tasks/lazygit.yml @@ -0,0 +1,34 @@ +--- +- name: Get latest lazygit version + ansible.builtin.shell: | + curl -s "https://api.github.com/repos/jesseduffield/lazygit/releases/latest" | + grep -Po '"tag_name": *"v\K[^"]*' + register: lazygit_version + changed_when: false + +- name: Download lazygit tar.gz + ansible.builtin.get_url: + url: "https://github.com/jesseduffield/lazygit/releases/download/v{{ lazygit_version.stdout }}/lazygit_{{ lazygit_version.stdout }}_Linux_x86_64.tar.gz" + dest: "/tmp/lazygit.tar.gz" + +- name: Extract lazygit binary + ansible.builtin.unarchive: + src: "/tmp/lazygit.tar.gz" + dest: "/tmp" + creates: "/tmp/lazygit" + remote_src: true + +- name: Install lazygit + ansible.builtin.copy: + src: "/tmp/lazygit" + dest: /usr/local/bin/lazygit + mode: "0755" + become: true + +- name: Remove lazygit tar.gz and binary + ansible.builtin.file: + path: "{{ item }}" + state: absent + loop: + - "/tmp/lazygit.tar.gz" + - "/tmp/lazygit" diff --git a/roles/ubuntu/tasks/ledger_cli.yml b/roles/ubuntu/tasks/ledger_cli.yml new file mode 100644 index 0000000..e451147 --- /dev/null +++ b/roles/ubuntu/tasks/ledger_cli.yml @@ -0,0 +1,40 @@ +--- +- name: Clone Ledger repository + ansible.builtin.git: + repo: "{{ ledger_repo }}" + dest: "{{ ledger_clone_dir }}" + version: master + update: true + register: git_clone + become: true + +- name: Run acprep update to configure and build Ledger + ansible.builtin.command: ./acprep update + args: + chdir: "{{ ledger_clone_dir }}" + when: git_clone.changed + become: true + +- name: Move the built ledger binary to /usr/bin + ansible.builtin.copy: + src: "{{ ledger_clone_dir }}/ledger" + dest: "{{ ledger_binary_path }}" + mode: "0755" + force: true + become: true + +- name: Ensure the ledger binary is executable + ansible.builtin.file: + path: "{{ ledger_binary_path }}" + mode: "0755" + state: file + become: true + +- name: Verify Ledger installation + ansible.builtin.command: ledger --version + register: ledger_version + changed_when: false + +- name: Display Ledger version + ansible.builtin.debug: + msg: "Ledger version installed: {{ ledger_version.stdout }}" diff --git a/roles/ubuntu/tasks/main.yml b/roles/ubuntu/tasks/main.yml new file mode 100644 index 0000000..f059a8b --- /dev/null +++ b/roles/ubuntu/tasks/main.yml @@ -0,0 +1,39 @@ +--- +- name: Install apt packages + ansible.builtin.import_tasks: apt.yml +- name: Install snap packages + ansible.builtin.import_tasks: snap.yml +- name: Install nvim + ansible.builtin.import_tasks: nvim.yml +- name: Install Rust + ansible.builtin.import_tasks: rust.yml +- name: Ghostty + ansible.builtin.import_tasks: ghostty.yml +- name: Install pacstall + ansible.builtin.import_tasks: pacstall.yml +- name: Install ledger + ansible.builtin.import_tasks: ledger_cli.yml +- name: Install git-delta + ansible.builtin.import_tasks: git_delta.yml +- name: Install atuin + ansible.builtin.import_tasks: atuin.yml +- name: Install Starship + ansible.builtin.import_tasks: starship.yml +- name: Install EurKey + ansible.builtin.import_tasks: eurkey.yml +# - name: Install Veracrypt +# ansible.builtin.import_tasks: veracrypt.yml +- name: Install FiraCode + ansible.builtin.import_tasks: fira_code_fonts.yml +- name: Remove Ubuntu Pro Banner + ansible.builtin.import_tasks: remove_ubuntu_banner.yml +- name: Install ProtonVPN + ansible.builtin.import_tasks: protonvpn.yml +- name: Install Docker + ansible.builtin.import_tasks: docker.yml +- name: Install lazygit + ansible.builtin.import_tasks: lazygit.yml +- name: Install ripgrep + ansible.builtin.import_tasks: ripgrep.yml +- name: Install Vagrant + ansible.builtin.import_tasks: hashicorp_vagrant.yml diff --git a/roles/ubuntu/tasks/nvim.yml b/roles/ubuntu/tasks/nvim.yml new file mode 100644 index 0000000..8c94a23 --- /dev/null +++ b/roles/ubuntu/tasks/nvim.yml @@ -0,0 +1,25 @@ +--- +- name: Check if Neovim config directory already exists + ansible.builtin.stat: + path: "{{ nvim_config_path }}" + register: nvim_config + +- name: Clone LazyVim starter to Neovim config directory + ansible.builtin.git: + repo: https://github.com/LazyVim/starter + dest: "{{ nvim_config_path }}" + clone: true + update: false + when: not nvim_config.stat.exists + +- name: Remove .git directory from Neovim config + ansible.builtin.file: + path: "{{ nvim_config_path }}/.git" + state: absent + when: not nvim_config.stat.exists + +- name: Install neovim npm package globally + community.general.npm: + name: neovim + global: true + become: true diff --git a/roles/ubuntu/tasks/pacstall.yml b/roles/ubuntu/tasks/pacstall.yml new file mode 100644 index 0000000..8e8eb1f --- /dev/null +++ b/roles/ubuntu/tasks/pacstall.yml @@ -0,0 +1,6 @@ +--- +- name: Install Pacstall + ansible.builtin.shell: yes | bash -c "$(curl -fsSL https://pacstall.dev/q/install)" + args: + creates: /usr/local/bin/pacstall # Adjust based on pacstall install path + become: true diff --git a/roles/ubuntu/tasks/protonvpn.yml b/roles/ubuntu/tasks/protonvpn.yml new file mode 100644 index 0000000..41e9dad --- /dev/null +++ b/roles/ubuntu/tasks/protonvpn.yml @@ -0,0 +1,36 @@ +--- +- name: Download ProtonVPN release deb + ansible.builtin.get_url: + url: https://repo.protonvpn.com/debian/dists/stable/main/binary-all/protonvpn-stable-release_1.0.6_all.deb + dest: "/tmp/protonvpn-stable-release_1.0.6_all.deb" + +- name: Verify ProtonVPN deb checksum + ansible.builtin.shell: echo "e5e03976d0980bafdf07da2f71b14fbc883c091e72b16772199742c98473002f /tmp/protonvpn-stable-release_1.0.6_all.deb" | sha256sum --check - + register: checksum_result + failed_when: "'FAILED' in checksum_result.stdout" + +- name: Install ProtonVPN release package + ansible.builtin.apt: + deb: "/tmp/protonvpn-stable-release_1.0.6_all.deb" + state: present + become: true + +- name: Update apt cache after ProtonVPN repo added + ansible.builtin.apt: + update_cache: true + become: true + +- name: Install ProtonVPN GNOME desktop + ansible.builtin.apt: + name: + - proton-vpn-gnome-desktop + - libayatana-appindicator3-1 + - gir1.2-ayatanaappindicator3-0.1 + - gnome-shell-extension-appindicator + state: present + become: true + +- name: Remove ProtonVPN release deb + ansible.builtin.file: + path: "/tmp/protonvpn-stable-release_1.0.6_all.deb" + state: absent diff --git a/roles/ubuntu/tasks/remove_ubuntu_banner.yml b/roles/ubuntu/tasks/remove_ubuntu_banner.yml new file mode 100644 index 0000000..3bfa32d --- /dev/null +++ b/roles/ubuntu/tasks/remove_ubuntu_banner.yml @@ -0,0 +1,17 @@ +--- +- name: Backup Ubuntu Pro banner configuration + ansible.builtin.command: mv /etc/apt/apt.conf.d/20apt-esm-hook.conf /etc/apt/apt.conf.d/20apt-esm-hook.conf.bak + args: + removes: /etc/apt/apt.conf.d/20apt-esm-hook.conf + become: true + +- name: Create empty Ubuntu Pro banner configuration + ansible.builtin.file: + path: /etc/apt/apt.conf.d/20apt-esm-hook.conf + state: touch + become: true + +- name: Update apt cache + ansible.builtin.apt: + update_cache: true + become: true diff --git a/roles/ubuntu/tasks/ripgrep.yml b/roles/ubuntu/tasks/ripgrep.yml new file mode 100644 index 0000000..0df907f --- /dev/null +++ b/roles/ubuntu/tasks/ripgrep.yml @@ -0,0 +1,15 @@ +- name: Download ripgrep deb + ansible.builtin.get_url: + url: https://github.com/BurntSushi/ripgrep/releases/download/14.1.0/ripgrep_14.1.0-1_{{ aarch }}.deb + dest: "/tmp/ripgrep_14.1.0-1_{{ aarch }}.deb" + +- name: Install ripgrep + ansible.builtin.apt: + deb: "/tmp/ripgrep_14.1.0-1_{{ aarch }}.deb" + state: present + become: true + +- name: Remove ripgrep deb + ansible.builtin.file: + path: "/tmp/ripgrep_14.1.0-1_{{ aarch }}.deb" + state: absent diff --git a/roles/ubuntu/tasks/rust.yml b/roles/ubuntu/tasks/rust.yml new file mode 100644 index 0000000..0b693e3 --- /dev/null +++ b/roles/ubuntu/tasks/rust.yml @@ -0,0 +1,11 @@ +--- +- name: Install Rust (via rustup) + ansible.builtin.shell: yes | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs + args: + creates: "{{ ansible_env.HOME }}/.cargo/bin/rustc" + +- name: Install bininstall + ansible.builtin.shell: yes | curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh + +- name: Install bininstall + ansible.builtin.shell: yes | cargo binstall dioxus-cli diff --git a/roles/ubuntu/tasks/snap.yml b/roles/ubuntu/tasks/snap.yml new file mode 100644 index 0000000..c8be03f --- /dev/null +++ b/roles/ubuntu/tasks/snap.yml @@ -0,0 +1,8 @@ +--- +- name: Install snap packages + community.general.snap: + name: "{{ item.name }}" + classic: "{{ item.classic }}" + state: present + become: true + loop: "{{ snap_tools }}" diff --git a/roles/ubuntu/tasks/starship.yml b/roles/ubuntu/tasks/starship.yml new file mode 100644 index 0000000..74465fe --- /dev/null +++ b/roles/ubuntu/tasks/starship.yml @@ -0,0 +1,5 @@ +--- +- name: Install starship + ansible.builtin.shell: yes | bash -c "curl -sS https://starship.rs/install.sh" + args: + creates: "{{ ansible_env.HOME }}/.config/starship.toml" # Adjust based on where starship installs diff --git a/roles/ubuntu/tasks/veracrypt.yml b/roles/ubuntu/tasks/veracrypt.yml new file mode 100644 index 0000000..9162464 --- /dev/null +++ b/roles/ubuntu/tasks/veracrypt.yml @@ -0,0 +1,16 @@ +--- +- name: Download Veracrypt deb + ansible.builtin.get_url: + url: "https://launchpad.net/veracrypt/trunk/1.26.20/+download/veracrypt-1.26.20-Debian-12-{{ aarch }}.deb" + dest: "/tmp/veracrypt.deb" + +- name: Install Veracrypt + ansible.builtin.apt: + deb: "/tmp/veracrypt.deb" + state: present + become: true + +- name: Remove Veracrypt deb + ansible.builtin.file: + path: "/tmp/veracrypt.deb" + state: absent diff --git a/roles/ubuntu/vars/main.yml b/roles/ubuntu/vars/main.yml new file mode 100644 index 0000000..31e3a9b --- /dev/null +++ b/roles/ubuntu/vars/main.yml @@ -0,0 +1,86 @@ +apt_dependencies: + - ansible + - bat + - build-essential + - cmake + - curl + - doxygen + - eza + - fd-find + - file + - fzf + - gcc + - gettext + - git + - libarchive-tools + - libayatana-appindicator3-dev + - libboost-date-time-dev + - libboost-dev + - libboost-filesystem-dev + - libboost-iostreams-dev + - libboost-python-dev + - libboost-regex-dev + - libboost-system-dev + - libboost-test-dev + - libclang-dev + - libedit-dev + - libgmp3-dev + - libmpfr-dev + - librsvg2-dev + - libssl-dev + - libwebkit2gtk-4.1-dev + - libxdo-dev + - luarocks + - npm + - python3-dev + - python3-ipykernel + - python3-pip + - python3-venv + - texinfo + - tzdata + - v4l2loopback-dkms + - wget + - xsel + +apt_tools: + - keepassxc + - obs-studio + - p7zip + - pkg-config + - ranger + - tealdeer + - texlive-full + - virtualbox + - wireguard-tools + - yt-dlp + - zsh + +snap_tools: + - name: "bottom" + classic: false + - name: "winbox" + classic: false + - name: "signal-desktop" + classic: false + - name: "nvim" + classic: true + - name: "zellij" + classic: true + - name: "jupyterlab-desktop" + classic: true + - name: "intellij-idea-community" + classic: true + - name: "dive" + classic: false + +nvim_config_path: "~/.config/nvim" + +ledger_repo: "https://github.com/ledger/ledger.git" +ledger_clone_dir: "/opt/ledger" +ledger_binary_path: "/usr/bin/ledger" + +docker: + url: "https://download.docker.com/linux" + apt_release_channel: "stable" + +aarch: "{{ 'arm64' if ansible_architecture == 'aarch64' else 'amd64' }}"