Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
5a74d8c
try
james-otten Dec 7, 2024
4c796b9
lol
james-otten Dec 7, 2024
ac041bf
vm
james-otten Dec 7, 2024
d63901d
vm
james-otten Dec 7, 2024
d8bd25e
fix
james-otten Dec 7, 2024
c2ac443
chrony
james-otten Dec 8, 2024
874e9e2
chrony
james-otten Dec 8, 2024
9930e36
dd logs
james-otten Dec 8, 2024
745ec79
dd logs
james-otten Dec 8, 2024
ac8cc09
dd logs
james-otten Dec 8, 2024
e1da32c
role dir
Dec 11, 2024
3b6b6ed
fix
Dec 11, 2024
a0138f2
iptables
Dec 12, 2024
246f4f7
iptables
Dec 12, 2024
3a52fac
lint
Dec 12, 2024
eb6f0c1
mgt
Dec 12, 2024
8bf48fd
iptables
Dec 13, 2024
30d67bc
boot
Dec 13, 2024
2448a50
sources
Dec 13, 2024
ed44097
sn10
james-otten Dec 19, 2024
62ee1bc
fix
james-otten Dec 19, 2024
0cb8cd7
deps
james-otten Dec 19, 2024
42aca5c
ssh
james-otten Dec 26, 2024
af837db
spell
james-otten Dec 26, 2024
62e1675
ahh
james-otten Dec 26, 2024
59aba99
mesh_dns
james-otten Dec 26, 2024
d6fd17d
mesh_dns
james-otten Dec 26, 2024
861390d
branch + support
james-otten Dec 26, 2024
379fd3f
branch + support
james-otten Dec 26, 2024
086dc91
branch + support
james-otten Dec 26, 2024
8d26c31
cf
james-otten Dec 28, 2024
170cb7a
netplan
james-otten Dec 30, 2024
f65645a
netplan
james-otten Dec 30, 2024
30cf6ac
netplan
james-otten Dec 30, 2024
23775d6
netplan
james-otten Dec 30, 2024
dad342c
netplan
james-otten Dec 30, 2024
284b811
motd
james-otten Jan 10, 2025
fc45665
lint
james-otten Jan 16, 2025
4a6b8a3
remove the bird_neighbor parameter due to broadcast mode per daniel
james-otten Jan 23, 2025
f924906
switch to shared role
james-otten Jan 23, 2025
0308b40
switch to shared role
james-otten Jan 23, 2025
f5ebaa0
bind bird to chrony
james-otten Jan 23, 2025
11ec265
cleanup
james-otten Jan 24, 2025
285768b
prod1
james-otten Mar 9, 2025
15c641e
add servers
james-otten Mar 9, 2025
db8bf1f
no3
james-otten Mar 10, 2025
a9f5f88
clean
james-otten Mar 11, 2025
dcbdf82
Create scorecard.yaml
james-otten Jun 3, 2025
7892b03
Create dependabot.yml
james-otten Jun 24, 2025
57b49b3
Create requirements.txt
james-otten Jun 24, 2025
c1fdfaf
Update deploy_ntp.yaml
james-otten Jun 24, 2025
1186a9c
Update deploy_ntp.yaml
james-otten Jan 13, 2026
bf59e38
Update deploy.yaml
james-otten Jan 13, 2026
cbf73ca
Update deploy_ntp.yaml
james-otten Jan 13, 2026
49c61ef
Update deploy_ntp.yaml
james-otten Jan 13, 2026
d37f757
Update deploy_ntp.yaml
james-otten Jan 13, 2026
f2cd5ee
Update requirements.txt
james-otten Jan 13, 2026
850a3a6
Update deploy_ntp.yaml
james-otten Jan 13, 2026
dda8953
Update deploy_ntp.yaml
james-otten Jan 13, 2026
6575e83
Update deploy_ntp.yaml
james-otten Jan 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
version: 2
updates:
- package-ecosystem: "pip"
directory: "/ansible/"
schedule:
interval: "cron"
cronjob: "41 6 * * *"
assignees:
- "james-otten"
- package-ecosystem: "terraform"
directory: "/terraform/"
schedule:
interval: "cron"
cronjob: "4 6 * * *"
assignees:
- "james-otten"
16 changes: 16 additions & 0 deletions .github/workflows/ansible_lint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: ansible-lint
on:
pull_request:
jobs:
build:
name: Ansible Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run ansible-lint
uses: ansible/ansible-lint@c629b235398065e24ff44b5f1138028642c74a03
with:
args: "--exclude .ansible/collections/"
setup_python: "true"
working_directory: "./ansible/"
requirements_file: ""
37 changes: 37 additions & 0 deletions .github/workflows/deploy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Deploy Environments
permissions: read-all

