Compare commits
71 Commits
main
..
development
| Author | SHA256 | Date | |
|---|---|---|---|
| 8d40ddc636 | |||
| 5706fc9854 | |||
| 5e0d333c7b | |||
| 76d0fe843a | |||
| 8c9a79c07a | |||
| f0dbaef0e4 | |||
| 01e471ec0f | |||
| 6cdfecfd8d | |||
| 4665903b01 | |||
| a935e484d9 | |||
| 2fa109335f | |||
| f9ee2fcc05 | |||
| 316e6018fc | |||
| ed627fbd19 | |||
| 7859a609eb | |||
| fad2891925 | |||
| 1e8f162672 | |||
| 90de36e0b2 | |||
| bfe44f6b17 | |||
| 331b2ba504 | |||
| 26142f24b0 | |||
| 97b4169bdc | |||
| b8792fc523 | |||
| 1a0d1e5d0b | |||
| 8b50cacb1b | |||
| e1592fca85 | |||
| 456ee502ee | |||
| 4fe4ca317a | |||
| 4f86f4c114 | |||
| bcd45cff9e | |||
| 0e820b49f9 | |||
| 9b213b81e9 | |||
| 761137317a | |||
| 43ded2bdca | |||
| bb65f915a7 | |||
| 94fc56674f | |||
| 9518826ea4 | |||
| e34628f838 | |||
| c3d3c59611 | |||
| 9c63ca61a0 | |||
| 839a136393 | |||
| fa41c94b49 | |||
| 347962126e | |||
| 4154b5297a | |||
| 0429125819 | |||
| 28e9fbd9b9 | |||
| dfc6aa5cb3 | |||
| 86b8a2e06d | |||
| 2bf8241293 | |||
| 303608172f | |||
| 31eac61575 | |||
| db6669f9a9 | |||
| effd8336cd | |||
| 246737d212 | |||
| aff550d586 | |||
| 716ac04c4f | |||
| 438c4d2100 | |||
| 36369f1ad6 | |||
| f4f2b96d1a | |||
| 9f1db4076f | |||
| da8db08d78 | |||
| f2661aaf02 | |||
| 44766173bd | |||
| c5b8ada835 | |||
| b25e844c0a | |||
| dc490c1613 | |||
| c2dcfa2996 | |||
| 16e3a9cbe2 | |||
| 117821b738 | |||
| 0e3f78b695 | |||
| ba750bed89 |
+1
-1
@@ -1,4 +1,4 @@
|
||||
# ---> Ansible
|
||||
*.retry
|
||||
EXAMPLES
|
||||
|
||||
roles
|
||||
|
||||
@@ -0,0 +1,219 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
####
|
||||
#### WARNING:
|
||||
####
|
||||
#### bootstrap.sh and bootstrap.yml should be updated together. They should do the
|
||||
#### exact same things with the following exceptions:
|
||||
####
|
||||
#### * bootstrap.sh
|
||||
#### - at the end it should run ansible-pull.sh against bootstrap.yml
|
||||
####
|
||||
#### * bootstrap.yml
|
||||
#### - at the end it should configure cron to schedule ansible-pull.sh
|
||||
####
|
||||
#### !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
#### ! Make sure to keep them in sync !
|
||||
#### !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
####
|
||||
|
||||
|
||||
#
|
||||
#### VARIABLES
|
||||
#
|
||||
|
||||
TIMESTAMP="$(date "+%Y%m%d%H%M%S")"
|
||||
|
||||
GIT_REPO_BASE="https://gitea.admin-a.hpetersenfamily.com/heath/ansible"
|
||||
GIT_REPO_BRANCH="${1:-"development"}"
|
||||
|
||||
GIT_REPO_FILES="${GIT_REPO_BASE}/raw/branch/${GIT_REPO_BRANCH}/files"
|
||||
|
||||
GIT_REPO_sudoers_d_hpf="${GIT_REPO_FILES}/etc/sudoers.d/hpf"
|
||||
GIT_REPO_SKEL_ansible_venv_sh="${GIT_REPO_FILES}/etc/skel/.profile.d/ansible-venv.sh"
|
||||
GIT_REPO_SKEL_profile="${GIT_REPO_FILES}/etc/skel/.profile"
|
||||
GIT_REPO_ansible_pull_sh="${GIT_REPO_FILES}/home/hpf-ans/bin/ansible-pull.sh"
|
||||
|
||||
ETC_sudoers_d="/etc/sudoers.d"
|
||||
ETC_sudoers_d_hpf="${ETC_sudoers_d}/hpf"
|
||||
|
||||
unset SKEL
|
||||
if [ -r /etc/default/useradd ] ; then . /etc/default/useradd ; fi
|
||||
SKEL="${SKEL:-/etc/skel}"
|
||||
SKEL_profile_d="${SKEL}/.profile.d"
|
||||
SKEL_ansible_venv_sh="${SKEL_profile_d}/ansible-venv.sh"
|
||||
SKEL_profile="${SKEL}/.profile"
|
||||
|
||||
ANSIBLE_PULL_SH_LOG_DIR="/var/log/ansible-pull.sh"
|
||||
|
||||
|
||||
#
|
||||
#### FUNCTIONS
|
||||
#
|
||||
|
||||
# $group_name $group_number
|
||||
group_exists () {
|
||||
grep -q "^$1:[^:]*:$2:" /etc/group
|
||||
}
|
||||
|
||||
# $user_name $user_number
|
||||
user_exists () {
|
||||
grep -q "^$1:[^:]*:$2:$2:" /etc/passwd
|
||||
}
|
||||
|
||||
# $group_name $group_number
|
||||
system_groupadd () {
|
||||
if group_exists "$1" "$2" ; then return 0 ; fi
|
||||
groupadd -r -g "$2" "$1"
|
||||
rc=$?
|
||||
if [ $rc -ne 0 ] ; then
|
||||
echo "ERROR - Unable to add $1 group! ($rc)" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# $user_name $user_number
|
||||
system_useradd () {
|
||||
if user_exists "$1" "$2" ; then return 0 ; fi
|
||||
system_groupadd "${@}"
|
||||
useradd -r -u "$2" -g "$2" -s /usr/bin/bash -m "$1"
|
||||
rc=$?
|
||||
if [ $rc -ne 0 ] ; then
|
||||
echo "ERROR - Unable to add $1 user! ($rc)" >&2
|
||||
exit 2
|
||||
fi
|
||||
}
|
||||
|
||||
# $groups $user_name
|
||||
add_groups_to_user () {
|
||||
usermod -aG "$1" "$2"
|
||||
rc=$?
|
||||
if [ $rc -ne 0 ] ; then
|
||||
echo "ERROR - Unable to add groups ($1) to user ($2)! ($rc)" >&2
|
||||
exit 3
|
||||
fi
|
||||
}
|
||||
|
||||
# $source_file $dest_file $dest_file_ownership $dest_file_permissions
|
||||
get_file() {
|
||||
local source_file dest_file dest_file_ownership dest_file_permissions
|
||||
|
||||
source_file="${1}"
|
||||
dest_file="${2}"
|
||||
dest_file_ownership="${3}"
|
||||
dest_file_permissions="${4}"
|
||||
|
||||
if [ -e "${dest_file}" ] ; then mv "${dest_file}" "${dest_file}.${TIMESTAMP}" ; fi
|
||||
if ! curl -f -o "${dest_file}" "${source_file}" ; then
|
||||
echo "ERROR - Unable to download \"${source_file}\"" >&2
|
||||
echo " to \"${dest_file}\"." >&2
|
||||
exit 4
|
||||
fi
|
||||
if ! chown "${dest_file_ownership}" "${dest_file}" ; then
|
||||
echo "ERROR - Unable to change ownership of \"${dest_file}\" to \"${dest_file_ownership}\"" >&2
|
||||
exit 4
|
||||
fi
|
||||
if ! chmod "${dest_file_permissions}" "${dest_file}" ; then
|
||||
echo "ERROR - Unable to change permissions of \"${dest_file}\" to \"${dest_file_permissions}\"" >&2
|
||||
exit 4
|
||||
fi
|
||||
}
|
||||
|
||||
# $directory $directory_ownership $directory_permissions
|
||||
create_directory() {
|
||||
local directory directory_ownership directory_permissions
|
||||
|
||||
directory="${1}"
|
||||
directory_ownership="${2}"
|
||||
directory_permissions="${3}"
|
||||
|
||||
if ! mkdir -p "${directory}" ; then
|
||||
echo "ERROR - Unable to create directory \"${directory}\"" >&2
|
||||
exit 5
|
||||
fi
|
||||
if ! chown "${directory_ownership}" "${directory}" ; then
|
||||
echo "ERROR - Unable to change ownership of \"${directory}\" to \"${directory_ownership}\"" >&2
|
||||
exit 5
|
||||
fi
|
||||
if ! chmod "${directory_permissions}" "${directory}" ; then
|
||||
echo "ERROR - Unable to change permissions of \"${directory}\" to \"${directory_permissions}\"" >&2
|
||||
exit 5
|
||||
fi
|
||||
}
|
||||
|
||||
# $command_line
|
||||
as_hpf_ans () {
|
||||
su --login hpf-ans --command "${1}"
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
#### PROCESS
|
||||
#
|
||||
|
||||
# Make sure we're running as root
|
||||
if [ "$(id -u)" -ne 0 ] ; then
|
||||
echo "ERROR - Not running as root" >&2
|
||||
exit 100
|
||||
fi
|
||||
|
||||
# Install minimal necessary packages
|
||||
if which -s apt ; then
|
||||
apt update
|
||||
apt install bash curl python3 python3-pip python3-venv python3-virtualenv -y
|
||||
else
|
||||
echo "ERROR - Unable to determine how to install packages" >&2
|
||||
exit 101
|
||||
fi
|
||||
|
||||
# Create system group hpf-sudo for normal sudo users
|
||||
system_groupadd hpf-sudo 700
|
||||
|
||||
# Create system group hpf-sudo-np for special sudo users that don't require a password
|
||||
system_groupadd hpf-sudo-np 701
|
||||
|
||||
# Make sure /etc/sudoers.d exists
|
||||
create_directory "${ETC_sudoers_d}" "root:root" "u=rwx,go="
|
||||
|
||||
# Get /etc/sudoers.d/hpf
|
||||
get_file "${GIT_REPO_sudoers_d_hpf}" "${ETC_sudoers_d_hpf}" "root:root" "u=rw,go="
|
||||
|
||||
# Make sure /etc/skel/.profile.d exists
|
||||
create_directory "${SKEL_profile_d}" "root:root" "u=rwx,go="
|
||||
|
||||
# Get /etc/skel/.profile.d/ansible-venv.sh
|
||||
get_file "${GIT_REPO_SKEL_ansible_venv_sh}" "${SKEL_ansible_venv_sh}" "root:root" "u=rw,go="
|
||||
|
||||
# Get /etc/skel/.profile
|
||||
get_file "${GIT_REPO_SKEL_profile}" "${SKEL_profile}" "root:root" "u=rw,go="
|
||||
|
||||
# Create the hpf-ans user
|
||||
system_useradd hpf-ans 800
|
||||
add_groups_to_user hpf-sudo-np hpf-ans
|
||||
|
||||
# Set HPF_ANS variables now that the user is created
|
||||
HPF_ANS_HOME="$(as_hpf_ans 'echo "${HOME}"')"
|
||||
HPF_ANS_ansible_venv="${HPF_ANS_HOME}/.ansible-venv"
|
||||
HPF_ANS_bin="${HPF_ANS_HOME}/bin"
|
||||
HPF_ANS_ansible_pull_sh="${HPF_ANS_bin}/ansible-pull.sh"
|
||||
|
||||
# Make sure /home/hpf-ans/.ansible-venv exists
|
||||
as_hpf_ans "if [ ! -d \"${HPF_ANS_ansible_venv}\" ] ; then virtualenv \"${HPF_ANS_ansible_venv}\" ; fi"
|
||||
|
||||
# Make sure pip is up to date
|
||||
as_hpf_ans "pip install --upgrade pip"
|
||||
|
||||
# Make sure ansible is up to date
|
||||
as_hpf_ans "pip install --upgrade ansible"
|
||||
|
||||
# Make sure /home/hpf-ans/bin exists
|
||||
create_directory "${HPF_ANS_bin}" "hpf-ans:hpf-ans" "u=rwx,go="
|
||||
|
||||
# Get /home/hpf-ans/bin/ansible-pull.sh
|
||||
get_file "${GIT_REPO_ansible_pull_sh}" "${HPF_ANS_ansible_pull_sh}" "hpf-ans:hpf-ans" "u=rwx,go="
|
||||
|
||||
# Make sure log directory exists
|
||||
create_directory "${ANSIBLE_PULL_SH_LOG_DIR}" "hpf-ans:root" "u=rwx,go="
|
||||
|
||||
# Run ansible-pull to finish up
|
||||
#as_hpf_ans "$HPF_ANS_ansible_pull_sh --branch ${GIT_REPO_BRANCH} bootstrap.yml"
|
||||
@@ -1,6 +1,7 @@
|
||||
[defaults]
|
||||
|
||||
inventory = ./inventory
|
||||
roles_path = ./roles
|
||||
|
||||
remote_user = hpf-ans
|
||||
host_key_checking = False
|
||||
@@ -10,6 +11,8 @@ timeout = 30
|
||||
stdout_callback = default
|
||||
callback_result_format = yaml
|
||||
|
||||
interpreter_python = auto_silent
|
||||
|
||||
#[privilege_escalation]
|
||||
#become = True
|
||||
#become_method = sudo
|
||||
|
||||
-153
@@ -1,153 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
####
|
||||
#### WARNING:
|
||||
####
|
||||
#### bootstrap.sh and bootstrap.yml should be updated together. They should do the
|
||||
#### exact same things with the following exceptions:
|
||||
####
|
||||
#### * bootstrap.sh
|
||||
#### - at the end it should run ansible-pull.sh against bootstrap.yml
|
||||
####
|
||||
#### * bootstrap.yml
|
||||
#### - at the end it should configure cron to schedule ansible-pull.sh
|
||||
####
|
||||
#### !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
#### ! Make sure to keep them in sync !
|
||||
#### !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
####
|
||||
|
||||
|
||||
#
|
||||
#### VARIABLES
|
||||
#
|
||||
|
||||
GIT_REPO_BASE="https://gitea.admin-a.hpetersenfamily.com/heath/ansible"
|
||||
GIT_REPO="${GIT_REPO_BASE}.git"
|
||||
GIT_REPO_sudoers_d_hpf="${GIT_REPO_BASE}/raw/branch/main/files/etc_sudoers_d_hpf"
|
||||
GIT_REPO_ansible_pull_sh="${GIT_REPO_BASE}/raw/branch/main/files/home_hpf_ans_bin_ansible_pull_sh"
|
||||
|
||||
|
||||
ETC_sudoers_d_hpf="/etc/sudoers.d/hpf"
|
||||
|
||||
HPF_ANS_ansible_venv="\${HOME}/.ansible-venv"
|
||||
HPF_ANS_activate="${HPF_ANS_ansible_venv}/bin/activate"
|
||||
|
||||
HPF_ANS_bin="\${HOME}/bin"
|
||||
HPF_ANS_ansible_pull_sh="${HPF_ANS_bin}/ansible-pull.sh"
|
||||
|
||||
ANSIBLE_PULL_SH_LOG_DIR="/var/log/ansible-pull.sh"
|
||||
|
||||
|
||||
#
|
||||
#### FUNCTIONS
|
||||
#
|
||||
|
||||
# $group_name $group_number
|
||||
group_exists () {
|
||||
grep -q "^$1:[^:]*:$2:" /etc/group
|
||||
}
|
||||
|
||||
# $user_name $user_number
|
||||
user_exists () {
|
||||
grep -q "^$1:[^:]*:$2:$2:" /etc/passwd
|
||||
}
|
||||
|
||||
# $group_name $group_number
|
||||
system_groupadd () {
|
||||
if group_exists "$1" "$2" ; then return 0 ; fi
|
||||
groupadd -r -g "$2" "$1"
|
||||
rc=$?
|
||||
if [ $rc -ne 0 ] ; then
|
||||
echo "ERROR - Unable to add $1 group! ($rc)" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# $user_name $user_number
|
||||
system_useradd () {
|
||||
if user_exists "$1" "$2" ; then return 0 ; fi
|
||||
system_groupadd "${@}"
|
||||
useradd -r -u "$2" -g "$2" -s /bin/bash -m "$1"
|
||||
rc=$?
|
||||
if [ $rc -ne 0 ] ; then
|
||||
echo "ERROR - Unable to add $1 user! ($rc)" >&2
|
||||
exit 2
|
||||
fi
|
||||
}
|
||||
|
||||
# $groups $user_name
|
||||
add_groups_to_user () {
|
||||
usermod -aG "$1" "$2"
|
||||
rc=$?
|
||||
if [ $rc -ne 0 ] ; then
|
||||
echo "ERROR - Unable to add groups ($1) to user ($2)! ($rc)" >&2
|
||||
exit 3
|
||||
fi
|
||||
}
|
||||
|
||||
# $command_line
|
||||
as_hpf_ans () {
|
||||
su --login hpf-ans -c "if [ -r \"${HPF_ANS_activate}\" ] ; then source \"${HPF_ANS_activate}\" ; fi ; ${1}"
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
#### PROCESS
|
||||
#
|
||||
|
||||
# Make sure we're running as root
|
||||
if [ $(id -u) -ne 0 ] ; then
|
||||
echo "ERROR - Not running as root!" >&2
|
||||
exit 100
|
||||
fi
|
||||
|
||||
# Install minimal necessary packages
|
||||
if which -s apt ; then
|
||||
apt update
|
||||
apt install bash curl python3 python3-pip python3-venv python3-virtualenv -y
|
||||
else
|
||||
echo "ERROR - Unable to determine how to install packages" >&2
|
||||
exit 101
|
||||
fi
|
||||
|
||||
# Create system group hpf-sudo for normal sudo users
|
||||
system_groupadd hpf-sudo 700
|
||||
|
||||
# Create system group hpf-sudo-np for special sudo users that don't require a password
|
||||
system_groupadd hpf-sudo-np 701
|
||||
|
||||
# Create /etc/sudoers.d/hpf to allow common sudo permissions
|
||||
rm "${ETC_sudoers_d_hpf}" 2>/dev/null
|
||||
curl -o "$ETC_sudoers_d_hpf" "${GIT_REPO_sudoers_d_hpf}"
|
||||
chown root:root "${ETC_sudoers_d_hpf}"
|
||||
chmod u=rw,go= "${ETC_sudoers_d_hpf}"
|
||||
|
||||
# Create the hpf-ans user
|
||||
system_useradd hpf-ans 800
|
||||
add_groups_to_user hpf-sudo-np hpf-ans
|
||||
|
||||
# Make sure .ansible-venv exists
|
||||
as_hpf_ans "if [ ! -d \"${HPF_ANS_ansible_venv}\" ] ; then virtualenv \"${HPF_ANS_ansible_venv}\" ; fi"
|
||||
|
||||
# Make sure pip is up to date
|
||||
as_hpf_ans "pip install --upgrade pip"
|
||||
|
||||
# Make sure ansible is installed
|
||||
as_hpf_ans "pip install --upgrade ansible"
|
||||
|
||||
# Make sure bin exists
|
||||
as_hpf_ans "mkdir -p \"${HPF_ANS_bin}\""
|
||||
as_hpf_ans "chown hpf-ans:hpf-ans \"${HPF_ANS_bin}\"; chmod u=rwx,go= \"${HPF_ANS_bin}\""
|
||||
|
||||
# Create ~hpf-ans/bin/ansible-pull.sh
|
||||
as_hpf_ans "rm \"${HPF_ANS_ansible_pull_sh}\" 2>/dev/null"
|
||||
as_hpf_ans "curl -o \"${HPF_ANS_ansible_pull_sh}\" \"${GIT_REPO_ansible_pull_sh}\""
|
||||
as_hpf_ans "chown hpf-ans:hpf-ans \"${HPF_ANS_ansible_pull_sh}\"; chmod u=rwx,go= \"${HPF_ANS_ansible_pull_sh}\""
|
||||
|
||||
# Make sure log directory exists
|
||||
mkdir -p "${ANSIBLE_PULL_SH_LOG_DIR}"
|
||||
chown hpf-ans:root "${ANSIBLE_PULL_SH_LOG_DIR}"; chmod ug=rwx,o= "${ANSIBLE_PULL_SH_LOG_DIR}"
|
||||
|
||||
# Run ansible-pull to finish up
|
||||
as_hpf_ans "bin/ansible-pull.sh bootstrap.yml"
|
||||
+271
-115
@@ -1,131 +1,287 @@
|
||||
---
|
||||
|
||||
####
|
||||
#### WARNING:
|
||||
####
|
||||
#### bootstrap.sh and bootstrap.yml should be updated together. They should do the
|
||||
#### exact same things with the following exceptions:
|
||||
####
|
||||
#### * bootstrap.sh
|
||||
#### - at the end it should run ansible-pull.sh against bootstrap.yml
|
||||
####
|
||||
#### * bootstrap.yml
|
||||
#### - at the end it should configure cron to schedule ansible-pull.sh
|
||||
####
|
||||
#### !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
#### ! Make sure to keep them in sync !
|
||||
#### !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
####
|
||||
|
||||
|
||||
# Update software repositories here
|
||||
# Change the following to work with multiple distros
|
||||
|
||||
- name: bootstrap
|
||||
- name: Bootstrap playbook
|
||||
hosts: all
|
||||
become: yes
|
||||
|
||||
tasks:
|
||||
|
||||
- name: Install bootstrap packages
|
||||
ansible.builtin.apt:
|
||||
state: latest
|
||||
pkg:
|
||||
- bash
|
||||
- curl
|
||||
- python3
|
||||
- python3-pip
|
||||
- python3-venv
|
||||
- python3-virtualenv
|
||||
|
||||
- name: Make sure hpf-sudo group exists
|
||||
ansible.builtin.group:
|
||||
name: hpf-sudo
|
||||
state: present
|
||||
system: true
|
||||
gid: 700
|
||||
#### System Software
|
||||
|
||||
- name: Make sure hpf-sudo-np group exists
|
||||
ansible.builtin.group:
|
||||
name: hpf-sudo-np
|
||||
state: present
|
||||
system: true
|
||||
gid: 701
|
||||
- name: Update repositories
|
||||
become: true
|
||||
ansible.builtin.apt:
|
||||
update_cache: true
|
||||
|
||||
- name: Copy over /etc/sudoers.d/hpf
|
||||
ansible.builtin.copy:
|
||||
src: etc_sudoers_d_hpf
|
||||
dest: /etc/sudoers.d/hpf
|
||||
owner: root
|
||||
group: root
|
||||
mode: u=rw,go=
|
||||
backup: true
|
||||
validate: /usr/sbin/visudo -csf %s
|
||||
- name: Install bootstrap packages
|
||||
become: true
|
||||
ansible.builtin.apt:
|
||||
state: present
|
||||
pkg:
|
||||
- bash
|
||||
- python3
|
||||
- python3-pip
|
||||
- python3-venv
|
||||
- python3-virtualenv
|
||||
- logrotate
|
||||
|
||||
- name: Make sure hpf-ans group exists
|
||||
ansible.builtin.group:
|
||||
name: hpf-ans
|
||||
state: present
|
||||
system: true
|
||||
gid: 800
|
||||
|
||||
- name: Make sure hpf-ans user exists
|
||||
ansible.builtin.user:
|
||||
name: hpf-ans
|
||||
state: present
|
||||
system: true
|
||||
uid: 800
|
||||
group: hpf-ans
|
||||
groups: hpf-sudo-np
|
||||
append: yes
|
||||
create_home: true
|
||||
shell: /bin/bash
|
||||
#### Configure sudo
|
||||
|
||||
- name: Install latest version of pip in .ansible-venv
|
||||
ansible.builtin.pip:
|
||||
name: pip
|
||||
virtualenv: $HOME/.ansible-venv
|
||||
extra_args: --upgrade
|
||||
become: no
|
||||
- name: Create system group hpf-sudo for normal sudo users
|
||||
become: true
|
||||
ansible.builtin.group:
|
||||
name: hpf-sudo
|
||||
state: present
|
||||
system: true
|
||||
gid: 700
|
||||
|
||||
- name: Install latest version of ansible in .ansible-venv
|
||||
ansible.builtin.pip:
|
||||
name: ansible
|
||||
virtualenv: $HOME/.ansible-venv
|
||||
extra_args: "--upgrade"
|
||||
become: no
|
||||
- name: Create system group hpf-sudo-np for special sudo users that don't require a password
|
||||
become: true
|
||||
ansible.builtin.group:
|
||||
name: hpf-sudo-np
|
||||
state: present
|
||||
system: true
|
||||
gid: 701
|
||||
|
||||
- name: Make sure bin directory exists
|
||||
ansible.builtin.file:
|
||||
path: $HOME/bin
|
||||
state: directory
|
||||
owner: hpf-ans
|
||||
group: hpf-ans
|
||||
mode: u=rwx,go=
|
||||
become: no
|
||||
- name: Get /etc/sudoers.d
|
||||
become: true
|
||||
ansible.builtin.copy:
|
||||
src: etc/sudoers.d
|
||||
dest: /etc/
|
||||
owner: root
|
||||
group: root
|
||||
directory_mode: u=rwx,go=
|
||||
mode: u=rw,g=r,o=
|
||||
backup: true
|
||||
validate: /usr/sbin/visudo -csf %s
|
||||
|
||||
- name: Copy over bin/ansible-pull.sh
|
||||
ansible.builtin.copy:
|
||||
src: home_hpf_ans_bin_ansible_pull_sh
|
||||
dest: $HOME/bin/ansible-pull.sh
|
||||
owner: hpf-ans
|
||||
group: hpf-ans
|
||||
mode: u=rwx,go=
|
||||
backup: true
|
||||
become: no
|
||||
|
||||
- name: Make sure log directory exists
|
||||
ansible.builtin.file:
|
||||
path: /var/log/ansible-pull.sh
|
||||
state: directory
|
||||
owner: hpf-ans
|
||||
group: root
|
||||
mode: ug=rwx,o=
|
||||
#### Configure sshd
|
||||
|
||||
# - name: Create ansible-pull.sh crontab entry
|
||||
# ansible.builtin.cron:
|
||||
# name: "ansible-pull"
|
||||
# minute: "*/27"
|
||||
# job: $HOME/bin/ansible-pull.sh
|
||||
# backup: true
|
||||
# become: no
|
||||
- name: Get /etc/ssh/sshd_config.d
|
||||
become: true
|
||||
ansible.builtin.copy:
|
||||
src: etc/ssh/sshd_config.d
|
||||
dest: /etc/ssh/
|
||||
owner: root
|
||||
group: root
|
||||
directory_mode: u=rwx,go=rx
|
||||
mode: u=rw,go=r
|
||||
backup: true
|
||||
validate: /usr/sbin/sshd -t -f %s
|
||||
notify: Restart sshd
|
||||
|
||||
|
||||
#### Configure /etc/skel
|
||||
|
||||
- name: Get /etc/skel
|
||||
become: true
|
||||
ansible.builtin.copy:
|
||||
src: etc/skel
|
||||
dest: /etc/
|
||||
owner: root
|
||||
group: root
|
||||
directory_mode: u=rwx,go=rx
|
||||
mode: u=rw,go=
|
||||
backup: true
|
||||
|
||||
|
||||
#### User: root
|
||||
|
||||
- name: Set root's authorized_keys
|
||||
become: true
|
||||
ansible.posix.authorized_key:
|
||||
user: root
|
||||
state: present
|
||||
key: "{{ lookup('file', item) }}"
|
||||
loop:
|
||||
- files/ssh-keys/heath.pub
|
||||
|
||||
- name: Lock the root user's password
|
||||
become: true
|
||||
ansible.builtin.user:
|
||||
name: root
|
||||
password_lock: true
|
||||
|
||||
|
||||
#### User: first
|
||||
|
||||
- name: Create the first user
|
||||
become: true
|
||||
ansible.builtin.user:
|
||||
name: first
|
||||
comment: First User
|
||||
state: present
|
||||
system: false
|
||||
groups: hpf-sudo-np
|
||||
append: true
|
||||
create_home: true
|
||||
shell: /usr/bin/bash
|
||||
|
||||
- name: Set first's authorized_keys
|
||||
become: true
|
||||
ansible.posix.authorized_key:
|
||||
user: first
|
||||
state: present
|
||||
key: "{{ lookup('file', item) }}"
|
||||
loop:
|
||||
- files/ssh-keys/first.pub
|
||||
- files/ssh-keys/heath.pub
|
||||
|
||||
|
||||
#### User: hpf-ans
|
||||
|
||||
- name: Create the hpf-ans group
|
||||
become: true
|
||||
ansible.builtin.group:
|
||||
name: hpf-ans
|
||||
state: present
|
||||
system: true
|
||||
gid: 800
|
||||
|
||||
- name: Create the hpf-ans user
|
||||
become: true
|
||||
ansible.builtin.user:
|
||||
name: hpf-ans
|
||||
state: present
|
||||
system: true
|
||||
uid: 800
|
||||
group: hpf-ans
|
||||
groups: hpf-sudo-np
|
||||
append: true
|
||||
create_home: true
|
||||
shell: /usr/bin/bash
|
||||
password_lock: true
|
||||
|
||||
- name: Get /home/hpf-ans/bin
|
||||
become: true
|
||||
become_user: hpf-ans
|
||||
ansible.builtin.copy:
|
||||
src: home/hpf-ans/bin
|
||||
dest: $HOME/
|
||||
owner: hpf-ans
|
||||
group: hpf-ans
|
||||
directory_mode: u=rwx,go=
|
||||
mode: u=rwx,go=
|
||||
backup: true
|
||||
|
||||
- name: Set hpf-ans's authorized_keys
|
||||
become: true
|
||||
ansible.posix.authorized_key:
|
||||
user: hpf-ans
|
||||
state: present
|
||||
key: "{{ lookup('file', item) }}"
|
||||
loop:
|
||||
- files/ssh-keys/heath.pub
|
||||
|
||||
- name: Make sure pip is up to date
|
||||
become: true
|
||||
become_user: hpf-ans
|
||||
ansible.builtin.pip:
|
||||
name: pip
|
||||
virtualenv: $HOME/.ansible-venv
|
||||
extra_args: --upgrade
|
||||
|
||||
- name: Make sure ansible is up to date
|
||||
become: true
|
||||
become_user: hpf-ans
|
||||
ansible.builtin.pip:
|
||||
name: ansible
|
||||
virtualenv: $HOME/.ansible-venv
|
||||
extra_args: --upgrade
|
||||
|
||||
|
||||
#### User: heath
|
||||
|
||||
- name: Create the heath group
|
||||
become: true
|
||||
ansible.builtin.group:
|
||||
name: heath
|
||||
state: present
|
||||
system: false
|
||||
gid: 60001
|
||||
|
||||
- name: Create the heath user
|
||||
become: true
|
||||
ansible.builtin.user:
|
||||
name: heath
|
||||
comment: Heath Petersen
|
||||
state: present
|
||||
system: false
|
||||
uid: 60001
|
||||
group: heath
|
||||
groups: hpf-sudo
|
||||
append: true
|
||||
create_home: true
|
||||
shell: /usr/bin/bash
|
||||
password: '$y$j9T$.NJVASBkVLnvqgznpcpdx1$7poH23pou7VHti3IfvDzwECdLtTcMercYNCeevgV.xC'
|
||||
|
||||
- name: Set heath's authorized_keys
|
||||
become: true
|
||||
ansible.posix.authorized_key:
|
||||
user: heath
|
||||
state: present
|
||||
key: "{{ lookup('file', item) }}"
|
||||
loop:
|
||||
- files/ssh-keys/heath.pub
|
||||
|
||||
|
||||
#### ansible-pull.sh
|
||||
|
||||
- name: Make sure log directory exists
|
||||
become: true
|
||||
ansible.builtin.file:
|
||||
path: /var/log/ansible-pull.sh
|
||||
state: directory
|
||||
owner: hpf-ans
|
||||
group: root
|
||||
mode: u=rwx,g=r,o=
|
||||
|
||||
# - name: Create ansible-pull.sh crontab entry
|
||||
# become: true
|
||||
# become_user: hpf-ans
|
||||
# ansible.builtin.cron:
|
||||
# name: "ansible-pull"
|
||||
# minute: "*/27"
|
||||
# job: $HOME/bin/ansible-pull.sh
|
||||
# backup: true
|
||||
|
||||
- name: Rotate ansible-pull.sh.log
|
||||
become: true
|
||||
community.general.logrotate:
|
||||
name: ansible-pull.sh
|
||||
paths:
|
||||
- /var/log/ansible-pull.sh/*.log
|
||||
rotation_period: daily
|
||||
rotate_count: 32
|
||||
compress: true
|
||||
compress_options: "-9"
|
||||
delay_compress: true
|
||||
missing_ok: true
|
||||
not_if_empty: true
|
||||
backup: true
|
||||
|
||||
|
||||
#### Clean System Software
|
||||
|
||||
- name: Remove packages installed as dependencies that are no longer required and purge their configuration files
|
||||
become: true
|
||||
ansible.builtin.apt:
|
||||
autoremove: true
|
||||
purge: true
|
||||
|
||||
- name: Remove old downloaded packages
|
||||
become: true
|
||||
ansible.builtin.apt:
|
||||
autoclean: true
|
||||
|
||||
|
||||
#### Handlers
|
||||
|
||||
handlers:
|
||||
|
||||
- name: Restart sshd
|
||||
become: true
|
||||
ansible.builtin.service:
|
||||
name: sshd
|
||||
state: restarted
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
# ~/.bashrc: executed by bash(1) for non-login shells.
|
||||
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
|
||||
# for examples
|
||||
|
||||
# If not running interactively, don't do anything
|
||||
case $- in
|
||||
*i*) ;;
|
||||
*) return;;
|
||||
esac
|
||||
|
||||
# don't put duplicate lines or lines starting with space in the history.
|
||||
# See bash(1) for more options
|
||||
HISTCONTROL=ignoreboth
|
||||
|
||||
# append to the history file, don't overwrite it
|
||||
shopt -s histappend
|
||||
|
||||
# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
|
||||
HISTSIZE=1000
|
||||
HISTFILESIZE=2000
|
||||
|
||||
# check the window size after each command and, if necessary,
|
||||
# update the values of LINES and COLUMNS.
|
||||
shopt -s checkwinsize
|
||||
|
||||
# If set, the pattern "**" used in a pathname expansion context will
|
||||
# match all files and zero or more directories and subdirectories.
|
||||
#shopt -s globstar
|
||||
|
||||
# make less more friendly for non-text input files, see lesspipe(1)
|
||||
#[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"
|
||||
|
||||
# set variable identifying the chroot you work in (used in the prompt below)
|
||||
if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then
|
||||
debian_chroot=$(cat /etc/debian_chroot)
|
||||
fi
|
||||
|
||||
# set a fancy prompt (non-color, unless we know we "want" color)
|
||||
case "$TERM" in
|
||||
xterm-color|*-256color) color_prompt=yes;;
|
||||
esac
|
||||
|
||||
# uncomment for a colored prompt, if the terminal has the capability; turned
|
||||
# off by default to not distract the user: the focus in a terminal window
|
||||
# should be on the output of commands, not on the prompt
|
||||
#force_color_prompt=yes
|
||||
|
||||
if [ -n "$force_color_prompt" ]; then
|
||||
if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
|
||||
# We have color support; assume it's compliant with Ecma-48
|
||||
# (ISO/IEC-6429). (Lack of such support is extremely rare, and such
|
||||
# a case would tend to support setf rather than setaf.)
|
||||
color_prompt=yes
|
||||
else
|
||||
color_prompt=
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$color_prompt" = yes ]; then
|
||||
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
|
||||
else
|
||||
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
|
||||
fi
|
||||
unset color_prompt force_color_prompt
|
||||
|
||||
# If this is an xterm set the title to user@host:dir
|
||||
case "$TERM" in
|
||||
xterm*|rxvt*)
|
||||
PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
|
||||
# enable color support of ls and also add handy aliases
|
||||
if [ -x /usr/bin/dircolors ]; then
|
||||
test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
|
||||
alias ls='ls --color=auto'
|
||||
#alias dir='dir --color=auto'
|
||||
#alias vdir='vdir --color=auto'
|
||||
|
||||
#alias grep='grep --color=auto'
|
||||
#alias fgrep='fgrep --color=auto'
|
||||
#alias egrep='egrep --color=auto'
|
||||
fi
|
||||
|
||||
# colored GCC warnings and errors
|
||||
#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'
|
||||
|
||||
# some more ls aliases
|
||||
#alias ll='ls -l'
|
||||
#alias la='ls -A'
|
||||
#alias l='ls -CF'
|
||||
|
||||
# Alias definitions.
|
||||
# You may want to put all your additions into a separate file like
|
||||
# ~/.bash_aliases, instead of adding them here directly.
|
||||
# See /usr/share/doc/bash-doc/examples in the bash-doc package.
|
||||
|
||||
if [ -f ~/.bash_aliases ]; then
|
||||
. ~/.bash_aliases
|
||||
fi
|
||||
|
||||
# enable programmable completion features (you don't need to enable
|
||||
# this, if it's already enabled in /etc/bash.bashrc and /etc/profile
|
||||
# sources /etc/bash.bashrc).
|
||||
if ! shopt -oq posix; then
|
||||
if [ -f /usr/share/bash-completion/bash_completion ]; then
|
||||
. /usr/share/bash-completion/bash_completion
|
||||
elif [ -f /etc/bash_completion ]; then
|
||||
. /etc/bash_completion
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -d "$HOME/.bashrc.d" ] ; then
|
||||
for bashrc_script in $HOME/.bashrc.d/*.sh ; do
|
||||
. "${bashrc_script}"
|
||||
done
|
||||
fi
|
||||
@@ -0,0 +1,33 @@
|
||||
# ~/.profile: executed by the command interpreter for login shells.
|
||||
# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login
|
||||
# exists.
|
||||
# see /usr/share/doc/bash/examples/startup-files for examples.
|
||||
# the files are located in the bash-doc package.
|
||||
|
||||
# the default umask is set in /etc/profile; for setting the umask
|
||||
# for ssh logins, install and configure the libpam-umask package.
|
||||
#umask 022
|
||||
|
||||
# if running bash
|
||||
if [ -n "$BASH_VERSION" ]; then
|
||||
# include .bashrc if it exists
|
||||
if [ -f "$HOME/.bashrc" ]; then
|
||||
. "$HOME/.bashrc"
|
||||
fi
|
||||
fi
|
||||
|
||||
# set PATH so it includes user's private bin if it exists
|
||||
if [ -d "$HOME/bin" ] ; then
|
||||
PATH="$HOME/bin:$PATH"
|
||||
fi
|
||||
|
||||
# set PATH so it includes user's private bin if it exists
|
||||
if [ -d "$HOME/.local/bin" ] ; then
|
||||
PATH="$HOME/.local/bin:$PATH"
|
||||
fi
|
||||
|
||||
if [ -d "$HOME/.profile.d" ] ; then
|
||||
for profile_script in $HOME/.profile.d/*.sh ; do
|
||||
. "${profile_script}"
|
||||
done
|
||||
fi
|
||||
@@ -0,0 +1,6 @@
|
||||
ANSIBLE_ACTIVATE="${HOME}/.ansible-venv/bin/activate"
|
||||
|
||||
if [ -r "${ANSIBLE_ACTIVATE}" ] ; then
|
||||
VIRTUAL_ENV_DISABLE_PROMPT=true
|
||||
. "${ANSIBLE_ACTIVATE}"
|
||||
fi
|
||||
@@ -0,0 +1,3 @@
|
||||
PermitRootLogin prohibit-password # Some software such as Proxmox requires key based root login
|
||||
PasswordAuthentication no
|
||||
PermitEmptyPasswords no
|
||||
@@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
if [ -r /etc/ansible-pull.sh.conf ] ; then
|
||||
. /etc/ansible-pull.sh.conf
|
||||
fi
|
||||
|
||||
SCRIPT_NAME="$(basename "${0}")"
|
||||
GIT_REPO_BRANCH="${GIT_REPO_BRANCH:-production}"
|
||||
OIC_FLAG="--only-if-changed"
|
||||
VERBOSE_FLAG="--verbose"
|
||||
DEBUG_FLAG="false"
|
||||
|
||||
# - Process command line
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
-h|--help)
|
||||
echo "Usage: $0 [--branch <branch name>] [--force] [--quiet] [-- <ansible-pull args>]"
|
||||
exit 0
|
||||
;;
|
||||
-d|--debug)
|
||||
VERBOSE_FLAG="-vvv"
|
||||
DEBUG_FLAG="true"
|
||||
shift 1
|
||||
;;
|
||||
-b|--branch)
|
||||
shift 1
|
||||
if [ $# -eq 0 ] ; then echo "${SCRIPT_NAME}: ERROR - Branch not specified." ; exit 1 ; fi
|
||||
GIT_REPO_BRANCH="$1"
|
||||
shift 1
|
||||
;;
|
||||
-f|--force)
|
||||
OIC_FLAG=""
|
||||
shift 1
|
||||
;;
|
||||
-q|--quiet)
|
||||
VERBOSE_FLAG=""
|
||||
shift 1
|
||||
;;
|
||||
--)
|
||||
shift 1
|
||||
break
|
||||
;;
|
||||
*)
|
||||
echo "${SCRIPT_NAME}: ERROR - Invalid argument '${1}'." ; exit 2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
VENV_ACTIVATE_SCRIPT="${HOME}/.ansible-venv/bin/activate"
|
||||
LOCK_FILE="/var/run/lock/ansible-pull.sh.lock"
|
||||
LOG_DIR="/var/log/ansible-pull.sh"
|
||||
LOG_FILE="${LOG_DIR}/ansible-pull.sh.log"
|
||||
GIT_REPO_BASE="https://gitea.admin-a.hpetersenfamily.com/heath/ansible"
|
||||
GIT_REPO="${GIT_REPO_BASE}.git"
|
||||
|
||||
# - Include ansible virtual environment (in case not already done - we don't know how we're being run)
|
||||
. "${VENV_ACTIVATE_SCRIPT}"
|
||||
|
||||
# - If we can't get a lock, don't proceed
|
||||
if ! exec 9>"${LOCK_FILE}" ; then
|
||||
echo "${SCRIPT_NAME}: ERROR - Unable to open the lock file (${LOCK_FILE})! Exiting..." >&2
|
||||
exit 10
|
||||
fi
|
||||
if ! flock -n 9 ; then
|
||||
echo "${SCRIPT_NAME}: ERROR - Another copy is already running! Exiting..." >&2
|
||||
exit 11
|
||||
fi
|
||||
|
||||
# - If debugging requested or running from a terminal . . .
|
||||
if [ "${DEBUG_FLAG}" = "true" ] || test -t 0 ; then
|
||||
exec > >(tee -a "${LOG_FILE}") 2>&1 # - send STDOUT and STDERR to both STDOUT and the log file
|
||||
else
|
||||
exec >>"${LOG_FILE}" 2>&1 # - send STDOUT and STDERR to the log file only
|
||||
fi
|
||||
|
||||
# - Log that we've gotten this far
|
||||
echo
|
||||
echo "${SCRIPT_NAME}: ------------------------------- $(date "+%Y-%m-%d %H:%M:%S") -------------------------------"
|
||||
|
||||
# - Do our work
|
||||
ansible-pull ${OIC_FLAG} ${VERBOSE_FLAG} --url "${GIT_REPO}" --checkout "${GIT_REPO_BRANCH}" "${@}"
|
||||
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
if [ -z "${1:-}" ] ; then
|
||||
echo "ERROR - ansible OS family unspecified." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ANSIBLE_OS_FAMILY="${1}"
|
||||
shift
|
||||
|
||||
if [ "${#}" -ne 0 ] ; then
|
||||
echo "ERROR - unknown command line parameter specified." >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
useradd_D() {
|
||||
|
||||
case "${ANSIBLE_OS_FAMILY}" in
|
||||
Debian)
|
||||
/usr/sbin/useradd -D
|
||||
;;
|
||||
RedHat)
|
||||
/usr/sbin/useradd -D
|
||||
;;
|
||||
*)
|
||||
echo "ERROR - Unknown ansible OS FAMILY \"${ANSIBLE_OS_FAMILY}\"." >&2
|
||||
exit 99
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
user_vars() {
|
||||
useradd_D | sed 's/.*=/\L&/'
|
||||
}
|
||||
|
||||
(
|
||||
user_vars
|
||||
) | jo
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# - Fix branch to check out
|
||||
|
||||
. "${HOME}/.ansible-venv/bin/activate"
|
||||
|
||||
SCRIPT_NAME="$(basename "${0}")"
|
||||
GIT_REPO_BASE="https://gitea.admin-a.hpetersenfamily.com/heath/ansible"
|
||||
GIT_REPO="${GIT_REPO_BASE}.git"
|
||||
LOG_DIR="/var/log/ansible-pull.sh"
|
||||
LOG_FILE="${LOG_DIR}/ansible-pull.sh.log"
|
||||
LOCK_FILE="/tmp/ansible-pull.sh.lock"
|
||||
|
||||
# - Redirect all further output to the log file
|
||||
exec >>"${LOG_FILE}" 2>&1
|
||||
|
||||
# - Log that we've gotten this far
|
||||
echo -n "$(basename "${0}"): $(date "+%Y-%m-%d %H:%M:%S")"
|
||||
|
||||
# - If we can't lock the lock file, don't proceed
|
||||
exec 9>"${LOCK_FILE}"
|
||||
if ! flock -n 9 ; then echo " - ERROR - Another copy of ${SCRIPT_NAME} is already running! Exiting..." ; exit 1 ; fi
|
||||
|
||||
# - Do our work
|
||||
echo
|
||||
ansible-pull --only-if-changed --url "${GIT_REPO}" --checkout main "${@}"
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJOr+lI3L/cXv31JrdPEMjrCQziBacNnLWsToetpFUCk first@hpetersenfamily.com
|
||||
@@ -0,0 +1 @@
|
||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPNOrXhub0nCmr0s8u8BK6jyJJt07rBB25PlEtzflj+y heath@hpetersenfamily.com
|
||||
@@ -0,0 +1,18 @@
|
||||
---
|
||||
- name: Configure time synchronization
|
||||
hosts: all
|
||||
become: true
|
||||
vars:
|
||||
timesync_ntp_provider: chrony
|
||||
timesync_ntp_servers:
|
||||
- hostname: 0.north-america.pool.ntp.org
|
||||
iburst: true
|
||||
- hostname: 1.north-america.pool.ntp.org
|
||||
iburst: true
|
||||
- hostname: 2.north-america.pool.ntp.org
|
||||
iburst: true
|
||||
timesync_chrony_custom_settings:
|
||||
- "logdir /var/log/chrony"
|
||||
- "log measurements statistics tracking"
|
||||
roles:
|
||||
- linux-system-roles.timesync
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
roles:
|
||||
- name: linux-system-roles.timesync
|
||||
version: 1.14.1
|
||||
@@ -0,0 +1,87 @@
|
||||
Manually on each system:
|
||||
* set hostname to fqdn
|
||||
* set ansible branch if not production
|
||||
* run bootstrap.yml
|
||||
* update first password
|
||||
|
||||
iris.heath.hpetersenfamily.com admin-a.hpetersenfamily.com core.mary.hpetersenfamily.com
|
||||
|
||||
|
||||
heath
|
||||
authorized_keys:
|
||||
- heath@hpetersenfamily.com
|
||||
password:
|
||||
status: VALID
|
||||
value: COMMON STRONG FOR ALL HOSTS
|
||||
first
|
||||
authorized_keys:
|
||||
- first@hpetersenfamily.com
|
||||
- heath@hpetersenfamily.com
|
||||
password:
|
||||
status: VALID
|
||||
value: UNIQUE LONG FOR EACH HOST
|
||||
root
|
||||
authorized_keys:
|
||||
- heath@hpetersenfamily.com
|
||||
password:
|
||||
status: LOCKED
|
||||
hpf-ans:
|
||||
authorized_keys:
|
||||
- heath@hpetersenfamily.com
|
||||
password:
|
||||
status: LOCKED
|
||||
|
||||
|
||||
# Change to work with multiple distros (nothing hardcoded)
|
||||
|
||||
* create production, development branches
|
||||
* cron job for ansible-pull
|
||||
|
||||
|
||||
|
||||
* Configure hosts
|
||||
# cat >>/etc/hosts <<-!!TheEnd!!
|
||||
::1 name.f.q.d.n name-ipv6.f.q.d.n name name-ipv6
|
||||
127.0.0.1 name.f.q.d.n name-ipv4.f.q.d.n name name-ipv4
|
||||
!!TheEnd!!
|
||||
|
||||
|
||||
##########
|
||||
########## normal tasks
|
||||
##########
|
||||
|
||||
- name: Install openssh, openssh-server, openssh-sftp-server
|
||||
ansible.builtin.apt:
|
||||
pkg:
|
||||
- openssh
|
||||
- openssh-server
|
||||
- openssh-sftp-server
|
||||
|
||||
- name: Install bash, bash-completion
|
||||
ansible.builtin.apt:
|
||||
pkg:
|
||||
- bash
|
||||
- bash-completion
|
||||
|
||||
- name: Install chrony
|
||||
ansible.builtin.apt:
|
||||
pkg:
|
||||
- chrony
|
||||
|
||||
* Configure chrony
|
||||
# cat >/etc/chrony/sources.d/hpetersenfamily-north-america.sources <<!!TheEnd!!
|
||||
pool 0.north-america.pool.ntp.org iburst
|
||||
!!TheEnd!!
|
||||
|
||||
|
||||
~heath/.gitconfig
|
||||
|
||||
fail2ban
|
||||
uptime kuma
|
||||
|
||||
==============================================================
|
||||
==============================================================
|
||||
==============================================================
|
||||
|
||||
use tags to do things like allow selecting software updates, software cleanup, etc.
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
- name: Create user
|
||||
hosts: all
|
||||
|
||||
tasks:
|
||||
|
||||
- name: Create the second user
|
||||
become: true
|
||||
ansible.builtin.user:
|
||||
name: second
|
||||
comment: second User
|
||||
state: present
|
||||
system: false
|
||||
groups: hpf-sudo-np
|
||||
append: true
|
||||
create_home: true
|
||||
shell: /usr/bin/bash
|
||||
uid: 60002
|
||||
|
||||
- name: Set second's authorized_keys
|
||||
become: true
|
||||
ansible.posix.authorized_key:
|
||||
user: second
|
||||
state: present
|
||||
key: "{{ lookup('file', item) }}"
|
||||
loop:
|
||||
- files/ssh-keys/second.pub
|
||||
- files/ssh-keys/heath.pub
|
||||
@@ -0,0 +1,257 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Serialize bash variables to JSON output
|
||||
#
|
||||
# # Created
|
||||
# Author: Dave Eddy <ysap@daveeddy.com>
|
||||
# Date: July 09, 2026
|
||||
# License: MIT
|
||||
#
|
||||
# # Contributors
|
||||
# - Dave Eddy <ysap@daveeddy.com>
|
||||
|
||||
_jv-usage() {
|
||||
local usage
|
||||
read -r -d '' usage <<-EOF
|
||||
Usage: jsonvar [-aev] [[name], ...]
|
||||
|
||||
Serialize bash variables to JSON output
|
||||
|
||||
Options
|
||||
-a show all variables
|
||||
-e show only exported variables
|
||||
-v show only the values of the variables
|
||||
-h show this message and exit
|
||||
EOF
|
||||
echo "$usage"
|
||||
}
|
||||
|
||||
_jv-json-encode-string() {
|
||||
local s=$1
|
||||
|
||||
local LC_ALL=C
|
||||
local -A table=()
|
||||
|
||||
# we can start at 1 because bash variables can't have nul bytes in them
|
||||
local hex byte esc i
|
||||
for ((i = 1; i < 0x20; i++)); do
|
||||
printf -v hex '%02x' "$i"
|
||||
|
||||
printf -v byte '%b' "\\x$hex"
|
||||
printf -v esc '\\u%04x' "$i"
|
||||
table[$byte]=$esc
|
||||
done
|
||||
|
||||
table[$'\b']='\b'
|
||||
table[$'\t']='\t'
|
||||
table[$'\n']='\n'
|
||||
table[$'\f']='\f'
|
||||
table[$'\r']='\r'
|
||||
|
||||
table['\']='\\'
|
||||
table['"']='\"'
|
||||
|
||||
# serialize the string
|
||||
local out=''
|
||||
local len=${#s}
|
||||
local c
|
||||
for ((i = 0; i < len; i++)); do
|
||||
c=${s:i:1}
|
||||
esc=${table[$c]}
|
||||
|
||||
if [[ -n $esc ]]; then
|
||||
# lookup table matched for this byte
|
||||
out+=$esc
|
||||
else
|
||||
# no lookup table match, byte falls through
|
||||
out+=$c
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
printf '"%s"' "$out"
|
||||
}
|
||||
|
||||
_jv-encode-variable() {
|
||||
local _jv_name=$1
|
||||
local -n _jv_ref=$_jv_name
|
||||
local _jv_attrs=${_jv_ref@a}
|
||||
|
||||
case "$_jv_attrs" in
|
||||
*a*) # process indexed array
|
||||
echo -n '['
|
||||
local _jv_value _jv_i=0
|
||||
for _jv_value in "${_jv_ref[@]}"; do
|
||||
((_jv_i++))
|
||||
|
||||
# check member type
|
||||
if [[ $_jv_attrs == *i* ]]; then
|
||||
printf '%d' "$_jv_value"
|
||||
else
|
||||
_jv-json-encode-string "$_jv_value"
|
||||
fi
|
||||
|
||||
if ((_jv_i < ${#_jv_ref[@]})); then
|
||||
echo -n ', '
|
||||
fi
|
||||
done
|
||||
echo -n ']'
|
||||
;;
|
||||
*A*) # process associative array
|
||||
echo -n '{'
|
||||
local _jv_key _jv_value _jv_i=0
|
||||
for _jv_key in "${!_jv_ref[@]}"; do
|
||||
((_jv_i++))
|
||||
|
||||
_jv_value=${_jv_ref[$_jv_key]}
|
||||
|
||||
_jv-json-encode-string "$_jv_key"
|
||||
echo -n ': '
|
||||
|
||||
if [[ $_jv_attrs == *i* ]]; then
|
||||
printf '%d' "$_jv_value"
|
||||
else
|
||||
_jv-json-encode-string "$_jv_value"
|
||||
fi
|
||||
|
||||
if ((_jv_i < ${#_jv_ref[@]})); then
|
||||
echo -n ', '
|
||||
fi
|
||||
done
|
||||
echo -n '}'
|
||||
;;
|
||||
*i*) # process integer
|
||||
echo -n "$_jv_ref"
|
||||
;;
|
||||
*) # anything else, it's probably a string lol
|
||||
_jv-json-encode-string "$_jv_ref"
|
||||
;;
|
||||
esac
|
||||
|
||||
}
|
||||
|
||||
jsonvar() {
|
||||
local _jv_all='false'
|
||||
local _jv_exported='false'
|
||||
local _jv_value='false'
|
||||
|
||||
# get arguments from user
|
||||
local OPTIND OPTARG _jv_opt
|
||||
while getopts 'aevh' _jv_opt; do
|
||||
case "$_jv_opt" in
|
||||
a) _jv_all='true';;
|
||||
e) _jv_exported='true';;
|
||||
v) _jv_value='true';;
|
||||
h) _jv-usage; return 0;;
|
||||
*) _jv-usage >&2; return 2;;
|
||||
esac
|
||||
done
|
||||
shift "$((OPTIND - 1))"
|
||||
|
||||
local _jv_key
|
||||
|
||||
# figure out what variables to look at
|
||||
local -a _jv_variables
|
||||
if $_jv_all; then
|
||||
readarray -t _jv_variables < <(compgen -v)
|
||||
elif $_jv_exported; then
|
||||
readarray -t _jv_variables < <(compgen -e)
|
||||
else
|
||||
_jv_variables=("$@")
|
||||
|
||||
# ensure the user gave us *something*
|
||||
if (( ${#_jv_variables[@]} == 0 )); then
|
||||
echo 'variable name or flag required' >&2
|
||||
_jv-usage >&2
|
||||
return 2
|
||||
fi
|
||||
|
||||
# check variables given
|
||||
local _jv_error='false'
|
||||
for _jv_key in "${_jv_variables[@]}"; do
|
||||
# warn the user if they gave us an internal name
|
||||
if [[ $_jv_key == _jv_* ]]; then
|
||||
echo "[error] invalid internal variable '$_jv_key'" >&2
|
||||
_jv_error='true'
|
||||
fi
|
||||
|
||||
# check to make sure the variable is defined
|
||||
if ! declare -p "$_jv_key" &>/dev/null; then
|
||||
echo "[error] variable '$_jv_key' not defined" >&2
|
||||
_jv_error='true'
|
||||
fi
|
||||
done
|
||||
|
||||
if $_jv_error; then
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# loop the variables first to filter out hidden / internal var names
|
||||
local _jv_i
|
||||
local _jv_len=${#_jv_variables[@]}
|
||||
for ((_jv_i = 0; _jv_i < _jv_len; _jv_i++)); do
|
||||
_jv_key=${_jv_variables[_jv_i]}
|
||||
|
||||
# filter out internal variables by name
|
||||
if [[ $_jv_key == _jv_* ]]; then
|
||||
unset '_jv_variables[_jv_i]'
|
||||
continue
|
||||
fi
|
||||
|
||||
# variable name was good, do nothing
|
||||
done
|
||||
|
||||
# loop the remaining variables and format them
|
||||
$_jv_value || echo '{'
|
||||
_jv_i=0
|
||||
for _jv_key in "${_jv_variables[@]}"; do
|
||||
((_jv_i++))
|
||||
|
||||
if ! $_jv_value; then
|
||||
# indent
|
||||
echo -n ' '
|
||||
|
||||
# print the key
|
||||
_jv-json-encode-string "$_jv_key"
|
||||
echo -n ': '
|
||||
fi
|
||||
|
||||
# print the value
|
||||
_jv-encode-variable "$_jv_key"
|
||||
|
||||
# optionally print the comma
|
||||
if ! $_jv_value && ((_jv_i < ${#_jv_variables[@]})); then
|
||||
echo -n ','
|
||||
fi
|
||||
echo
|
||||
done
|
||||
$_jv_value || echo '}'
|
||||
}
|
||||
|
||||
_jv-complete() {
|
||||
COMPREPLY=(
|
||||
# add all variables
|
||||
$(compgen -v -- "${COMP_WORDS[COMP_CWORD]}")
|
||||
|
||||
# add the individual flags
|
||||
$(compgen -W '-a -e -v -h' -- "${COMP_WORDS[COMP_CWORD]}")
|
||||
)
|
||||
}
|
||||
|
||||
if ( return 0 &>/dev/null ); then
|
||||
# we are being sourced
|
||||
complete -F _jv-complete jsonvar
|
||||
else
|
||||
# we are being executed directly
|
||||
declare -a test_indexed=(a b c)
|
||||
declare -a test_sparse=(a b c [67]=d)
|
||||
declare -A test_assoc=([a]=1 [b]=2 [c]=3)
|
||||
declare -i test_int=67
|
||||
declare -- test_string='hello world'
|
||||
|
||||
declare -ai test_indexed_ints=(0 1 2 0xff foo bar baz)
|
||||
declare -Ai test_assoc_ints=([foo]=0 [bar]=1 [baz]=0xff [bat]=foo)
|
||||
|
||||
jsonvar "$@"
|
||||
fi
|
||||
Executable
+11
@@ -0,0 +1,11 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
send_some_output() {
|
||||
echo "hello"
|
||||
echo "here"
|
||||
echo "goodbye"
|
||||
}
|
||||
|
||||
exec > >(tee -a ./x.out) 2>&1
|
||||
|
||||
send_some_output >&2
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
|
||||
- name: test-get-hpf-facts.yml
|
||||
hosts: all
|
||||
|
||||
tasks:
|
||||
|
||||
- name: Copy over get-hpf-facts.sh
|
||||
ansible.builtin.copy:
|
||||
src: home/hpf-ans/bin/get-hpf-facts.sh
|
||||
dest: bin/get-hpf-facts.sh
|
||||
owner: hpf-ans
|
||||
group: hpf-ans
|
||||
mode: u=rwx,go=gx
|
||||
backup: true
|
||||
|
||||
- name: Run get-hpf-facts.sh
|
||||
ansible.builtin.command:
|
||||
cmd: bin/get-hpf-facts.sh {{ ansible_facts["os_family"] }}
|
||||
register: registered_hpf_facts
|
||||
changed_when: false
|
||||
|
||||
- name: Convert k=v stdout into facts
|
||||
ansible.builtin.set_fact:
|
||||
hpf_facts: "{{ registered_hpf_facts.stdout | from_json }}"
|
||||
|
||||
- name: Print skel
|
||||
ansible.builtin.debug:
|
||||
var: hpf_facts.skel
|
||||
@@ -0,0 +1,70 @@
|
||||
---
|
||||
|
||||
- name: test-get_useradd_settings.sh
|
||||
hosts: all
|
||||
|
||||
tasks:
|
||||
|
||||
- name: Copy over bin/get_useradd_settings.sh
|
||||
ansible.builtin.copy:
|
||||
src: hpf-ans/bin/get_useradd_settings.sh
|
||||
dest: bin/get_useradd_settings.sh
|
||||
owner: hpf-ans
|
||||
group: hpf-ans
|
||||
mode: u=rwx,go=gx
|
||||
backup: true
|
||||
|
||||
- name: Run get_useradd_settings.sh
|
||||
ansible.builtin.command:
|
||||
cmd: bin/get_useradd_settings.sh {{ ansible_facts["os_family"] }}
|
||||
register: useradd_settings
|
||||
changed_when: false
|
||||
|
||||
- name: Convert k=v stdout into variables
|
||||
ansible.builtin.set_fact:
|
||||
# great_heath:
|
||||
# - "{{ item.split('=', 1)[0] }}": "{{ item.split('=', 1)[1] }}"
|
||||
"HPF_{{ item.split('=', 1)[0] }}": "{{ item.split('=', 1)[1] }}"
|
||||
# "{{ item.split('=', 1)[0] | trim }}": "{{ item.split('=', 1)[1] | trim }}"
|
||||
loop: "{{ useradd_settings.stdout.splitlines() }}"
|
||||
|
||||
|
||||
|
||||
# - name: Convert key-value strings into variables
|
||||
# vars:
|
||||
# my_var: "SKEL= SKEL2=/etc/skel\nHEATH=great"
|
||||
# ansible.builtin.set_fact: "{{ my_var }}"
|
||||
|
||||
# ansible.builtin.set_fact: "{{ useradd_settings.stdout }}"
|
||||
|
||||
# ansible.builtin.set_fact: "SKEL= SKEL2=/etc/skel\nHEATH=great"
|
||||
|
||||
# ansible.builtin.set_fact: "{{ useradd_settings.stdout | from_yaml }}"
|
||||
|
||||
# ansible.builtin.set_fact: "{{ useradd_settings.stdout }}"
|
||||
|
||||
# ansible.builtin.set_fact: "SKEL2=/etc/skel\nHEATH=great"
|
||||
|
||||
# - name: Convert key-value strings into variables
|
||||
# ansible.builtin.set_fact:
|
||||
# kv_vars: "{{ useradd_settings.stdout }}"
|
||||
|
||||
# - name: Print ansible variables
|
||||
# ansible.builtin.debug:
|
||||
# var: vars
|
||||
|
||||
# - name: Print SKEL
|
||||
# ansible.builtin.debug:
|
||||
# var: SKEL
|
||||
# - name: Print heath.SKEL
|
||||
# ansible.builtin.debug:
|
||||
# var: heath.SKEL
|
||||
# - name: Print SKEL2
|
||||
# ansible.builtin.debug:
|
||||
# var: SKEL2
|
||||
# - name: Print HEATH
|
||||
# ansible.builtin.debug:
|
||||
# var: HEATH
|
||||
- name: Print all variables
|
||||
ansible.builtin.debug:
|
||||
var: vars
|
||||
Reference in New Issue
Block a user