commit 9d7c62684f6f42b6f78512bb1d6e692dd53b59ed Author: ge Date: Sun Sep 15 14:12:48 2024 +0300 init diff --git a/README.md b/README.md new file mode 100644 index 0000000..ca058e0 --- /dev/null +++ b/README.md @@ -0,0 +1,25 @@ +# Ansible playbooks to setup servers + +## Requirements + +``` +ansible-galaxy install -r requirements.yml +``` + +## Roles + +Basic server setup: + +- `hostname` Set hostname, FQDN. +- `tz` Set TZ `Europe/Moscow`. +- `locale` Generate and set locale `en_US.utf-8`. +- `packages` Install admin tools e.g. vim, tree, etc. +- `dotfiles` Add dotfiles for root and /etc/skel. +- `motd` Modify MOTD. +- `ufw` Enable UFW, allow OpenSSH rule. +- `sshd` Disable SSH authentication via passwords. + +Other: + +- `avahi` Install and configure Avahi daemon for mDNS. +- `docker` Install Docker Engine. diff --git a/ansible.cfg b/ansible.cfg new file mode 100644 index 0000000..18429f2 --- /dev/null +++ b/ansible.cfg @@ -0,0 +1,4 @@ +[defaults] +host_key_checking = false +inventory = ./inventory.yaml +roles_path = ./roles/ diff --git a/inventory.yaml b/inventory.yaml new file mode 100644 index 0000000..10fada7 --- /dev/null +++ b/inventory.yaml @@ -0,0 +1,35 @@ +all: + vars: + architectures: + x86_64: amd64 + aarch64: arm64 + armv7l: armhf + children: + external: + hosts: + mainframe: + server_hostname: mainframe + server_fqdn: mainframe.phreepunk.network + ansible_host: 147.45.233.134 + ansible_user: root + ansible_ssh_private_key_file: /home/ge/.ssh/id_ed25519 + internal: + hosts: + opipcplus: + server_hostname: opipcplus + server_fqdn: opipcplus.local + ansible_host: 192.168.3.8 + ansible_user: root + ansible_ssh_private_key_file: /home/ge/.ssh/id_ed25519 + opi3b: + server_hostname: opi3b + server_fqdn: opi3b.local + ansible_host: 192.168.3.6 + ansible_user: root + ansible_ssh_private_key_file: /home/ge/.ssh/id_ed25519 + pnx: + server_hostname: pnx + server_fqdn: pnx.local + ansible_host: 192.168.3.128 + ansible_user: root + ansible_ssh_private_key_file: /home/ge/.ssh/id_ed25519 diff --git a/playbooks/base.yaml b/playbooks/base.yaml new file mode 100644 index 0000000..ddd6883 --- /dev/null +++ b/playbooks/base.yaml @@ -0,0 +1,8 @@ +- hosts: all + roles: + - hostname + - tz + - locale + - motd + - dotfiles + - packages diff --git a/playbooks/external.yaml b/playbooks/external.yaml new file mode 100644 index 0000000..f68dbbb --- /dev/null +++ b/playbooks/external.yaml @@ -0,0 +1,6 @@ +- hosts: external + roles: + - sshd + - ufw + - role: docker + when: server_hostname in ['mainframe'] diff --git a/playbooks/internal.yaml b/playbooks/internal.yaml new file mode 100644 index 0000000..7d1eed8 --- /dev/null +++ b/playbooks/internal.yaml @@ -0,0 +1,5 @@ +- hosts: internal + roles: + - avahi + - role: docker + when: server_hostname != 'pnx' diff --git a/playbooks/master.yaml b/playbooks/master.yaml new file mode 100644 index 0000000..05146be --- /dev/null +++ b/playbooks/master.yaml @@ -0,0 +1,3 @@ +- import_playbook: base.yaml +- import_playbook: internal.yaml +- import_playbook: external.yaml diff --git a/requirements.yaml b/requirements.yaml new file mode 100644 index 0000000..aeaf735 --- /dev/null +++ b/requirements.yaml @@ -0,0 +1,2 @@ +collections: +- name: community.general diff --git a/roles/avahi/files/nsswitch.conf b/roles/avahi/files/nsswitch.conf new file mode 100644 index 0000000..d7b860c --- /dev/null +++ b/roles/avahi/files/nsswitch.conf @@ -0,0 +1,13 @@ +# Ansible managed + +passwd: files +group: files +shadow: files +gshadow: files +hosts: files mdns4_minimal [NOTFOUND=return] dns +networks: files +protocols: db files +services: db files +ethers: db files +rpc: db files +netgroup: nis diff --git a/roles/avahi/handlers/main.yaml b/roles/avahi/handlers/main.yaml new file mode 100644 index 0000000..fd9f6ab --- /dev/null +++ b/roles/avahi/handlers/main.yaml @@ -0,0 +1,9 @@ +- name: Restart Avahi Daemon + ansible.builtin.service: + name: avahi-daemon + state: restarted + +- name: Autoremove and autoclean packages + ansible.builtin.apt: + autoremove: yes + autoclean: yes diff --git a/roles/avahi/tasks/main.yaml b/roles/avahi/tasks/main.yaml new file mode 100644 index 0000000..492a05f --- /dev/null +++ b/roles/avahi/tasks/main.yaml @@ -0,0 +1,30 @@ +- name: Populate service facts + ansible.builtin.service_facts: + +- name: Stop and disable systemd-resolved + ansible.builtin.systemd: + name: systemd-resolved + state: stopped + enabled: false + when: "'systemd-resolved' in services" + +- name: Install Avahi Daemon and helpers + ansible.builtin.apt: + name: "{{ item }}" + state: latest + update_cache: yes + install_recommends: no + with_items: + - avahi-daemon + - avahi-utils + - libnss-mdns + notify: Autoremove and autoclean packages + +- name: Configure /etc/nsswitch.conf + ansible.builtin.copy: + src: nsswitch.conf + dest: /etc/nsswitch.conf + owner: root + group: root + mode: 0644 + notify: Restart Avahi Daemon diff --git a/roles/docker/handlers/main.yaml b/roles/docker/handlers/main.yaml new file mode 100644 index 0000000..e56c07b --- /dev/null +++ b/roles/docker/handlers/main.yaml @@ -0,0 +1,4 @@ +- name: Autoremove and autoclean packages + ansible.builtin.apt: + autoremove: yes + autoclean: yes diff --git a/roles/docker/tasks/main.yaml b/roles/docker/tasks/main.yaml new file mode 100644 index 0000000..3e37524 --- /dev/null +++ b/roles/docker/tasks/main.yaml @@ -0,0 +1,46 @@ +- name: Check and install prerequisites + ansible.builtin.apt: + name: "{{ item }}" + state: latest + update_cache: yes + install_recommends: no + with_items: + - ca-certificates + - curl + - gnupg + - lsb-release + +- name: Add Docker repository + block: + - name: Make APT keyrings dir + ansible.builtin.file: + path: /etc/apt/keyrings + state: directory + owner: root + group: root + mode: 0755 + + - name: Add Docker APT key + ansible.builtin.get_url: + url: "https://download.docker.com/linux/debian/gpg" + dest: /etc/apt/keyrings/docker.asc + + - name: Add Docker APT list + ansible.builtin.apt_repository: + repo: "deb [arch={{ architectures[ansible_architecture] }} signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian {{ ansible_distribution_release }} stable" + filename: docker + state: present + +- name: Install Docker Engine + ansible.builtin.apt: + name: "{{ item }}" + state: latest + update_cache: yes + install_recommends: no + with_items: + - docker-ce + - docker-ce-cli + - containerd.io + - docker-buildx-plugin + - docker-compose-plugin + notify: Autoremove and autoclean packages diff --git a/roles/dotfiles/files/dot.bash_profile b/roles/dotfiles/files/dot.bash_profile new file mode 100644 index 0000000..cb4c4d1 --- /dev/null +++ b/roles/dotfiles/files/dot.bash_profile @@ -0,0 +1,3 @@ +# Ansible managed + +[ -f ~/.bashrc ] && . ~/.bashrc diff --git a/roles/dotfiles/files/dot.bashrc b/roles/dotfiles/files/dot.bashrc new file mode 100644 index 0000000..fe7d2a9 --- /dev/null +++ b/roles/dotfiles/files/dot.bashrc @@ -0,0 +1,31 @@ +# Ansible managed + +[ -f ~/.profile ] && . ~/.profile + +[ -f ~/.profile.extra ] && . ~/.profile.extra + +alias grep='grep --color=auto' +alias diff='diff --color=auto' +alias ls='ls -F --color=auto' +alias l='ls -hl' +alias ll='ls -alh' +alias tree='tree -F' +alias qq='history -c; exit' + +shopt -s autocd +shopt -s histappend + +HISTCONTROL=ignoreboth +HISTSIZE=20000 +HISTFILESIZE=20000 +HISTTIMEFORMAT="%d %b %Y %T %z " + +if [ "$EUID" -eq 0 ]; then + if [ -f /etc/armbian-release ]; then + PS1='\[\033[38;5;208;1m\]\u@\H\[\033[00m\]:\w\[\033[00m\]\$ ' + else + PS1='\[\033[1m\]\u@\H\[\033[00m\]:\w\[\033[00m\]\$ ' + fi +else + PS1='\u@\H:\w\$ ' +fi diff --git a/roles/dotfiles/files/dot.profile b/roles/dotfiles/files/dot.profile new file mode 100644 index 0000000..bb5d322 --- /dev/null +++ b/roles/dotfiles/files/dot.profile @@ -0,0 +1,7 @@ +# Ansible managed + +PATH=$HOME/.local/bin:$PATH +EDITOR=vim +VISUAL=vim +LESS=-R +export PATH EDITOR VISUAL LESS diff --git a/roles/dotfiles/files/dot.screenrc b/roles/dotfiles/files/dot.screenrc new file mode 100644 index 0000000..0e940a9 --- /dev/null +++ b/roles/dotfiles/files/dot.screenrc @@ -0,0 +1,5 @@ +# Ansible managed + +startup_message off +hardstatus alwayslastline +hardstatus string '%S: %-w%>(%n %t)%{-}%+w%<' diff --git a/roles/dotfiles/files/dot.vimrc b/roles/dotfiles/files/dot.vimrc new file mode 100644 index 0000000..833ef7b --- /dev/null +++ b/roles/dotfiles/files/dot.vimrc @@ -0,0 +1,20 @@ +" Ansible managed + +colorscheme default +filetype plugin on +syntax on +let python_highlight_all = 1 +set mouse-=a +set tabstop=4 +set shiftwidth=4 +set smarttab +set expandtab +set softtabstop=4 +set autoindent +set listchars=tab:▸\ ,trail:· +set list +set t_Co=256 +set enc=utf-8 +set fenc=utf-8 +set termencoding=utf-8 +set modeline diff --git a/roles/dotfiles/tasks/main.yaml b/roles/dotfiles/tasks/main.yaml new file mode 100644 index 0000000..c2ac0fe --- /dev/null +++ b/roles/dotfiles/tasks/main.yaml @@ -0,0 +1,26 @@ +- name: Copy dotfiles + ansible.builtin.copy: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + owner: root + group: root + mode: 0644 + with_items: + - { src: 'dot.vimrc', dest: '/etc/skel/.vimrc' } + - { src: 'dot.screenrc', dest: '/etc/skel/.screenrc' } + - { src: 'dot.profile', dest: '/etc/skel/.profile' } + - { src: 'dot.bashrc', dest: '/etc/skel/.bashrc' } + - { src: 'dot.bash_profile', dest: '/etc/skel/.bash_profile' } + - { src: 'dot.vimrc', dest: '/root/.vimrc' } + - { src: 'dot.screenrc', dest: '/root/.screenrc' } + - { src: 'dot.profile', dest: '/root/.profile' } + - { src: 'dot.bashrc', dest: '/root/.bashrc' } + - { src: 'dot.bash_profile', dest: '/root/.bash_profile' } + +- name: Remove unwanted dotfiles + ansible.builtin.file: + path: "{{ item }}" + state: absent + with_items: + - /etc/skel/.bash_logout + - /root/resize.log diff --git a/roles/hostname/tasks/main.yaml b/roles/hostname/tasks/main.yaml new file mode 100644 index 0000000..5d8cf50 --- /dev/null +++ b/roles/hostname/tasks/main.yaml @@ -0,0 +1,23 @@ +- name: Set a hostname via hostnamectl + ansible.builtin.hostname: + name: "{{ server_hostname }}" + use: systemd + when: ansible_virtualization_type == "kvm" or + ansible_virtualization_type == "openstack" or + ansible_virtualization_type == "NA" + +- name: Set a hostname and FQDN in /etc/hosts + ansible.builtin.template: + src: hosts + dest: /etc/hosts + owner: root + group: root + mode: 0644 + +- name: Set a hostname in /etc/hostname + ansible.builtin.template: + src: hostname + dest: /etc/hostname + owner: root + group: root + mode: 0644 diff --git a/roles/hostname/templates/hostname b/roles/hostname/templates/hostname new file mode 100644 index 0000000..0d911df --- /dev/null +++ b/roles/hostname/templates/hostname @@ -0,0 +1 @@ +{{ server_hostname }} diff --git a/roles/hostname/templates/hosts b/roles/hostname/templates/hosts new file mode 100644 index 0000000..758334e --- /dev/null +++ b/roles/hostname/templates/hosts @@ -0,0 +1,10 @@ +# Ansible managed + +127.0.0.1 localhost +::1 localhost6 +127.0.0.1 {{ server_fqdn }} {{ server_hostname }} +::1 localhost ip6-localhost ip6-loopback +fe00::0 ip6-localnet +ff02::1 ip6-allnodes +ff02::2 ip6-allrouters +ff02::3 ip6-allhosts diff --git a/roles/locale/tasks/main.yaml b/roles/locale/tasks/main.yaml new file mode 100644 index 0000000..e8a5335 --- /dev/null +++ b/roles/locale/tasks/main.yaml @@ -0,0 +1,8 @@ +- name: Generate en_US.UTF-8 locale + community.general.locale_gen: + name: en_US.UTF-8 + state: present + +- name: Set en_US.UTF-8 as default locale + ansible.builtin.command: localectl set-locale LANG=en_US.utf8 + when: ansible_env.LANG != "en_US.utf8" diff --git a/roles/motd/files/motd.cube b/roles/motd/files/motd.cube new file mode 100644 index 0000000..4734f6a --- /dev/null +++ b/roles/motd/files/motd.cube @@ -0,0 +1,9 @@ + + +------+. + |`. | `. + | `+--+---+ + | | | | + +---+--+. | + `. | `.| + `+------+ + diff --git a/roles/motd/files/motd.orangepi b/roles/motd/files/motd.orangepi new file mode 100644 index 0000000..33071d9 --- /dev/null +++ b/roles/motd/files/motd.orangepi @@ -0,0 +1,8 @@ + ____ + _\\/_/_ + / ____ \ + / /\ | /\ \ + | |-|+|-| | + \ \/_|_\/ / + \_______/ + diff --git a/roles/motd/tasks/main.yaml b/roles/motd/tasks/main.yaml new file mode 100644 index 0000000..97dec89 --- /dev/null +++ b/roles/motd/tasks/main.yaml @@ -0,0 +1,39 @@ +- name: Find unwanted motd scripts + ansible.builtin.find: + paths: /etc/update-motd.d/ + file_type: any + register: collected_files + +- name: Delete unwanted motd scripts + ansible.builtin.file: + path: "{{ item.path }}" + state: absent + with_items: "{{ collected_files.files }}" + +- name: Remove Debian legal notice (/etc/motd) + ansible.builtin.file: + path: /etc/motd + state: absent + +- name: Detect Armbian + ansible.builtin.stat: + path: /etc/armbian-release + register: armbian + +- name: Add custom /etc/motd for Armbian + ansible.builtin.copy: + src: motd.orangepi + dest: /etc/motd + owner: root + group: root + mode: 0755 + when: armbian.stat.exists == True + +- name: Add common custom /etc/motd + ansible.builtin.copy: + src: motd.cube + dest: /etc/motd + owner: root + group: root + mode: 0755 + when: armbian.stat.exists == False diff --git a/roles/packages/handlers/main.yaml b/roles/packages/handlers/main.yaml new file mode 100644 index 0000000..e56c07b --- /dev/null +++ b/roles/packages/handlers/main.yaml @@ -0,0 +1,4 @@ +- name: Autoremove and autoclean packages + ansible.builtin.apt: + autoremove: yes + autoclean: yes diff --git a/roles/packages/tasks/main.yaml b/roles/packages/tasks/main.yaml new file mode 100644 index 0000000..a85b712 --- /dev/null +++ b/roles/packages/tasks/main.yaml @@ -0,0 +1,35 @@ +- name: Install base packages + ansible.builtin.apt: + name: "{{ item }}" + state: latest + update_cache: yes + install_recommends: no + with_items: + - cron + - logrotate + - dmidecode + - lshw + - sysstat + - iotop + - iftop + - inetutils-telnet + - inetutils-ping + - inetutils-ftp + - ethtool + - tcpdump + - mtr + - curl + - wget + - rsync + - psmisc + - screen + - vim + - file + - tree + - plocate + - findutils + - diffutils + - git + - htop + - unzip + notify: Autoremove and autoclean packages diff --git a/roles/sshd/files/sshd_config b/roles/sshd/files/sshd_config new file mode 100644 index 0000000..c39e921 --- /dev/null +++ b/roles/sshd/files/sshd_config @@ -0,0 +1,11 @@ +# Ansible managed + +Include /etc/ssh/sshd_config.d/*.conf +PermitRootLogin yes +PasswordAuthentication no +ChallengeResponseAuthentication no +UsePAM yes +X11Forwarding yes +PrintMotd no +AcceptEnv LANG LC_* +Subsystem sftp /usr/lib/openssh/sftp-server diff --git a/roles/sshd/handlers/main.yaml b/roles/sshd/handlers/main.yaml new file mode 100644 index 0000000..439395a --- /dev/null +++ b/roles/sshd/handlers/main.yaml @@ -0,0 +1,4 @@ +- name: Restart sshd + ansible.builtin.service: + name: sshd + state: restarted diff --git a/roles/sshd/tasks/main.yaml b/roles/sshd/tasks/main.yaml new file mode 100644 index 0000000..3a044b7 --- /dev/null +++ b/roles/sshd/tasks/main.yaml @@ -0,0 +1,8 @@ +- name: Update sshd_config + ansible.builtin.copy: + src: sshd_config + dest: /etc/ssh/sshd_config + owner: root + group: root + mode: 0644 + notify: Restart sshd diff --git a/roles/tz/handlers/main.yaml b/roles/tz/handlers/main.yaml new file mode 100644 index 0000000..70c3ce3 --- /dev/null +++ b/roles/tz/handlers/main.yaml @@ -0,0 +1,4 @@ +- name: Restart Cron + ansible.builtin.service: + name: cron + state: restarted diff --git a/roles/tz/tasks/main.yaml b/roles/tz/tasks/main.yaml new file mode 100644 index 0000000..254030e --- /dev/null +++ b/roles/tz/tasks/main.yaml @@ -0,0 +1,4 @@ +- name: Set timezone to Europe/Moscow + community.general.timezone: + name: Europe/Moscow + notify: Restart Cron diff --git a/roles/ufw/tasks/main.yaml b/roles/ufw/tasks/main.yaml new file mode 100644 index 0000000..1e6d81d --- /dev/null +++ b/roles/ufw/tasks/main.yaml @@ -0,0 +1,14 @@ +- name: Install UFW + ansible.builtin.apt: + name: ufw + state: latest + update_cache: yes + +- name: Allow SSH + community.general.ufw: + rule: allow + name: OpenSSH + +- name: Enable Firewall + community.general.ufw: + state: enabled