on:
push:
# branches:
# - main
workflow_dispatch:
branches:
- main

jobs:
# deploy_prod3:
# name: Deploy prod3
# uses: ./.github/workflows/deploy_ntp.yaml
# with:
# environment: prod3
# secrets: inherit
# #if: github.ref == 'refs/heads/main'

deploy_prod2:
name: Deploy prod2
uses: ./.github/workflows/deploy_ntp.yaml
with:
environment: prod2
secrets: inherit
# needs: deploy_prod3
#if: github.ref == 'refs/heads/main'

deploy_prod1:
name: Deploy prod1
uses: ./.github/workflows/deploy_ntp.yaml
with:
environment: prod1
secrets: inherit
needs: deploy_prod2
if: github.ref == 'refs/heads/main'
92 changes: 92 additions & 0 deletions .github/workflows/deploy_ntp.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
name: Deploy NTP Server
permissions: read-all

on:
workflow_call:
inputs:
environment:
required: true
type: string

env:
# Secrets
TF_VAR_proxmox_host: ${{ secrets.TF_VAR_PROXMOX_HOST }}
TF_VAR_proxmox_token_id: ${{ secrets.TF_VAR_PROXMOX_TOKEN_ID }}
TF_VAR_proxmox_token_secret: ${{ secrets.TF_VAR_PROXMOX_TOKEN_SECRET }}
TF_VAR_local_password: ${{ secrets.TF_VAR_LOCAL_PASSWORD }}
TF_VAR_datadog_api_key: ${{ secrets.DATADOG_API_KEY }}
TF_VAR_datadog_site: ${{ secrets.DATADOG_SITE }}
# Credentials for deployment to AWS
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
# S3 bucket for the Terraform state
BUCKET_TF_STATE: ${{ secrets.BUCKET_TF_STATE}}

jobs:
deploy:
runs-on: ubuntu-latest
environment: ${{ inputs.environment }}
steps:
- name: Checkout
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # @v4

- uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d #@v5
with:
python-version: '3.11'

- name: Setup ansible
run: pip install -r ansible/requirements.txt && export PATH="$HOME/.local/bin:$PATH" && ansible-galaxy collection install -r ansible/roles/requirements.yml

- name: Setup Terraform with specified version on the runner
uses: hashicorp/setup-terraform@651471c36a6092792c552e8b1bef71e592b462d8 # @v3
with:
terraform_version: 1.8.3

- name: Setup backend
run: |
echo "bucket = \"${{ secrets.BUCKET_TF_STATE }}\"" > backend.tfvars
echo "key = \"terraform/state/ntp-${{ inputs.environment }}.tfstate\"" >> backend.tfvars
working-directory: ./terraform/

- name: Terraform init
id: init
run: terraform init -backend-config=backend.tfvars
working-directory: ./terraform/

- name: Terraform format
id: fmt
run: terraform fmt -check
working-directory: ./terraform/

- name: Terraform validate
run: |
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ntp
echo "${{ secrets.SSH_PUBLIC_KEY }}" > ntp.pub
chmod 600 ntp
chmod 600 ntp.pub
terraform validate
working-directory: ./terraform/

- name: Setup WireGuard
uses: nycmeshnet/nycmesh-vpn-action@main
with:
config-name: ghntp
private-key: ${{ secrets.WIREGUARD_PRIVATE_KEY }}
server-preference: '10,3,11'
# run: |
# sudo apt-get update && sudo apt-get install -y wireguard
# echo "${{ secrets.WIREGUARD_PRIVATE_KEY }}" > privatekey
# sudo ip link add dev wg0 type wireguard
# sudo ip address add dev wg0 ${{ secrets.WIREGUARD_OVERLAY_NETWORK_IP }} peer ${{ secrets.WIREGUARD_PEER }}
# sudo wg set wg0 listen-port 48123 private-key privatekey peer ${{ secrets.WIREGUARD_PEER_PUBLIC_KEY }} allowed-ips 0.0.0.0/0 endpoint ${{ secrets.WIREGUARD_ENDPOINT }}
# sudo ip link set up dev wg0
# rm privatekey

- name: Terraform Apply
run: |
terraform apply -auto-approve -input=false -var-file=${{ inputs.environment }}.tfvars
working-directory: ./terraform/

- name: Run playbook
run: sleep 20 && export PATH="$HOME/.local/bin:$PATH" && ansible-playbook -i inventory.yaml ntp_servers.yaml
working-directory: ./ansible/
64 changes: 64 additions & 0 deletions .github/workflows/scorecard.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: Scorecard supply-chain security
on:
# For Branch-Protection check. Only the default branch is supported. See
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection
branch_protection_rule:
# To guarantee Maintained check is occasionally updated. See
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained
schedule:
- cron: '30 15 * * 6'
push:
branches: [ "main" ]

# Declare default permissions as read only.
permissions: read-all

jobs:
analysis:
name: Scorecard analysis
runs-on: ubuntu-latest
# `publish_results: true` only works when run from the default branch. conditional can be removed if disabled.
if: github.event.repository.default_branch == github.ref_name || github.event_name == 'pull_request'
permissions:
# Needed to upload the results to code-scanning dashboard.
security-events: write
# Needed to publish results and get a badge (see publish_results below).
id-token: write

steps:
- name: "Checkout code"
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false

- name: "Run analysis"
uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1
with:
results_file: results.sarif
results_format: sarif
# (Optional) "write" PAT token. Uncomment the `repo_token` line below if:
# - you want to enable the Branch-Protection check on a *public* repository, or
# - you are installing Scorecard on a *private* repository
# To create the PAT, follow the steps in https://github.com/ossf/scorecard-action?tab=readme-ov-file#authentication-with-fine-grained-pat-optional.
# repo_token: ${{ secrets.SCORECARD_TOKEN }}

# Public repositories:
# - Publish results to OpenSSF REST API for easy access by consumers
# - Allows the repository to include the Scorecard badge.
# - See https://github.com/ossf/scorecard-action#publishing-results.
publish_results: true

# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
with:
name: SARIF file
path: results.sarif
retention-days: 5

# Upload the results to GitHub's code scanning dashboard (optional).
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@d39d31e687223d841ef683f52467bd88e9b21c14 # v3
with:
sarif_file: results.sarif
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
data/
data/
.vscode/
1 change: 1 addition & 0 deletions ansible/.ansible-lint-ignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
roles/chrony_server/tasks/main.yaml no-changed-when
8 changes: 8 additions & 0 deletions ansible/ansible.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[defaults]
host_key_checking = False
callbacks_enabled = timer, profile_tasks, profile_roles
gathering = 'explicit'
pipelining = True

[ssh_connection]
ssh_args = '-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o CheckHostIP=no -o ControlMaster=auto -o ControlPersist=60s'
3 changes: 3 additions & 0 deletions ansible/inventory.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
plugin: cloud.terraform.terraform_provider
project_path: "../terraform"
5 changes: 5 additions & 0 deletions ansible/ntp_servers.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
- name: NTP Servers
hosts: ntp_mgt
become: true
roles:
- role: chrony_server
28 changes: 28 additions & 0 deletions ansible/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
ansible==11.6.0 \
--hash=sha256:5b9c19d6a1080011c14c821bc7e6f8fd5b2a392219cbf2ced9be05e6d447d8cd
ansible-core==2.18.6 \
--hash=sha256:12a34749a7b20f0f1536bd3e3b2e137341867e4642e351273e96647161f595c0
cffi==1.17.1 \
--hash=sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd \
--hash=sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d \
--hash=sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93
cryptography==45.0.4 \
--hash=sha256:2882338b2a6e0bd337052e8b9007ced85c637da19ef9ecaf437744495c8c2999
Jinja2==3.1.6 \
--hash=sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67
MarkupSafe==3.0.2 \
--hash=sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396 \
--hash=sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84 \
--hash=sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8
packaging==25.0 \
--hash=sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484
passlib==1.7.4 \
--hash=sha256:aa6bca462b8d8bda89c70b382f0c298a20b5560af6cbfa2dce410c0a2fb669f1
pycparser==2.22 \
--hash=sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc
PyYAML==6.0.2 \
--hash=sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85 \
--hash=sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476
resolvelib==1.0.1 \
--hash=sha256:f80de38ae744bcf4e918e27a681a5c6cb63a08d9a926c0989c0730bcdd089049 \
--hash=sha256:d2da45d1a8dfee81bdd591647783e340ef3bcb104b54c383f70d422ef5cc7dbf
6 changes: 6 additions & 0 deletions ansible/roles/chrony_server/files/configured_servers.sources
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Managed by ansible

# Cloudflare NTS
server time.cloudflare.com nts iburst
server virginia.time.system76.com nts iburst
server ohio.time.system76.com nts iburst
104 changes: 104 additions & 0 deletions ansible/roles/chrony_server/tasks/main.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
- name: Install deps
ansible.builtin.apt:
lock_timeout: 240
update_cache: true
pkg:
- ca-certificates
- iptables-persistent
- chrony

- name: Import the ssh_config role from the nycmesh.common collection
ansible.builtin.import_role:
name: nycmesh.common.ssh_config

- name: Import the mesh_dns role from the nycmesh.common collection
ansible.builtin.import_role:
name: nycmesh.common.mesh_dns
vars:
extra_resolvers: "9.9.9.9"

- name: Import the support_account role from the nycmesh.common collection
ansible.builtin.import_role:
name: nycmesh.common.support_account

- name: Import the motd role from the nycmesh.common collection
ansible.builtin.import_role:
name: nycmesh.common.motd
vars:
github_repo: https://github.com/nycmeshnet/ntp-infra

- name: Allow restarting of chrony
ansible.builtin.lineinfile:
path: /lib/systemd/system/chrony.service
insertafter: '\[Service\]'
search_string: Restart=
line: "Restart=always"

- name: Import the Datadog Agent role from the Datadog collection
ansible.builtin.import_role:
name: datadog.dd.agent
vars:
datadog_api_key: "{{ DATADOG_API_KEY }}"
datadog_site: "{{ DATADOG_SITE }}"
datadog_config:
hostname: "{{ VM_HOSTNAME }}"
logs_enabled: true
datadog_additional_groups: "systemd-journal"
datadog_checks:
journald:
logs:
- type: journald
path: /var/log/journal/

- name: Reload datadog
ansible.builtin.systemd_service:
name: datadog-agent
state: restarted
enabled: true
daemon_reload: true

- name: Iptables rules
ansible.builtin.template:
src: iptables.j2
dest: /etc/iptables/rules.v4
mode: "600"

- name: Restore iptables rules
ansible.builtin.command:
cmd: "bash -c '/sbin/iptables-restore < /etc/iptables/rules.v4'"

- name: Import the netplan_loopback role from the nycmesh.common collection
ansible.builtin.import_role:
name: nycmesh.common.netplan_loopback
vars:
netplan_loopback_ips: "{{ NTP_IP }};{{ bird_router_id }}"

- name: Restart and enable iptables service
ansible.builtin.service:
name: netfilter-persistent
state: restarted
enabled: true

- name: Chrony config
ansible.builtin.template:
src: chrony.conf.j2
dest: /etc/chrony/chrony.conf
mode: "0644"

- name: Chrony sources
ansible.builtin.copy:
src: configured_servers.sources
dest: /etc/chrony/sources.d/configured_servers.sources
mode: "0644"

- name: Restart chrony
ansible.builtin.systemd_service:
name: chrony
state: restarted
enabled: true

- name: Import the bird_basic role from the nycmesh.common collection
ansible.builtin.import_role:
name: nycmesh.common.bird2_basic
vars:
bird_binds_to_service: "chrony.service"
Loading
Loading