Compare commits
583 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3c53891d82 | |||
| 2de0510059 | |||
| 13511a796c | |||
| 0e4160f6d6 | |||
| 9ab631a925 | |||
| bb05c00b6f | |||
| 13ea3288f7 | |||
| 669ce4e88a | |||
| 0b2241ceb7 | |||
| 4003e830cf | |||
| 9250b3e22a | |||
| 6c4117ab95 | |||
| cfb0a1d437 | |||
| f25426a1ca | |||
| e325544c58 | |||
| 1332c86ecc | |||
| 548ac28dc2 | |||
| 042f04601c | |||
| e0a042608a | |||
| f7deab4509 | |||
| e8bcbe8dd2 | |||
| 909c7ebaa1 | |||
| 433d6bf70b | |||
| 6a9b1b8112 | |||
| 0abfad7c4b | |||
| 96edc58a2a | |||
| b7e9ef7a16 | |||
| 9a3a640cce | |||
| f7d685a9ac | |||
| 7145e1d0a5 | |||
| 650038dfa1 | |||
| 34cfefc62c | |||
| 04a5f0b646 | |||
| b86190dcf6 | |||
| b99ab02fcc | |||
| 7519ef532d | |||
| eeb3d6d739 | |||
| 77e42d3a56 | |||
| b6613aaeaf | |||
| 7014b5c549 | |||
| bef52b0abc | |||
| 3f95800825 | |||
| 0a656dcaf2 | |||
| fd6318ec86 | |||
| 69be15e39c | |||
| 742770dfe9 | |||
| 85c8a1c0b9 | |||
| baa28bf66c | |||
| c48fa3d0df | |||
| aca10f2250 | |||
| c6634cddac | |||
| efc9a8a0f4 | |||
| 832da6ee78 | |||
| b3936a3cab | |||
| b096120482 | |||
| c339952965 | |||
| 91197e3931 | |||
| 1f1aed480f | |||
| c3d1638fd4 | |||
| 33fa78e117 | |||
| 77e8704c8e | |||
| e1e89dc89b | |||
| 1f662db288 | |||
| 1742641296 | |||
| c27fee72ba | |||
| c20d2be439 | |||
| 4549a213e2 | |||
| 8587141c69 | |||
| e65cf2ce2c | |||
| 44c0436216 | |||
| 4cf1c47db2 | |||
| f7beeb1cff | |||
| cd0c596797 | |||
| 4687bb7bd5 | |||
| 1af0192a5c | |||
| b912e18028 | |||
| 86dfa5cb00 | |||
| f9813a249e | |||
| a083b71a27 | |||
| a9fa3c95e3 | |||
| 78400a13db | |||
| c21af9193f | |||
| b8a32d8c8f | |||
| 4273819a2e | |||
| cd9ead5c82 | |||
| d22242efff | |||
| 712980805d | |||
| d559799d77 | |||
| 7ec7902a79 | |||
| 556d94bcb0 | |||
| fba2477179 | |||
| ff6e294e1e | |||
| 6bef5ab9f0 | |||
| 3b3b8a5e6c | |||
| 57e39cbe04 | |||
| 49a09cd242 | |||
| e9c2fe368e | |||
| 1dcd0bf9d1 | |||
| 88e6b245c4 | |||
| bee079297d | |||
| 9ffda8fd78 | |||
| 51aed951fe | |||
| f10011b208 | |||
| 93238eb93f | |||
| 3ed591777c | |||
| ffa781d8c9 | |||
| 54e110241c | |||
| 8723f1b7f5 | |||
| b1b01f3ab3 | |||
| b5aead95bf | |||
| eccede0bb7 | |||
| 5950d8aa94 | |||
| 385c0cf657 | |||
| 5cfdcaea13 | |||
| 5a34437ec8 | |||
| 8a69f1dd93 | |||
| 20778b55ee | |||
| 8f3654125c | |||
| 61962528c6 | |||
| 8fc754abf3 | |||
| 2925eae450 | |||
| 75eff71896 | |||
| 824181aeee | |||
| 263ef13da5 | |||
| 4321affbb4 | |||
| ab436a34b2 | |||
| 09f8f49a10 | |||
| f2f383e845 | |||
| cdf266c9bb | |||
| e3ac1fa602 | |||
| 0df1163756 | |||
| 016ac4af28 | |||
| 3f9cf3b5e9 | |||
| 38a5dcbd21 | |||
| 67072c1d4e | |||
| 696570784f | |||
| 7c71871fd6 | |||
| a213005361 | |||
| 1daaaef3c1 | |||
| 6df3148f18 | |||
| 2ac2b20a97 | |||
| c03e49b389 | |||
| 399fbd46f7 | |||
| 52c186a9fb | |||
| 93303473bf | |||
| 1c046417be | |||
| 1fb6393649 | |||
| 0fc8c7ab07 | |||
| ea9874fe77 | |||
| ffdd167352 | |||
| a577d491ef | |||
| 71f405a399 | |||
| d6b4123e8a | |||
| 8e2d8149df | |||
| fcad744044 | |||
| be7bf40bb9 | |||
| 24f0c918ad | |||
| cbbade2b61 | |||
| 2008e12b6f | |||
| 922a5e9e96 | |||
| 16c1fa0efa | |||
| fb5a5ba603 | |||
| 8e433ae621 | |||
| c7dc9d396a | |||
| d9c7dc5347 | |||
| 19e4f99816 | |||
| 67a0273ad1 | |||
| 238298aed1 | |||
| 939388388f | |||
| 2e3833964d | |||
| 9d5acaaa92 | |||
| f01c505e6c | |||
| 9dd0e5eea7 | |||
| 206481ca1f | |||
| 824c662932 | |||
| 6f66b51f99 | |||
| 31a831f309 | |||
| 57a22f9e54 | |||
| 52954927be | |||
| d033fdfa9b | |||
| 4edb624a0c | |||
| 5388e9bca5 | |||
| 5859b98a20 | |||
| 52ec39de79 | |||
| 955b4dab13 | |||
| a1ee9aba41 | |||
| ec1f356620 | |||
| 533ffdd370 | |||
| 5ce74f062d | |||
| 66716f5780 | |||
| 043c9687c7 | |||
| 4f0b4cfe5d | |||
| eaed4624cd | |||
| 420556ce83 | |||
| e1c2da5cdb | |||
| 97540b24aa | |||
| e3735adcc8 | |||
| ff2b99ec00 | |||
| 9d627b2fc2 | |||
| 3948b03cc8 | |||
| 3384ddad47 | |||
| 3d40106eba | |||
| 77111f8982 | |||
| 72dccbe8f6 | |||
| 7abd917fcf | |||
| f37ea41632 | |||
| 1934d62697 | |||
| 0b891864ea | |||
| ecae976f3b | |||
| b82705c3a7 | |||
| 05f0945e7f | |||
| 7f94212785 | |||
| 1f6ddc377c | |||
| 24591c299a | |||
| 4521b58c17 | |||
| 488c614ae7 | |||
| 04a0a70368 | |||
| 3d14f85c68 | |||
| ec7b22974e | |||
| 8877e0110d | |||
| 3c13802cf2 | |||
| 06014f6cf6 | |||
| 066654b5c4 | |||
| 4a2c93e0c4 | |||
| b534308953 | |||
| 54e3d576d5 | |||
| 0e3f8abb45 | |||
| 3a0c706c5f | |||
| e9f517509d | |||
| df53a0535a | |||
| b879f3fffa | |||
| 65c273c3cd | |||
| 36b4567ff8 | |||
| 08eb39102f | |||
| 369db072df | |||
| 8827aebdf3 | |||
| d29d92bc7a | |||
| b9abc98083 | |||
| b193e19a50 | |||
| 4e01a93d1c | |||
| 34a9767106 | |||
| 1f6ee088ab | |||
| d1324ffcff | |||
| 0c6fd323e2 | |||
| 5bcd951bcf | |||
| c7dbc5ae01 | |||
| 69785d0494 | |||
| 8482b3597c | |||
| 7006bb492a | |||
| c710b9f2cf | |||
| 87123c7099 | |||
| 726df40e69 | |||
| 48d404df5e | |||
| da21662f01 | |||
| b03de66552 | |||
| 89c6700999 | |||
| c5e4bbab0b | |||
| 1d3bbc61fb | |||
| f53362d8aa | |||
| 32cd8fedae | |||
| 2166d4854d | |||
| 4762e28af4 | |||
| 1cf3f085c6 | |||
| 69f216848a | |||
| 6d531e0a25 | |||
| 87ed73492a | |||
| 48f58ee330 | |||
| 85f972b5eb | |||
| 3df3c0d9e7 | |||
| 3f87ed3d0a | |||
| b3ef40e93b | |||
| e857335c91 | |||
| 18145a20db | |||
| b920f77921 | |||
| 8efffa1b12 | |||
| 6c40facaef | |||
| dfb8118633 | |||
| 55d1605502 | |||
| d8ad3ab882 | |||
| c84b7d1123 | |||
| db87a4667d | |||
| d02bf24203 | |||
| b99ae77c13 | |||
| 131206ad9e | |||
| c8fa799e14 | |||
| 8f154ac98e | |||
| 009c0dd43b | |||
| 8aa492c959 | |||
| 6a21e8dedb | |||
| f4dec48ebb | |||
| 5d0daaefee | |||
| 0b5e11e215 | |||
| 6435f003af | |||
| c427d73c0c | |||
| c5de666c86 | |||
| c14f197bc2 | |||
| 1babac4ce0 | |||
| 6189697822 | |||
| d3ff8215e6 | |||
| 699aa5757f | |||
| 75bb1e4675 | |||
| 95ed547bbd | |||
| f20b1c88f4 | |||
| 84b0cb09fb | |||
| 8706b82009 | |||
| eed8d7ea81 | |||
| 60dbc44c1d | |||
| ba1bddb49d | |||
| be0e430b00 | |||
| b1866b26e7 | |||
| d9f2b4cad7 | |||
| 1d54a1bd44 | |||
| cc771e0b13 | |||
| 26e72dd3f1 | |||
| 481faa0acd | |||
| 0ae1fcd304 | |||
| 19daea6767 | |||
| d421a749e9 | |||
| 820191346b | |||
| 2da4bdc13e | |||
| 7ca0e8e5ad | |||
| d4037c7218 | |||
| d9498c66c7 | |||
| 1f0b71fab1 | |||
| 69ab87e4ed | |||
| 535bde66a8 | |||
| fd36ee6bf8 | |||
| fb1a0b3de8 | |||
| 3da059216c | |||
| f2fc0f64b3 | |||
| ef3cdf6f62 | |||
| db36090358 | |||
| 42d6e0da78 | |||
| 860ff9e065 | |||
| 1ec132b37f | |||
| 3564c6f79b | |||
| 4380cf28e7 | |||
| 179f618469 | |||
| 8112288dac | |||
| a296c9bf5e | |||
| f8cd764815 | |||
| 012a1dd117 | |||
| 6301da7603 | |||
| 9741508af3 | |||
| 4ac2ce24b8 | |||
| 996c713510 | |||
| e44e9da832 | |||
| 4c10573dab | |||
| 8460e24fd0 | |||
| b216198cd4 | |||
| 0f12eda873 | |||
| f5466aa013 | |||
| f21dbf79ea | |||
| be2ea7fc74 | |||
| 16e5b73622 | |||
| 9e30f385cc | |||
| 1281266ff5 | |||
| b6713b2830 | |||
| a8dac32320 | |||
| 08c09e0c6d | |||
| 90a93c4e8f | |||
| 54085449d9 | |||
| d3ef4cd14a | |||
| a896598eb0 | |||
| d97924e7e7 | |||
| 70f3a007fc | |||
| 18bd556c9d | |||
| deb80f24fe | |||
| 9a2e4be6af | |||
| 57348087a6 | |||
| a7969b768c | |||
| 5fbfbc9ad1 | |||
| 53353a603b | |||
| b38a01d6cd | |||
| 440337deb8 | |||
| 2ed6934cb2 | |||
| 3d37c3bdb8 | |||
| 8de0961975 | |||
| f931ec0cd6 | |||
| c3c10ce7e5 | |||
| 03b89d752e | |||
| 655109e5c8 | |||
| aabc4d229a | |||
| f6934952cf | |||
| a251d57742 | |||
| b4cc4923b3 | |||
| cf412bdf47 | |||
| c4e56cf5b1 | |||
| f1a3b1c169 | |||
| ec0f9f8a54 | |||
| b02f26aaf3 | |||
| aad0ed4146 | |||
| bbf07c84c5 | |||
| 0b98735261 | |||
| b5266d8b4b | |||
| 89f6fb35b8 | |||
| 3cbed2908a | |||
| b097fad335 | |||
| 47384c4b66 | |||
| 4ffd4dda5a | |||
| 825697c134 | |||
| 15c1396ebb | |||
| b7a474ae08 | |||
| cecd6bca5e | |||
| c07c840de4 | |||
| bc34e91fe6 | |||
| 20888af2b9 | |||
| 7872289630 | |||
| 30bc4fabfc | |||
| 0d02f5b7b6 | |||
| 44b9ca3b24 | |||
| 98f75b9fbd | |||
| dc5c78c507 | |||
| c76c18289a | |||
| 23ad772a53 | |||
| 926479d1ac | |||
| d7229e498a | |||
| 3cf60db048 | |||
| 6c4de20629 | |||
| 1ff9a29fb0 | |||
| 895abd694b | |||
| c70beefd40 | |||
| 55861d7c9a | |||
| dd004334b3 | |||
| 1999c7fde2 | |||
| 3377771e35 | |||
| 9562f5d7ce | |||
| 9b169236c6 | |||
| 3ef9b6860e | |||
| 5d5a13d5ff | |||
| 57d78b025b | |||
| 0d1a635f69 | |||
| 2e7c5e2cbe | |||
| 6b0e9b56b0 | |||
| c893b10540 | |||
| d789cdcbe3 | |||
| 2d30694f6e | |||
| 36c017bb70 | |||
| fbc5b9146d | |||
| ff1659e969 | |||
| 0f8fcc4dc0 | |||
| e458e92573 | |||
| 7b2bb828af | |||
| 2e8408fb11 | |||
| d407fcbe1a | |||
| 8df524c9d5 | |||
| bf693e7236 | |||
| b4d5b540c3 | |||
| 5ec576bebf | |||
| e547ae4667 | |||
| 0b164d534c | |||
| 2a8bfd86d0 | |||
| f4b8809853 | |||
| 24265ed8f6 | |||
| 5284bcd5e6 | |||
| 4e696a8fee | |||
| 5d893eafb4 | |||
| 8f1d81e650 | |||
| 16d137ff59 | |||
| 743d5a898c | |||
| 0b9dfc3b3c | |||
| 95850da1b4 | |||
| 39df4583d3 | |||
| 83a36ad4f2 | |||
| a17d0cd2e2 | |||
| 458fe871f4 | |||
| 1e59b91a0e | |||
| 4c79bccd85 | |||
| ff31f5c064 | |||
| 0360e165f4 | |||
| a36f9aebd5 | |||
| 7ed3d9ad64 | |||
| 69059e51df | |||
| 7013e9b26b | |||
| daba05d362 | |||
| c24f5bf91d | |||
| be341414f9 | |||
| c4ec0ad966 | |||
| 3876bd145c | |||
| 5342ed08b3 | |||
| 09934995cb | |||
| 568f9a83f5 | |||
| 3e510c8733 | |||
| c08306ecc2 | |||
| 8da24cf80a | |||
| 374d07f979 | |||
| 5e17ef2ea9 | |||
| 7645dd739e | |||
| 656548d4b0 | |||
| 5d7a350afe | |||
| 2e3099476e | |||
| a05c289aff | |||
| 347b9b9d76 | |||
| 0b06931427 | |||
| afa53aa747 | |||
| 91200fe37e | |||
| 895f1d0aef | |||
| f0a1969e73 | |||
| cd14a1ce23 | |||
| 3ddbbbb255 | |||
| d0483114dc | |||
| 722b942079 | |||
| 86d8b19ae3 | |||
| 63b190ccbd | |||
| 0bb60245dc | |||
| b70e7111ae | |||
| 788ec952fd | |||
| 038bf3e8d9 | |||
| 1cc77c6609 | |||
| dfd071150f | |||
| b55afab109 | |||
| cbbbe695ec | |||
| 6f3d3bbe49 | |||
| 3baf43ad74 | |||
| e2784f41fe | |||
| 1ac98da285 | |||
| 03463c6b88 | |||
| a1112357b8 | |||
| 10676c0754 | |||
| 1e581d71fb | |||
| a345319737 | |||
| f865ba6f16 | |||
| 8820fbe01e | |||
| 1775c937e6 | |||
| ee71215ac2 | |||
| 9819c38624 | |||
| 6aa7ede93a | |||
| c17d692c8a | |||
| e0269dc14b | |||
| 8d588eafb2 | |||
| cf899cd7fd | |||
| afcfc90cac | |||
| a29da08055 | |||
| 9f62b79b6f | |||
| b63e5af186 | |||
| 93bbfbbcdd | |||
| 4a02eba0e2 | |||
| f3d52b27b2 | |||
| 59115a58f5 | |||
| 049acd29cb | |||
| c5c9ee31f4 | |||
| 0ca80b1741 | |||
| 7c4d216817 | |||
| 9b1fafa848 | |||
| dc55872b5d | |||
| 77c90d7823 | |||
| ee7fddeed6 | |||
| 4e64a2b76a | |||
| 30cd9df16e | |||
| 333b00eeef | |||
| 6f1d04afc3 | |||
| 16310a21ba | |||
| c14a7ad35e | |||
| 47a0e912bb | |||
| 7c92ed044b | |||
| b64e4984af | |||
| 6348bb0fbb | |||
| 8e88b8bcbb | |||
| 73d0a36254 | |||
| b01df6af62 | |||
| feff445ab3 | |||
| ce1cfbf4c7 | |||
| daa40c6aa4 | |||
| 297c05742f | |||
| 65462229e5 | |||
| 1a13d29542 | |||
| 110a0dd411 | |||
| 1f14327c68 | |||
| cfd4e9150e | |||
| ed57ba4dc4 | |||
| 522c210f5a | |||
| 5b94503537 | |||
| 7772353d7c | |||
| 8c2f258d5d | |||
| 2cdb147b14 | |||
| 374ca7fb09 | |||
| 5c54f73210 | |||
| f550849d8e | |||
| a833562205 | |||
| 22080087c0 | |||
| 2e6c9886be | |||
| 5c77d4afa3 | |||
| fe0b34a752 |
+105
-5
@@ -1,15 +1,20 @@
|
||||
# Environment variables for docker-compose.yml
|
||||
PUID=1000
|
||||
PGID=1000
|
||||
LOG_LEVEL="DEBUG"
|
||||
LOG_LEVEL="INFO"
|
||||
NETWORK="web"
|
||||
TZ="Asia/Singapore"
|
||||
## dashboard configs
|
||||
HOST="furyhawk.lol"
|
||||
HOST="localhost"
|
||||
# TLD="lol"
|
||||
# LOCALDOMAIN="$(hostname).${TLD}"
|
||||
# DOMAIN="$(hostname).${TLD}"
|
||||
# DOMAINNAME="$(hostname).${TLD}"
|
||||
HOSTNAME="node00"
|
||||
DATADIR="/home/furyhawk/media"
|
||||
# media directory for jellyfin
|
||||
MEDIADIR="/var/media"
|
||||
# subdomain for dashboard.
|
||||
DASHBOARD_HOST="dashboard.furyhawk.lol"
|
||||
DASHBOARD_HOST="dashboard.example.lol"
|
||||
|
||||
## TLS configs
|
||||
CERT_PATH=./certs
|
||||
@@ -43,7 +48,7 @@ POSTGRES_PASSWORD=12345678
|
||||
PGADMIN_DEFAULT_EMAIL=youremail.com
|
||||
PGADMIN_DEFAULT_PASSWORD=12345678
|
||||
|
||||
DATABASE__HOSTNAME=furyhawk.lol
|
||||
DATABASE__HOSTNAME=example.lol
|
||||
DATABASE__USERNAME=admin
|
||||
DATABASE__PASSWORD=12345678
|
||||
DATABASE__PORT=5432
|
||||
@@ -58,6 +63,27 @@ MINIO_ROOT_PASSWORD=123456
|
||||
|
||||
NEO4J_PASSWORD=12345678
|
||||
|
||||
SEARXNG_SECRET=ultrasecretkey
|
||||
|
||||
#echo "AUTHENTIK_SECRET_KEY=$(openssl rand -base64 60 | tr -d '\n')" >> .env
|
||||
AUTHENTIK_SECRET_KEY=
|
||||
AUTHENTIK_ERROR_REPORTING__ENABLED=true
|
||||
# SMTP Host Emails are sent to
|
||||
AUTHENTIK_EMAIL__HOST=localhost
|
||||
AUTHENTIK_EMAIL__PORT=25
|
||||
# Optionally authenticate (don't add quotation marks to your password)
|
||||
AUTHENTIK_EMAIL__USERNAME=
|
||||
AUTHENTIK_EMAIL__PASSWORD=
|
||||
# Use StartTLS
|
||||
AUTHENTIK_EMAIL__USE_TLS=false
|
||||
# Use SSL
|
||||
AUTHENTIK_EMAIL__USE_SSL=false
|
||||
AUTHENTIK_EMAIL__TIMEOUT=10
|
||||
# Email address authentik will send from, should have a correct @domain
|
||||
AUTHENTIK_EMAIL__FROM=authentik@localhost
|
||||
COMPOSE_PORT_HTTP=80
|
||||
COMPOSE_PORT_HTTPS=443
|
||||
|
||||
#=====================================================================#
|
||||
# LibreChat Configuration #
|
||||
#=====================================================================#
|
||||
@@ -482,3 +508,77 @@ REDLIB_DEFAULT_DISABLE_VISIT_REDDIT_CONFIRMATION=off
|
||||
REDLIB_DEFAULT_HIDE_SCORE=off
|
||||
# Enable fixed navbar by default
|
||||
REDLIB_DEFAULT_FIXED_NAVBAR=on
|
||||
|
||||
# outline
|
||||
NODE_ENV=production
|
||||
|
||||
# Generate a hex-encoded 32-byte random key. You should use `openssl rand -hex 32`
|
||||
# in your terminal to generate a random value.
|
||||
OUTLINE_SECRET_KEY=00b5677d3ce6c106f3d95ec830f9530f9014a2620d16fe60ed867a30c4964c5e
|
||||
|
||||
# Generate a unique random key. The format is not important but you could still use
|
||||
# `openssl rand -hex 32` in your terminal to produce this.
|
||||
OUTLINE_UTILS_SECRET=4b8235fdc01295571bd0946abb5eaf7c131f1a652386c98b658bbc4b1b4e3540
|
||||
|
||||
# For production point these at your databases, in development the default
|
||||
# should work out of the box.
|
||||
DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${DATABASE__HOSTNAME}:5432/outline
|
||||
# DATABASE_CONNECTION_POOL_MIN=
|
||||
# DATABASE_CONNECTION_POOL_MAX=
|
||||
# Uncomment this to disable SSL for connecting to Postgres
|
||||
# PGSSLMODE=disable
|
||||
|
||||
# For redis you can either specify an ioredis compatible url like this
|
||||
REDIS_URL=redis://tasks.redis:6379
|
||||
# or alternatively, if you would like to provide additional connection options,
|
||||
# use a base64 encoded JSON connection option object. Refer to the ioredis documentation
|
||||
# for a list of available options.
|
||||
# Example: Use Redis Sentinel for high availability
|
||||
# {"sentinels":[{"host":"sentinel-0","port":26379},{"host":"sentinel-1","port":26379}],"name":"mymaster"}
|
||||
# REDIS_URL=ioredis://eyJzZW50aW5lbHMiOlt7Imhvc3QiOiJzZW50aW5lbC0wIiwicG9ydCI6MjYzNzl9LHsiaG9zdCI6InNlbnRpbmVsLTEiLCJwb3J0IjoyNjM3OX1dLCJuYW1lIjoibXltYXN0ZXIifQ==
|
||||
|
||||
# URL should point to the fully qualified, publicly accessible URL. If using a
|
||||
# proxy the port in URL and PORT may be different.
|
||||
OUTLINE_URL=https://outline.${DOMAIN}
|
||||
OUTLINE_PORT=3000
|
||||
|
||||
# See [documentation](docs/SERVICES.md) on running a separate collaboration
|
||||
# server, for normal operation this does not need to be set.
|
||||
COLLABORATION_URL=
|
||||
|
||||
# Specify what storage system to use. Possible value is one of "s3" or "local".
|
||||
# For "local", the avatar images and document attachments will be saved on local disk.
|
||||
FILE_STORAGE=local
|
||||
|
||||
# If "local" is configured for FILE_STORAGE above, then this sets the parent directory under
|
||||
# which all attachments/images go. Make sure that the process has permissions to create
|
||||
# this path and also to write files to it.
|
||||
FILE_STORAGE_LOCAL_ROOT_DIR=/var/lib/outline/data
|
||||
|
||||
# Maximum allowed size for the uploaded attachment.
|
||||
FILE_STORAGE_UPLOAD_MAX_SIZE=262144000
|
||||
|
||||
# Override the maximum size of document imports, generally this should be lower
|
||||
# than the document attachment maximum size.
|
||||
FILE_STORAGE_IMPORT_MAX_SIZE=
|
||||
|
||||
# Override the maximum size of workspace imports, these can be especially large
|
||||
# and the files are temporary being automatically deleted after a period of time.
|
||||
FILE_STORAGE_WORKSPACE_IMPORT_MAX_SIZE=
|
||||
|
||||
# –––––––––––––– AUTHENTICATION ––––––––––––––
|
||||
|
||||
# Third party signin credentials, at least ONE OF EITHER Google, Slack,
|
||||
# or Microsoft is required for a working installation or you'll have no sign-in
|
||||
# options.
|
||||
|
||||
# To configure Google auth, you'll need to create an OAuth Client ID at
|
||||
# => https://console.cloud.google.com/apis/credentials
|
||||
#
|
||||
# When configuring the Client ID, add an Authorized redirect URI:
|
||||
# https://<URL>/auth/google.callback
|
||||
GOOGLE_CLIENT_ID=
|
||||
GOOGLE_CLIENT_SECRET=
|
||||
|
||||
SLACK_CLIENT_ID=
|
||||
SLACK_CLIENT_SECRET=
|
||||
+13
-2
@@ -120,7 +120,7 @@ celerybeat.pid
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.env*
|
||||
.env_encoded
|
||||
.venv
|
||||
env/
|
||||
@@ -165,10 +165,21 @@ cython_debug/
|
||||
# production.yml
|
||||
|
||||
cache/
|
||||
config/
|
||||
data-node/
|
||||
meili_data*/
|
||||
privatebin-data/
|
||||
# postgres-data/
|
||||
minio-data/
|
||||
usersfile
|
||||
.DS_Store
|
||||
.DS_Store
|
||||
fstab
|
||||
|
||||
kubernetes/talos/kubeconfig.yaml
|
||||
kubernetes/talos/kubeconfig
|
||||
kubernetes/talos/config
|
||||
kubernetes/talos/_out/
|
||||
kubernetes/config/
|
||||
kubernetes/_out/
|
||||
swarm/seafile/seafile-data/
|
||||
swarm/seafile/seafile-mysql/db/
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
[submodule "LibreChat"]
|
||||
path = LibreChat
|
||||
url = https://github.com/furyhawk/LibreChat.git
|
||||
[submodule "emqx-docker"]
|
||||
path = emqx-docker
|
||||
url = https://github.com/furyhawk/emqx-docker.git
|
||||
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"makefile.configureOnOpen": false
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
# AGENTS.md
|
||||
|
||||
## Purpose
|
||||
- This repository is primarily infrastructure-as-code for Docker Compose, Docker Swarm, Kubernetes, Helm, and Ansible.
|
||||
- There is also a small Python Flask service in `webhook/` and a Streamlit app in `src/`.
|
||||
- Prefer narrow, low-risk edits. Many files are deployment manifests where a small typo can break production behavior.
|
||||
|
||||
## Agent Priorities
|
||||
- Preserve the existing structure and conventions of the file you are editing.
|
||||
- Favor minimal diffs over broad refactors.
|
||||
- Do not rotate secrets, change domains, or alter deployment targets unless the task explicitly requires it.
|
||||
- Treat `archive/` as historical unless the task explicitly mentions it.
|
||||
- When changing runtime configuration, update only the active path (`compose/`, `swarm/`, `cluster/`, `ansible/`, `webhook/`, `src/`) relevant to the request.
|
||||
|
||||
## Rule Files
|
||||
- No `.cursor/rules/` directory was found.
|
||||
- No `.cursorrules` file was found.
|
||||
- No `.github/copilot-instructions.md` file was found.
|
||||
- This file therefore acts as the main agent guidance for the repository.
|
||||
|
||||
## Repository Areas
|
||||
- `makefile`: top-level operator commands for Compose and Swarm deploys.
|
||||
- `compose.yml` + `compose/`: Docker Compose configuration assembled via `include:`.
|
||||
- `swarm/`: Docker Swarm stacks, environment-driven labels, and Traefik config.
|
||||
- `cluster/`: Kubernetes manifests and Helm charts.
|
||||
- `ansible/`: playbooks and RKE2 automation.
|
||||
- `webhook/`: Poetry-managed Flask app.
|
||||
- `src/`: Streamlit app and Python requirements.
|
||||
- `scripts/`: setup, build, and smoke-test scripts.
|
||||
|
||||
## Build Commands
|
||||
- Full local compose stack: `make serve`
|
||||
- Stop local compose stack: `make down`
|
||||
- Validate merged compose config: `docker compose -f compose.yml config`
|
||||
- Bring local compose stack up manually: `docker compose -f compose.yml up -d --build --pull always`
|
||||
- Legacy CI-style compose build path: `./scripts/build.sh`
|
||||
- Local Streamlit app only: `streamlit run src/app.py`
|
||||
- Local webhook app only: `cd webhook && poetry run python http_server.py`
|
||||
- Swarm core deploy: `make deploy-core`
|
||||
- Swarm app deploy: `make deploy-apps`
|
||||
- Swarm services deploy: `make deploy-services`
|
||||
- Ansible RKE2 cluster bootstrap: `cd ansible/rke2 && ansible-playbook site.yaml -i inventory/hosts.ini --key-file ~/.ssh/id_rsa -K`
|
||||
|
||||
## Lint And Validation Commands
|
||||
- There is no repo-wide lint target or CI workflow checked into the repository.
|
||||
- There are no configured `ruff`, `black`, `flake8`, `mypy`, `yamllint`, `ansible-lint`, or `pytest` configs in the root.
|
||||
- Use syntax and render validation that matches the area you changed.
|
||||
- Compose validation: `docker compose -f compose.yml config`
|
||||
- Swarm file validation: `docker stack deploy --compose-file ./swarm/<stack>.yml <stack> --dry-run` is not available in Docker Swarm, so use `docker compose config` patterns where possible and review label/env interpolation carefully.
|
||||
- Helm chart render check: `helm template test-release cluster/coder-chart`
|
||||
- Helm chart lint check: `helm lint cluster/coder-chart`
|
||||
- Helm dependency check for `cluster/code-server`: `helm dependency update cluster/code-server`
|
||||
- Kubernetes manifest spot check: `kubectl apply --dry-run=client -f <file>`
|
||||
- Ansible syntax check: `ansible-playbook --syntax-check <playbook> -i <inventory>`
|
||||
- Python webhook dependency install: `cd webhook && poetry install`
|
||||
- Python webhook quick import/run check: `cd webhook && poetry run python http_server.py`
|
||||
|
||||
## Test Commands
|
||||
- Main end-to-end smoke test script: `./scripts/test.sh`
|
||||
- Legacy CI path: `./scripts/travis.sh`
|
||||
- The smoke test expects a populated `.env`, reachable hosts, and a running local Traefik/Compose environment.
|
||||
- It verifies redirects and dashboard auth using values from `.env`.
|
||||
- Helm chart test hook exists for `cluster/coder-chart`; after install, run: `helm test <release-name>`
|
||||
- There are example/test deployment files under `test/`, but no unified automated test runner is wired to them.
|
||||
- There are currently no checked-in Python unit tests for `webhook/` or `src/`.
|
||||
|
||||
## Running A Single Test
|
||||
- There is no first-class single-test command for the main smoke suite in `./scripts/test.sh`; it is a single shell script.
|
||||
- To run one smoke assertion, copy the relevant `curl` command from `./scripts/test.sh` and execute it directly.
|
||||
- For Helm, the narrowest useful check is a single chart render/lint:
|
||||
- `helm lint cluster/coder-chart`
|
||||
- `helm template test-release cluster/coder-chart`
|
||||
- For a single Kubernetes manifest, use: `kubectl apply --dry-run=client -f path/to/file.yaml`
|
||||
- For a single Ansible playbook, use: `ansible-playbook --syntax-check path/to/playbook.yml -i inventory`
|
||||
- If Python tests are added later, the expected targeted form would be: `cd webhook && poetry run pytest path/to/test_file.py::test_name`
|
||||
- Do not claim pytest support exists today unless you also add the test dependency and test files.
|
||||
|
||||
## Working Safely With Config
|
||||
- Many YAML files interpolate env vars like `${DOMAINNAME}`, `${POSTGRES_PASSWORD}`, or `${VAR?Variable not set}`.
|
||||
- Preserve existing variable names exactly; accidental renames will break deployments.
|
||||
- Prefer existing anchors and aliases, such as `x-environment` blocks, over duplicating env declarations.
|
||||
- Preserve quoting style when editing Traefik labels or shell-sensitive strings.
|
||||
- Be careful with `$` escaping inside labels and regex replacements.
|
||||
- Avoid changing published ports, hostnames, or Traefik router rules unless explicitly requested.
|
||||
|
||||
## Code Style: General
|
||||
- Match the local style of the file you touch rather than imposing a new formatter.
|
||||
- Keep YAML keys, Helm templates, and Ansible tasks visually aligned and easy to scan.
|
||||
- Prefer small, direct changes over restructuring files.
|
||||
- Keep comments only when they explain a non-obvious operational constraint.
|
||||
- Reuse existing naming patterns like `api_server`, `postgres_db`, `streamlit-fin`, and `deploy-core`.
|
||||
- Preserve file-specific indentation conventions: YAML uses spaces, Make uses tabs for recipe lines, shell scripts use the existing shell style.
|
||||
|
||||
## Imports
|
||||
- In Python, keep imports at the top of the file.
|
||||
- Prefer standard library imports first, then third-party imports.
|
||||
- Avoid unused imports.
|
||||
- Follow the existing concise import style unless you are already refactoring the file for readability.
|
||||
- When touching `webhook/http_server.py` or `src/app.py`, it is acceptable to improve import ordering if part of a necessary edit.
|
||||
|
||||
## Formatting
|
||||
- YAML: two-space indentation, no tab characters.
|
||||
- Helm templates: preserve current whitespace trimming markers like `{{-` and `-}}`.
|
||||
- Python: use four-space indentation even though some existing files are inconsistent.
|
||||
- Shell: keep `set -e` or `set -ev` when present; do not remove safety flags casually.
|
||||
- Markdown: keep bullets short and operational.
|
||||
- Do not introduce large-scale formatting churn in files that are otherwise working.
|
||||
|
||||
## Types And Data Shapes
|
||||
- Python code in this repo is lightly typed today; there is no mypy configuration.
|
||||
- Add type hints when they clarify new or changed Python logic, but do not force a repo-wide typing conversion.
|
||||
- For YAML, respect the existing scalar style and only quote when interpolation, special characters, or parser ambiguity require it.
|
||||
- Keep environment values as strings unless the target format clearly expects booleans or integers.
|
||||
- In Helm values and templates, preserve the expected shape of objects and lists; changing key structure is usually a breaking change.
|
||||
|
||||
## Naming Conventions
|
||||
- Docker Compose services commonly use snake_case or hyphenated names already established in the file; follow the surrounding pattern.
|
||||
- Ansible task names should be descriptive imperative phrases.
|
||||
- Kubernetes resource names should stay lowercase and DNS-safe.
|
||||
- Python function names should be `snake_case`.
|
||||
- Python constants and environment variable names should be uppercase.
|
||||
- Keep public-facing hostnames and router names consistent with nearby services.
|
||||
|
||||
## Error Handling
|
||||
- Do not swallow errors silently in new Python code.
|
||||
- Avoid bare `except:`; catch specific exceptions where practical.
|
||||
- Return clear HTTP responses in Flask handlers.
|
||||
- In shell scripts, prefer failing fast over ignoring command failures.
|
||||
- In Ansible, use `register`, `when`, and `changed_when` intentionally; do not mark tasks changed without a reason.
|
||||
- In deployment config, prefer explicit required vars like `${VAR?Variable not set}` for critical settings.
|
||||
|
||||
## Python-Specific Notes
|
||||
- `webhook/http_server.py` currently uses minimal Flask code and would benefit from improved formatting and more explicit error handling when modified.
|
||||
- `src/app.py` contains Streamlit logic with some inconsistent spacing and a bare `except:`; fix such issues only when your change touches that area.
|
||||
- Preserve current runtime entrypoints unless the task explicitly changes startup behavior.
|
||||
|
||||
## Ansible-Specific Notes
|
||||
- Prefer fully qualified module names such as `ansible.builtin.command` where the surrounding file already uses them.
|
||||
- Keep playbooks idempotent where possible.
|
||||
- Avoid unnecessary `shell` usage when `command`, `template`, `copy`, or dedicated modules work.
|
||||
- Respect existing inventory and variable layout under `ansible/rke2/inventory/`.
|
||||
- Be cautious with `become_user`, `changed_when`, and cluster bootstrap sequencing.
|
||||
|
||||
## Helm And Kubernetes Notes
|
||||
- Render Helm templates locally before making broad chart changes.
|
||||
- Preserve helper usage like `include`, `toYaml`, `nindent`, and existing label helpers.
|
||||
- Avoid renaming values keys unless you also update every template consumer.
|
||||
- Maintain probe, volume, and securityContext structure unless there is a concrete reason to change them.
|
||||
- For plain manifests, keep apiVersion, kind, metadata, and spec ordering consistent with nearby files.
|
||||
|
||||
## Docker And Traefik Notes
|
||||
- Traefik labels are heavily used and are sensitive to quoting and interpolation.
|
||||
- Keep router, middleware, and service label names consistent across related files.
|
||||
- Prefer extending shared env blocks and shared network definitions over one-off duplication.
|
||||
- Be careful with `host-gateway`, mounted Docker sockets, and certificate storage paths.
|
||||
- Do not commit real secrets into compose, swarm, or manifest files.
|
||||
|
||||
## When Unsure
|
||||
- Validate the smallest affected surface first.
|
||||
- Prefer commands that only render or syntax-check before commands that deploy.
|
||||
- If a task spans multiple deployment systems, confirm which path is active before editing all of them.
|
||||
- Document assumptions in the final response if the repo does not provide a definitive source of truth.
|
||||
@@ -3,9 +3,10 @@
|
||||
# Webapp + Streamlit + Traefik + Docker
|
||||
This simple project uses Traefik as a reverse proxy to a Streamlit application and handles SSL certs with Lets Encrypt.
|
||||
|
||||
- [Chat](https://chat.furyhawk.lol/): Chat with AI.
|
||||
- [AI](https://bot.furyhawk.lol/): OpenwebUI.
|
||||
- ~~[Chat](https://chat.furyhawk.lol/): Chat with AI.~~
|
||||
- [Stock Analysis Assistant](https://fin.furyhawk.lol/): AI assistant using GROQ and llama3.
|
||||
- [Redlib](https://redlib.furyhawk.lol/): Reddit libre.
|
||||
- ~~[Redlib](https://redlib.furyhawk.lol/): Reddit libre.~~
|
||||
- [Blog](https://info.furyhawk.lol/)
|
||||
- [Beyond All Information](https://bai.furyhawk.lol/): analyse your [Beyond All Reason](https://www.beyondallreason.info/) games.
|
||||
- [CheatSheets](https://cheat.furyhawk.lol/): Collection of cheatsheets.
|
||||
@@ -17,19 +18,31 @@ This simple project uses Traefik as a reverse proxy to a Streamlit application a
|
||||
|
||||
## Requirements
|
||||
- Docker Compose
|
||||
- Build for ARM64 platform
|
||||
- Build for ARM64/x86 platform
|
||||
|
||||
## Production Deployment
|
||||
1. In `compose/traefik/traefik.yml`, change `example@test.com` to your email.
|
||||
2. In `compose/traefik/traefik.yml`, change `example.com` to your domain.
|
||||
3. `sudo apt-get install build-essential`
|
||||
4. `mdkir ~/st-sync`
|
||||
5. `mdkir ~/.thelounge`
|
||||
6. `touch cache/bar_cache.sqlite`
|
||||
7. `touch cache/short_cache.sqlite`
|
||||
8. `cp .env.example .env`
|
||||
9. `cp usersfile.example usersfile`
|
||||
10. `make serve`
|
||||
1. `git clone https://github.com/furyhawk/cloudy.git`
|
||||
2. `cd cloudy`
|
||||
3. `git submodule update --init --recursive`
|
||||
4. In `compose/traefik/traefik.yml`, change `example@test.com` to your email.
|
||||
5. In `compose/traefik/traefik.yml`, change `example.com` to your domain.
|
||||
6. `sudo apt-get install build-essential` (if not already installed) to use makefile.
|
||||
7. `mkdir ~/st-sync` syncthing folder.
|
||||
8. `mkdir ~/site` public site folder.
|
||||
9. `mkdir ./compose/config` to store config.
|
||||
10. `cp .env.example ./compose/.env && cp .env ~/config/.env`
|
||||
11. `cp ./compose/config/conf.php ~/config/conf.php`
|
||||
12. `cp usersfile.example ./compose/usersfile`
|
||||
13. `make serve`
|
||||
|
||||
## Docker Swarm Deployment
|
||||
```
|
||||
docker swarm init
|
||||
docker network create -d overlay --attachable traefik-public
|
||||
make deploy-core
|
||||
|
||||
docker service logs core_traefik --details
|
||||
```
|
||||
|
||||
### Notes:
|
||||
```yaml
|
||||
@@ -43,3 +56,29 @@ This simple project uses Traefik as a reverse proxy to a Streamlit application a
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-auth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/,test2:$$apr1$$d9hr9HBB$$4HxwgUir3HP4EsggP/QNo0"
|
||||
```
|
||||
|
||||
### TODO:
|
||||
|
||||
middleware:
|
||||
```
|
||||
# Enable HTTP Strict Transport Security (HSTS) to force clients to always connect via HTTPS
|
||||
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
|
||||
|
||||
# Enable cross-site filter (XSS) and tell browser to block detected attacks
|
||||
X-XSS-Protection "1; mode=block"
|
||||
|
||||
# Prevent some browsers from MIME-sniffing a response away from the declared Content-Type
|
||||
X-Content-Type-Options "nosniff"
|
||||
|
||||
# Disable some features
|
||||
Permissions-Policy "accelerometer=(),ambient-light-sensor=(),autoplay=(),camera=(),encrypted-media=(),focus-without-user-activation=(),geolocation=(),gyroscope=(),magnetometer=(),microphone=(),midi=(),payment=(),picture-in-picture=(),speaker=(),sync-xhr=(),usb=(),vr=()"
|
||||
|
||||
# Disable some features (legacy)
|
||||
Feature-Policy "accelerometer 'none';ambient-light-sensor 'none'; autoplay 'none';camera 'none';encrypted-media 'none';focus-without-user-activation 'none'; geolocation 'none';gyroscope 'none';magnetometer 'none';microphone 'none';midi 'none';payment 'none';picture-in-picture 'none'; speaker 'none';sync-xhr 'none';usb 'none';vr 'none'"
|
||||
|
||||
# Referer
|
||||
Referrer-Policy "no-referrer"
|
||||
|
||||
# X-Robots-Tag
|
||||
X-Robots-Tag "noindex, noarchive, nofollow"
|
||||
```
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
devservers:
|
||||
hosts:
|
||||
node09:
|
||||
ansible_host: 101.100.172.55
|
||||
ansible_port: 9991
|
||||
node00:
|
||||
ansible_host: 101.100.172.55
|
||||
ansible_port: 9999
|
||||
node01:
|
||||
ansible_host: 101.100.172.55
|
||||
ansible_port: 9998
|
||||
|
||||
debian:
|
||||
hosts:
|
||||
node00:
|
||||
ansible_host: 101.100.172.55
|
||||
ansible_port: 9999
|
||||
node01:
|
||||
ansible_host: 101.100.172.55
|
||||
ansible_port: 9998
|
||||
|
||||
local:
|
||||
hosts:
|
||||
node00:
|
||||
ansible_host: 192.168.50.114
|
||||
ansible_port: 22
|
||||
node01:
|
||||
ansible_host: 192.168.50.68
|
||||
ansible_port: 22
|
||||
node02:
|
||||
ansible_host: 192.168.50.56
|
||||
ansible_port: 22
|
||||
|
||||
test:
|
||||
hosts:
|
||||
node05:
|
||||
ansible_host: 192.168.50.205
|
||||
ansible_port: 22
|
||||
node09:
|
||||
ansible_host: 192.168.50.209
|
||||
ansible_port: 22
|
||||
|
||||
dev:
|
||||
hosts:
|
||||
dev301:
|
||||
ansible_host: 192.168.50.71
|
||||
dev302:
|
||||
ansible_host: 192.168.50.170
|
||||
|
||||
prod:
|
||||
hosts:
|
||||
dc00:
|
||||
ansible_host: 192.168.50.210
|
||||
ansible_user: user
|
||||
dc01:
|
||||
ansible_host: 192.168.50.201
|
||||
ansible_user: user
|
||||
dc02:
|
||||
ansible_host: 192.168.50.202
|
||||
ansible_user: user
|
||||
dc03:
|
||||
ansible_host: 192.168.50.203
|
||||
ansible_user: user
|
||||
dc04:
|
||||
ansible_host: 192.168.50.204
|
||||
ansible_user: user
|
||||
dc05:
|
||||
ansible_host: 192.168.50.205
|
||||
ansible_user: user
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
docker:
|
||||
hosts:
|
||||
docker01:
|
||||
ansible_host: 192.168.200.222
|
||||
ansible_user: 'ubuntu'
|
||||
ansible_become: true
|
||||
ansible_become_method: sudo
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
- name: Install Docker on Ubuntu
|
||||
hosts: all
|
||||
become: true
|
||||
roles:
|
||||
- docker_install
|
||||
- portainer_deploy
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
- name: Restart Docker
|
||||
ansible.builtin.systemd:
|
||||
name: docker
|
||||
state: restarted
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
- name: Ensure apt is using HTTPS
|
||||
ansible.builtin.apt:
|
||||
name: "{{ item }}"
|
||||
state: present
|
||||
loop:
|
||||
- apt-transport-https
|
||||
- ca-certificates
|
||||
- curl
|
||||
- software-properties-common
|
||||
|
||||
- name: Add Docker GPG key
|
||||
ansible.builtin.apt_key:
|
||||
url: "https://download.docker.com/linux/ubuntu/gpg"
|
||||
state: present
|
||||
|
||||
- name: Add Docker repository
|
||||
ansible.builtin.apt_repository:
|
||||
repo: "{{ docker_apt_repository }}"
|
||||
state: present
|
||||
|
||||
- name: Install Docker CE
|
||||
ansible.builtin.apt:
|
||||
name: docker-ce
|
||||
state: present
|
||||
update_cache: true
|
||||
|
||||
- name: Configure Docker daemon options
|
||||
ansible.builtin.template:
|
||||
src: "templates/docker_daemon.json.j2"
|
||||
dest: "/etc/docker/daemon.json"
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
mode: '0755' # Optional file permissions
|
||||
notify: Restart Docker
|
||||
|
||||
- name: Ensure Docker service is enabled and running
|
||||
ansible.builtin.systemd:
|
||||
name: docker
|
||||
enabled: true
|
||||
state: started
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"storage-driver": "{{ docker_daemon_options['storage-driver'] }}"
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
docker_apt_release_channel: "stable"
|
||||
docker_apt_repository: "deb [arch=amd64] https://download.docker.com/linux/ubuntu {{ ansible_distribution_release }} stable"
|
||||
docker_daemon_options:
|
||||
storage-driver: "overlay2"
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
- name: Start Portainer
|
||||
community.docker.docker_compose:
|
||||
project_src: /home/ubuntu/docker-compose/portainer
|
||||
state: present
|
||||
restarted: true
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
- name: Ensure docker-compose is installed
|
||||
ansible.builtin.package:
|
||||
name: docker-compose
|
||||
state: present
|
||||
|
||||
- name: Ensure Docker service is running
|
||||
ansible.builtin.service:
|
||||
name: docker
|
||||
state: started
|
||||
enabled: true
|
||||
|
||||
- name: Setup Portainer directory
|
||||
ansible.builtin.file:
|
||||
path: /home/ubuntu/docker-compose/portainer
|
||||
state: directory
|
||||
mode: '0755' # Optional file permissions
|
||||
owner: ubuntu # Optional ownership
|
||||
group: ubuntu # Optional group ownership
|
||||
|
||||
- name: Deploy Portainer using Docker Compose
|
||||
ansible.builtin.template:
|
||||
src: "templates/docker_compose.yaml.j2"
|
||||
dest: "/home/ubuntu/docker-compose/portainer/docker-compose.yaml"
|
||||
mode: '0755' # Optional file permissions
|
||||
owner: ubuntu # Optional ownership
|
||||
group: ubuntu # Optional group ownership
|
||||
notify:
|
||||
- Start Portainer
|
||||
|
||||
- name: Run Portainer docker-compose up
|
||||
community.docker.docker_compose:
|
||||
project_src: /home/ubuntu/docker-compose/portainer
|
||||
state: present
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
version: '3.3'
|
||||
services:
|
||||
portainer:
|
||||
image: portainer/portainer-ce:{{ portainer_version }}
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- portainer_data:/data
|
||||
ports:
|
||||
- "9000:9000"
|
||||
restart: always
|
||||
|
||||
volumes:
|
||||
portainer_data:
|
||||
@@ -0,0 +1,2 @@
|
||||
---
|
||||
portainer_version: "latest"
|
||||
@@ -0,0 +1,52 @@
|
||||
---
|
||||
- name: Deploy Docker Container with Docker Compose
|
||||
hosts: all
|
||||
become: true
|
||||
tasks:
|
||||
- name: Ensure Docker is installed
|
||||
ansible.builtin.package:
|
||||
name: docker
|
||||
state: present
|
||||
|
||||
- name: Ensure Docker service is running
|
||||
ansible.builtin.service:
|
||||
name: docker
|
||||
state: started
|
||||
enabled: true
|
||||
|
||||
- name: Create a directory for Docker Compose files
|
||||
ansible.builtin.file:
|
||||
path: /home/ubuntu/ansible-docker/docker-compose
|
||||
state: directory
|
||||
mode: '0755' # Optional file permissions
|
||||
owner: ubuntu # Optional ownership
|
||||
group: ubuntu # Optional group ownership
|
||||
|
||||
- name: Create a directory for Nginx website files
|
||||
ansible.builtin.file:
|
||||
path: /home/ubuntu/docker/nginx/web
|
||||
state: directory
|
||||
mode: '0755' # Optional file permissions
|
||||
owner: ubuntu # Optional ownership
|
||||
group: ubuntu # Optional group ownership
|
||||
|
||||
- name: Copy docker-compose to remote host
|
||||
ansible.builtin.copy:
|
||||
src: /home/ubuntu/nginx/docker-compose.yaml
|
||||
dest: /home/ubuntu/ansible-docker/docker-compose/docker-compose.yaml
|
||||
mode: '0755' # Optional file permissions
|
||||
owner: ubuntu # Optional ownership
|
||||
group: ubuntu # Optional group ownership
|
||||
|
||||
- name: Copy Nginx website folder to remote host # copies a folder - note no file extension
|
||||
ansible.builtin.copy:
|
||||
src: /home/ubuntu/nginx/website
|
||||
dest: /home/ubuntu/docker/nginx/web
|
||||
mode: '0755' # Optional file permissions
|
||||
owner: ubuntu # Optional ownership
|
||||
group: ubuntu # Optional group ownership
|
||||
|
||||
- name: Start Docker Compose
|
||||
community.docker.docker_compose:
|
||||
project_src: /home/ubuntu/ansible-docker/docker-compose
|
||||
state: present
|
||||
@@ -0,0 +1,24 @@
|
||||
---
|
||||
- name: Undo Docker Compose Deployment
|
||||
hosts: all
|
||||
become: true
|
||||
tasks:
|
||||
- name: Stop Docker Container
|
||||
community.docker.docker_compose:
|
||||
project_src: /home/ubuntu/ansible-docker/docker-compose
|
||||
state: absent
|
||||
|
||||
- name: Remove Docker Compose file
|
||||
ansible.builtin.file:
|
||||
path: /home/ubuntu/ansible-docker/docker-compose/docker-compose.yml
|
||||
state: absent
|
||||
|
||||
- name: Remove Docker Compose directory
|
||||
ansible.builtin.file:
|
||||
path: /home/ubuntu/ansible-docker
|
||||
state: absent
|
||||
|
||||
- name: Remove Website directory
|
||||
ansible.builtin.file:
|
||||
path: /home/ubuntu/docker/nginx/web
|
||||
state: absent
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
docker:
|
||||
hosts:
|
||||
docker01:
|
||||
ansible_host: 192.168.200.50
|
||||
ansible_user: 'ubuntu'
|
||||
ansible_become: true
|
||||
ansible_become_method: sudo
|
||||
@@ -0,0 +1,31 @@
|
||||
version: "3.9"
|
||||
services:
|
||||
web:
|
||||
image: nginx
|
||||
container_name: jimsgarage
|
||||
volumes:
|
||||
- /home/ubuntu/docker/nginx/templates:/etc/nginx/templates
|
||||
- /home/ubuntu/docker/nginx/web/website:/usr/share/nginx/html
|
||||
environment:
|
||||
- NGINX_HOST=nginx.jimsgarage.co.uk
|
||||
- NGINX_PORT=80
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.nginx.entrypoints=http"
|
||||
- "traefik.http.routers.nginx.rule=Host(`nginx.jimsgarage.co.uk`)"
|
||||
- "traefik.http.middlewares.nginx-https-redirect.redirectscheme.scheme=https"
|
||||
- "traefik.http.routers.nginx.middlewares=nginx-https-redirect"
|
||||
- "traefik.http.routers.nginx-secure.entrypoints=https"
|
||||
- "traefik.http.routers.nginx-secure.rule=Host(`nginx.jimsgarage.co.uk`)"
|
||||
- "traefik.http.routers.nginx-secure.tls=true"
|
||||
- "traefik.http.routers.nginx-secure.service=nginx"
|
||||
- "traefik.http.services.nginx.loadbalancer.server.port=80"
|
||||
- "traefik.docker.network=proxy"
|
||||
networks:
|
||||
proxy:
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
|
||||
networks:
|
||||
proxy:
|
||||
external: true
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 148 KiB |
@@ -0,0 +1,108 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Jim's Garage Ansible Demo</title>
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
|
||||
<style>
|
||||
.hero {
|
||||
background: url(Jims-Garage-1.png) no-repeat center center;
|
||||
background-size: cover;
|
||||
height: 400px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: white;
|
||||
text-shadow: 2px 2px 5px rgba(0, 0, 0, 0.7);
|
||||
}
|
||||
|
||||
.features {
|
||||
margin-top: 50px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.feature {
|
||||
padding: 20px;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.feature:hover {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.footer {
|
||||
background-color: #333;
|
||||
color: white;
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
bottom: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Navigation Bar -->
|
||||
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
|
||||
<a class="navbar-brand" href="#">My Webpage</a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav ml-auto">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#home">Home</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#features">Features</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#contact">Contact</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Hero Section -->
|
||||
<div class="hero" id="home">
|
||||
<h1>Welcome to Jim's Garage Ansible Demo</h1>
|
||||
</div>
|
||||
|
||||
<!-- Features Section -->
|
||||
<div class="container features" id="features">
|
||||
<h2>Our Features</h2>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="feature">
|
||||
<i class="fas fa-cogs fa-3x"></i>
|
||||
<h4>Feature 1</h4>
|
||||
<p>Dynamic and interactive elements.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="feature">
|
||||
<i class="fas fa-bolt fa-3x"></i>
|
||||
<h4>Feature 2</h4>
|
||||
<p>Responsive design and transitions.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="feature">
|
||||
<i class="fas fa-heart fa-3x"></i>
|
||||
<h4>Feature 3</h4>
|
||||
<p>Engaging user experiences.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Footer Section -->
|
||||
<div class="footer">
|
||||
<p>© 2024 My Webpage. All rights reserved.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,57 @@
|
||||
---
|
||||
- name: Update Windows, Arch Linux, and Ubuntu
|
||||
hosts: all
|
||||
tasks:
|
||||
- name: Gather facts
|
||||
ansible.builtin.setup:
|
||||
|
||||
- name: Update Windows
|
||||
when: ansible_facts['os_family'] == 'Windows'
|
||||
ansible.windows.win_updates:
|
||||
category_names:
|
||||
- SecurityUpdates
|
||||
- UpdateRollups
|
||||
- CriticalUpdates
|
||||
state: installed
|
||||
register: win_update_result
|
||||
|
||||
- name: Check if Windows requires a reboot
|
||||
when: win_update_result.changed and win_update_result.reboot_required | default(false)
|
||||
ansible.windows.win_reboot:
|
||||
reboot_timeout: 600
|
||||
register: win_reboot_result
|
||||
|
||||
- name: Update Arch Linux
|
||||
when: ansible_facts['os_family'] == 'Arch'
|
||||
community.general.pacman:
|
||||
update_cache: true
|
||||
upgrade: true
|
||||
register: arch_update_result
|
||||
|
||||
- name: Check if Arch Linux requires a reboot
|
||||
when: ansible_facts['os_family'] == 'Arch' and arch_update_result.changed
|
||||
ansible.builtin.stat:
|
||||
path: /run/reboot-required
|
||||
register: arch_reboot_required
|
||||
|
||||
- name: Reboot Arch Linux if required
|
||||
when: arch_reboot_required.stat.exists | default(false)
|
||||
ansible.builtin.reboot:
|
||||
reboot_timeout: 600
|
||||
|
||||
- name: Update Ubuntu
|
||||
when: ansible_facts['os_family'] == 'Debian'
|
||||
ansible.builtin.apt:
|
||||
upgrade: dist
|
||||
update_cache: true
|
||||
|
||||
- name: Check if a reboot is required on Ubuntu
|
||||
when: ansible_facts['os_family'] == 'Debian'
|
||||
ansible.builtin.stat:
|
||||
path: /var/run/reboot-required
|
||||
register: ubuntu_reboot_required
|
||||
|
||||
- name: Reboot Ubuntu if required
|
||||
when: ubuntu_reboot_required.stat.exists | default(false)
|
||||
ansible.builtin.reboot:
|
||||
reboot_timeout: 600
|
||||
@@ -0,0 +1,14 @@
|
||||
arch:
|
||||
hosts:
|
||||
arch01:
|
||||
ansible_host: 192.168.200.214
|
||||
ansible_user: 'root'
|
||||
ansible_python_interpreter: /usr/bin/python3
|
||||
|
||||
docker:
|
||||
hosts:
|
||||
docker01:
|
||||
ansible_host: 192.168.200.50
|
||||
ansible_user: 'ubuntu'
|
||||
ansible_become: true
|
||||
ansible_become_method: sudo
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
collections:
|
||||
- name: ansible.utils
|
||||
- name: community.general
|
||||
- name: ansible.posix
|
||||
- name: kubernetes.core
|
||||
@@ -0,0 +1,18 @@
|
||||
os: "linux"
|
||||
arch: "amd64"
|
||||
|
||||
kube_vip_version: "v0.8.0"
|
||||
vip_interface: eth0
|
||||
vip: 192.168.3.50
|
||||
|
||||
metallb_version: v0.13.12
|
||||
lb_range: 192.168.3.80-192.168.3.90
|
||||
lb_pool_name: first-pool
|
||||
|
||||
rke2_version: "v1.29.4+rke2r1"
|
||||
rke2_install_dir: "/usr/local/bin"
|
||||
rke2_binary_url: "https://github.com/rancher/rke2/releases/download/{{ rke2_version }}/rke2.linux-amd64"
|
||||
|
||||
ansible_user: ubuntu
|
||||
ansible_become: true
|
||||
ansible_become_method: sudo
|
||||
@@ -0,0 +1,11 @@
|
||||
# Make sure Ansible host has access to these devices
|
||||
# Good idea to snapshot all machines and deploy uing cloud-init
|
||||
|
||||
[servers]
|
||||
server1 ansible_host=192.168.3.21
|
||||
server2 ansible_host=192.168.3.22
|
||||
server3 ansible_host=192.168.3.23
|
||||
|
||||
[agents]
|
||||
agent1 ansible_host=192.168.3.24
|
||||
agent2 ansible_host=192.168.3.25
|
||||
@@ -0,0 +1,17 @@
|
||||
# Copy agent config to all agents - we need to change agent2 & 3 later with the token
|
||||
- name: Deploy RKE2 Agent Configuration
|
||||
ansible.builtin.template:
|
||||
src: templates/rke2-agent-config.j2
|
||||
dest: /etc/rancher/rke2/config.yaml
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
when: inventory_hostname in groups['agents']
|
||||
|
||||
# Check agents have restarted to pick up config
|
||||
- name: Ensure RKE2 agents are enabled and running
|
||||
ansible.builtin.systemd:
|
||||
name: rke2-agent
|
||||
enabled: true
|
||||
state: restarted
|
||||
daemon_reload: true
|
||||
@@ -0,0 +1,5 @@
|
||||
write-kubeconfig-mode: "0644"
|
||||
token: {{ hostvars['server1']['token'] }}
|
||||
server: https://{{ hostvars['server1']['ansible_host'] }}:9345
|
||||
node-label:
|
||||
- "agent=true"
|
||||
@@ -0,0 +1,53 @@
|
||||
# Copy server config with token to all servers except server 1 (this has token)
|
||||
- name: Deploy RKE2 server Configuration
|
||||
ansible.builtin.template:
|
||||
src: templates/rke2-server-config.j2
|
||||
dest: /etc/rancher/rke2/config.yaml
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
when: inventory_hostname != groups['servers'][0]
|
||||
|
||||
# Keep checking the cluster API until it's functioning (deployed)
|
||||
- name: Wait for cluster API to be ready (can take 5-10 mins depending on internet/hardware)
|
||||
ansible.builtin.command:
|
||||
cmd: "kubectl get nodes"
|
||||
register: kubectl_output
|
||||
until: "'connection refused' not in kubectl_output.stderr"
|
||||
retries: 120
|
||||
delay: 10
|
||||
changed_when: true
|
||||
become_user: "{{ ansible_user }}"
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
|
||||
# Use kubectl to deploy yaml. Perhaps this can be added to the manifest folder initially
|
||||
- name: Apply kube vip configuration file
|
||||
ansible.builtin.command:
|
||||
cmd: kubectl --kubeconfig /etc/rancher/rke2/rke2.yaml apply -f https://kube-vip.io/manifests/rbac.yaml
|
||||
changed_when: true
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
|
||||
# Apply the kube-vip configration. Perhaps this can be added to the manifest folder initially
|
||||
- name: Apply kube vip configuration file
|
||||
ansible.builtin.command:
|
||||
cmd: kubectl --kubeconfig /etc/rancher/rke2/rke2.yaml apply -f https://raw.githubusercontent.com/kube-vip/kube-vip-cloud-provider/main/manifest/kube-vip-cloud-controller.yaml
|
||||
changed_when: true
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
|
||||
# Check that additional servers are restarted
|
||||
- name: Ensure additional RKE2 servers are enabled and running
|
||||
ansible.builtin.systemd:
|
||||
name: rke2-server
|
||||
enabled: true
|
||||
state: restarted
|
||||
daemon_reload: true
|
||||
when: inventory_hostname != groups['servers'][0]
|
||||
|
||||
# enable additional servers
|
||||
- name: Ensure RKE2 server is enabled and running
|
||||
ansible.builtin.systemd:
|
||||
name: rke2-server
|
||||
enabled: true
|
||||
state: restarted
|
||||
daemon_reload: true
|
||||
when: inventory_hostname != groups['servers'][0]
|
||||
@@ -0,0 +1,10 @@
|
||||
write-kubeconfig-mode: "0644"
|
||||
token: {{ hostvars['server1']['token'] }}
|
||||
server: https://{{ hostvars['server1']['ansible_host'] }}:9345
|
||||
tls-san:
|
||||
- {{ vip }}
|
||||
- {{ hostvars['server1']['ansible_host'] }}
|
||||
- {{ hostvars['server2']['ansible_host'] }}
|
||||
- {{ hostvars['server3']['ansible_host'] }}
|
||||
node-label:
|
||||
- server=true
|
||||
@@ -0,0 +1,60 @@
|
||||
# Wait for Server 1 to be ready before continuing with metallb deployment
|
||||
- name: Wait for k8s nodes with node label 'server=true' to be ready, otherwise we cannot start metallb deployment
|
||||
ansible.builtin.command:
|
||||
cmd: "kubectl wait --for=condition=Ready nodes --selector server=true --timeout=600s"
|
||||
register: nodes_ready
|
||||
retries: 120
|
||||
delay: 10
|
||||
changed_when: true
|
||||
become_user: "{{ ansible_user }}"
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
|
||||
# Create namespace so that we can deploy metallb
|
||||
- name: Apply metallb namespace
|
||||
ansible.builtin.command:
|
||||
cmd: kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/namespace.yaml
|
||||
become_user: "{{ ansible_user }}"
|
||||
changed_when: true
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
|
||||
# Apply metallb manifest
|
||||
- name: Apply metallb manifest
|
||||
ansible.builtin.command:
|
||||
cmd: kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/{{ metallb_version }}/config/manifests/metallb-native.yaml
|
||||
become_user: "{{ ansible_user }}"
|
||||
changed_when: true
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
|
||||
# Wait for metallb deployment pods to be alive before deploying metallb manifests
|
||||
- name: Wait for metallb pods to be ready, otherwise we cannot start metallb deployment
|
||||
ansible.builtin.command:
|
||||
cmd: "kubectl wait --namespace metallb-system --for=condition=ready pod --selector=component=controller --timeout=1800s"
|
||||
changed_when: true
|
||||
become_user: "{{ ansible_user }}"
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
|
||||
# Apply L2 Advertisement for metallb
|
||||
- name: Apply metallb L2 Advertisement
|
||||
ansible.builtin.command:
|
||||
cmd: kubectl apply -f https://raw.githubusercontent.com/JamesTurland/JimsGarage/main/Kubernetes/RKE2/l2Advertisement.yaml
|
||||
become_user: "{{ ansible_user }}"
|
||||
changed_when: true
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
|
||||
# Deploy metal IP Pool to Server 1
|
||||
- name: Copy metallb IPPool to server 1
|
||||
ansible.builtin.template:
|
||||
src: templates/metallb-ippool.j2
|
||||
dest: /home/{{ ansible_user }}/ippool.yaml
|
||||
owner: "{{ ansible_user }}"
|
||||
group: "{{ ansible_user }}"
|
||||
mode: '0755'
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
|
||||
# don't think this will work as nodes are no execute, might need agents first
|
||||
- name: Apply metallb ipppool
|
||||
ansible.builtin.command:
|
||||
cmd: kubectl apply -f /home/{{ ansible_user }}/ippool.yaml
|
||||
become_user: "{{ ansible_user }}"
|
||||
changed_when: true
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
@@ -0,0 +1,8 @@
|
||||
apiVersion: metallb.io/v1beta1
|
||||
kind: IPAddressPool
|
||||
metadata:
|
||||
name: {{ lb_pool_name }}
|
||||
namespace: metallb-system
|
||||
spec:
|
||||
addresses:
|
||||
- {{ lb_range }}
|
||||
@@ -0,0 +1,17 @@
|
||||
# Create directory to deploy kube-vip manifest
|
||||
- name: Create directory for Kube VIP Manifest
|
||||
ansible.builtin.file:
|
||||
path: "/var/lib/rancher/rke2/server/manifests"
|
||||
state: directory
|
||||
mode: '0644'
|
||||
when: inventory_hostname in groups['servers']
|
||||
|
||||
# Copy kube-vip to server 1 manifest folder for auto deployment at bootstrap
|
||||
- name: Deploy Kube VIP Configuration
|
||||
ansible.builtin.template:
|
||||
src: templates/kube-vip-config.j2
|
||||
dest: /var/lib/rancher/rke2/server/manifests/kube-vip.yaml
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
@@ -0,0 +1,88 @@
|
||||
apiVersion: apps/v1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
app.kubernetes.io/name: kube-vip-ds
|
||||
app.kubernetes.io/version: {{ kube_vip_version }}
|
||||
name: kube-vip-ds
|
||||
namespace: kube-system
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: kube-vip-ds
|
||||
template:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
app.kubernetes.io/name: kube-vip-ds
|
||||
app.kubernetes.io/version: {{ kube_vip_version }}
|
||||
spec:
|
||||
affinity:
|
||||
nodeAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
nodeSelectorTerms:
|
||||
- matchExpressions:
|
||||
- key: node-role.kubernetes.io/master
|
||||
operator: Exists
|
||||
- matchExpressions:
|
||||
- key: node-role.kubernetes.io/control-plane
|
||||
operator: Exists
|
||||
containers:
|
||||
- args:
|
||||
- manager
|
||||
env:
|
||||
- name: vip_arp
|
||||
value: "true"
|
||||
- name: port
|
||||
value: "6443"
|
||||
- name: vip_interface
|
||||
value: {{ vip_interface }}
|
||||
- name: vip_cidr
|
||||
value: "32"
|
||||
- name: cp_enable
|
||||
value: "true"
|
||||
- name: cp_namespace
|
||||
value: kube-system
|
||||
- name: vip_ddns
|
||||
value: "false"
|
||||
- name: svc_enable
|
||||
value: "false"
|
||||
- name: svc_leasename
|
||||
value: plndr-svcs-lock
|
||||
- name: vip_leaderelection
|
||||
value: "true"
|
||||
- name: vip_leasename
|
||||
value: plndr-cp-lock
|
||||
- name: vip_leaseduration
|
||||
value: "5"
|
||||
- name: vip_renewdeadline
|
||||
value: "3"
|
||||
- name: vip_retryperiod
|
||||
value: "1"
|
||||
- name: address
|
||||
value: {{ vip }}
|
||||
- name: prometheus_server
|
||||
value: :2112
|
||||
image: ghcr.io/kube-vip/kube-vip:{{ kube_vip_version }}
|
||||
imagePullPolicy: Always
|
||||
name: kube-vip
|
||||
resources: {}
|
||||
securityContext:
|
||||
capabilities:
|
||||
add:
|
||||
- NET_ADMIN
|
||||
- NET_RAW
|
||||
hostNetwork: true
|
||||
serviceAccountName: kube-vip
|
||||
tolerations:
|
||||
- effect: NoSchedule
|
||||
operator: Exists
|
||||
- effect: NoExecute
|
||||
operator: Exists
|
||||
updateStrategy: {}
|
||||
status:
|
||||
currentNumberScheduled: 0
|
||||
desiredNumberScheduled: 0
|
||||
numberMisscheduled: 0
|
||||
numberReady: 0
|
||||
@@ -0,0 +1,15 @@
|
||||
- name: Enable IPv4 forwarding
|
||||
ansible.posix.sysctl:
|
||||
name: net.ipv4.ip_forward
|
||||
value: "1"
|
||||
state: present
|
||||
reload: true
|
||||
tags: sysctl
|
||||
|
||||
- name: Enable IPv6 forwarding
|
||||
ansible.posix.sysctl:
|
||||
name: net.ipv6.conf.all.forwarding
|
||||
value: "1"
|
||||
state: present
|
||||
reload: true
|
||||
tags: sysctl
|
||||
@@ -0,0 +1,20 @@
|
||||
# Create a directory to download RKE2 binary to
|
||||
- name: Create directory for RKE2 binary
|
||||
ansible.builtin.file:
|
||||
path: "{{ rke2_install_dir }}"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
|
||||
# Download the RKE2 binary
|
||||
- name: Download RKE2 binary
|
||||
ansible.builtin.get_url:
|
||||
url: "{{ rke2_binary_url }}"
|
||||
dest: "{{ rke2_install_dir }}/rke2"
|
||||
mode: '0755'
|
||||
|
||||
# Set permissions on the RKE2 binary
|
||||
- name: Set executable permissions on the RKE2 binary
|
||||
ansible.builtin.file:
|
||||
path: "{{ rke2_install_dir }}/rke2"
|
||||
mode: '0755'
|
||||
state: file
|
||||
@@ -0,0 +1,134 @@
|
||||
- name: Create directory for RKE2 config
|
||||
ansible.builtin.file:
|
||||
path: "/etc/rancher/rke2"
|
||||
state: directory
|
||||
mode: '0644'
|
||||
|
||||
- name: Create directory for RKE2 token
|
||||
ansible.builtin.file:
|
||||
path: "/var/lib/rancher/rke2/server"
|
||||
state: directory
|
||||
mode: '0644'
|
||||
|
||||
# Copy server config to server 1 for bootstrap - we need to change server2 & 3 later with the token
|
||||
- name: Deploy RKE2 server Configuration
|
||||
ansible.builtin.template:
|
||||
src: templates/rke2-server-config.j2
|
||||
dest: /etc/rancher/rke2/config.yaml
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
when: inventory_hostname in groups['servers']
|
||||
|
||||
- name: Create systemd service file for RKE2 server
|
||||
ansible.builtin.template:
|
||||
src: templates/rke2-server.service.j2
|
||||
dest: /etc/systemd/system/rke2-server.service
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
when: inventory_hostname in groups['servers']
|
||||
|
||||
- name: Create systemd service file for RKE2 agent
|
||||
ansible.builtin.template:
|
||||
src: templates/rke2-agent.service.j2
|
||||
dest: /etc/systemd/system/rke2-agent.service
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
when: inventory_hostname in groups['agents']
|
||||
|
||||
# we enable the first server to generate tokens etc, copy this afterwards to other servers
|
||||
- name: Ensure RKE2 server is enabled and running
|
||||
ansible.builtin.systemd:
|
||||
name: rke2-server
|
||||
enabled: true
|
||||
state: restarted
|
||||
daemon_reload: true
|
||||
when: inventory_hostname in groups['servers'][0]
|
||||
|
||||
# wait for node token to be availale so that we can copy it, we need this to join other nodes
|
||||
- name: Wait for node-token
|
||||
ansible.builtin.wait_for:
|
||||
path: /var/lib/rancher/rke2/server/node-token
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
|
||||
# wait for kubectl to be downloaded, part of the rke2 installation
|
||||
- name: Wait for kubectl
|
||||
ansible.builtin.wait_for:
|
||||
path: /var/lib/rancher/rke2/bin/kubectl
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
|
||||
# copy kubectl to usr bin so that all users can run kubectl commands
|
||||
- name: Copy kubectl to user bin
|
||||
ansible.builtin.copy:
|
||||
src: /var/lib/rancher/rke2/bin/kubectl
|
||||
dest: /usr/local/bin/kubectl
|
||||
mode: '0755'
|
||||
remote_src: true
|
||||
become: true
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
|
||||
# wait for the kubectl copy to complete
|
||||
- name: Wait for kubectl
|
||||
ansible.builtin.wait_for:
|
||||
path: /usr/local/bin/kubectl
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
|
||||
# modify token access
|
||||
- name: Register node-token file access mode
|
||||
ansible.builtin.stat:
|
||||
path: /var/lib/rancher/rke2/server
|
||||
register: p
|
||||
|
||||
- name: Change file access for node-token
|
||||
ansible.builtin.file:
|
||||
path: /var/lib/rancher/rke2/server
|
||||
mode: "g+rx,o+rx"
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
|
||||
# Save token as variable
|
||||
- name: Fetch the token from the first server node
|
||||
ansible.builtin.slurp:
|
||||
src: /var/lib/rancher/rke2/server/token
|
||||
register: rke2_token
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
run_once: true
|
||||
|
||||
# convert token to fact
|
||||
- name: Save Master node-token for later
|
||||
ansible.builtin.set_fact:
|
||||
token: "{{ rke2_token.content | b64decode | regex_replace('\n', '') }}"
|
||||
|
||||
# revert token file access
|
||||
- name: Restore node-token file access
|
||||
ansible.builtin.file:
|
||||
path: /var/lib/rancher/rke2/server
|
||||
mode: "{{ p.stat.mode }}"
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
|
||||
# check .kube folder exists so that we can use kubectl (config resides here)
|
||||
- name: Ensure .kube directory exists in user's home
|
||||
ansible.builtin.file:
|
||||
path: "/home/{{ ansible_user }}/.kube"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
become: true
|
||||
|
||||
# copy kubectl config file to .kube folder
|
||||
- name: Copy config file to user home directory
|
||||
ansible.builtin.copy:
|
||||
src: /etc/rancher/rke2/rke2.yaml
|
||||
dest: "/home/{{ ansible_user }}/.kube/config"
|
||||
remote_src: true
|
||||
owner: "{{ ansible_user }}"
|
||||
mode: "u=rw,g=,o="
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
|
||||
# change IP from local to server 1 IP
|
||||
- name: Replace IP address with server1
|
||||
ansible.builtin.replace:
|
||||
path: /home/{{ ansible_user }}/.kube/config
|
||||
regexp: '127.0.0.1'
|
||||
replace: "{{ hostvars['server1']['ansible_host'] }}"
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
@@ -0,0 +1,13 @@
|
||||
# rke2-agent.service.j2
|
||||
[Unit]
|
||||
Description=RKE2 Agent
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/local/bin/rke2 agent
|
||||
KillMode=process
|
||||
Restart=on-failure
|
||||
RestartSec=5s
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,10 @@
|
||||
write-kubeconfig-mode: "0644"
|
||||
tls-san:
|
||||
- {{ vip }}
|
||||
- {{ hostvars['server1']['ansible_host'] }}
|
||||
- {{ hostvars['server2']['ansible_host'] }}
|
||||
- {{ hostvars['server3']['ansible_host'] }}
|
||||
node-label:
|
||||
- server=true
|
||||
disable:
|
||||
- rke2-ingress-nginx
|
||||
@@ -0,0 +1,13 @@
|
||||
# rke2-server.service.j2
|
||||
[Unit]
|
||||
Description=RKE2 server
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/local/bin/rke2 server
|
||||
KillMode=process
|
||||
Restart=on-failure
|
||||
RestartSec=5s
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,61 @@
|
||||
# Hello, thanks for using my playbook, hopefully you can help to improve it.
|
||||
# Things that need adding: (there are many more)
|
||||
# 1) Support different OS & architectures
|
||||
# 2) Support multiple CNIs
|
||||
# 3) Improve the wait logic
|
||||
# 4) Use kubernetes Ansible plugins more sensibly
|
||||
# 5) Optimise flow logic
|
||||
# 6) Clean up
|
||||
|
||||
###############################################################
|
||||
# MAKE SURE YOU CHANGE group_vars/all.yaml VARIABLES!!!!!!!!!!!
|
||||
###############################################################
|
||||
|
||||
# bootstraps first server and copies configs for others/agents
|
||||
- name: Prepare all nodes
|
||||
hosts: servers,agents
|
||||
gather_facts: true # enables us to gather lots of useful variables: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/setup_module.html
|
||||
roles:
|
||||
- prepare-nodes
|
||||
|
||||
# creates directories for download and then downloads RKE2 and changes permissions
|
||||
- name: Download RKE2
|
||||
hosts: servers,agents
|
||||
gather_facts: true
|
||||
roles:
|
||||
- rke2-download
|
||||
|
||||
# Creates RKE2 bootstrap manifests folder and copies kube-vip template over (configured with variables)
|
||||
- name: Deploy Kube VIP
|
||||
hosts: servers
|
||||
gather_facts: true
|
||||
roles:
|
||||
- kube-vip
|
||||
|
||||
# bootstraps the first server, copies configs to nodes, saves token to use later
|
||||
- name: Prepare RKE2 on Servers and Agents
|
||||
hosts: servers,agents
|
||||
gather_facts: true
|
||||
roles:
|
||||
- rke2-prepare
|
||||
|
||||
# Adds additional servers using the token from the previous task
|
||||
- name: Add additional RKE2 Servers
|
||||
hosts: servers
|
||||
gather_facts: true
|
||||
roles:
|
||||
- add-server
|
||||
|
||||
# Adds agents to the cluster
|
||||
- name: Add additional RKE2 Agents
|
||||
hosts: agents
|
||||
gather_facts: true
|
||||
roles:
|
||||
- add-agent
|
||||
|
||||
# Finish kube-vip, add metallb
|
||||
- name: Apply manifests after cluster is created
|
||||
hosts: servers
|
||||
gather_facts: true
|
||||
roles:
|
||||
- apply-manifests
|
||||
@@ -0,0 +1,67 @@
|
||||
---
|
||||
- name: Deploy Docker Container with Docker Compose
|
||||
hosts: all
|
||||
become: true
|
||||
tasks:
|
||||
- name: Include variables file
|
||||
ansible.builtin.include_vars: myvars.yaml
|
||||
|
||||
- name: Ensure Docker is installed
|
||||
ansible.builtin.package:
|
||||
name: docker
|
||||
state: present
|
||||
|
||||
- name: Ensure Docker service is running
|
||||
ansible.builtin.service:
|
||||
name: docker
|
||||
state: started
|
||||
enabled: true
|
||||
|
||||
- name: Create a directory for Docker Compose files
|
||||
ansible.builtin.file:
|
||||
path: /home/ubuntu/ansible-docker/docker-compose
|
||||
state: directory
|
||||
mode: '0755' # Optional file permissions
|
||||
owner: ubuntu # Optional ownership
|
||||
group: ubuntu # Optional group ownership
|
||||
|
||||
- name: Create a directory for Nginx website files
|
||||
ansible.builtin.file:
|
||||
path: /home/ubuntu/docker/nginx/web
|
||||
state: directory
|
||||
mode: '0755' # Optional file permissions
|
||||
owner: ubuntu # Optional ownership
|
||||
group: ubuntu # Optional group ownership
|
||||
|
||||
- name: Copy docker-compose to remote host
|
||||
ansible.builtin.copy:
|
||||
src: /home/ubuntu/nginx/docker-compose.yaml
|
||||
dest: /home/ubuntu/ansible-docker/docker-compose/docker-compose.yaml
|
||||
mode: '0755' # Optional file permissions
|
||||
owner: ubuntu # Optional ownership
|
||||
group: ubuntu # Optional group ownership
|
||||
|
||||
- name: Copy Nginx website folder to remote host # copies a folder - note no file extension
|
||||
ansible.builtin.copy:
|
||||
src: /home/ubuntu/nginx/website
|
||||
dest: /home/ubuntu/docker/nginx/web
|
||||
mode: '0755' # Optional file permissions
|
||||
owner: ubuntu # Optional ownership
|
||||
group: ubuntu # Optional group ownership
|
||||
|
||||
- name: Replace old name with new name (requires Ansible >= 2.4)
|
||||
ansible.builtin.replace:
|
||||
path: /home/ubuntu/docker/nginx/web/website/index.html
|
||||
regexp: "Jim's Garage"
|
||||
replace: "{{ website_name }}"
|
||||
|
||||
- name: Access and print secret
|
||||
ansible.builtin.replace:
|
||||
path: /home/ubuntu/docker/nginx/web/website/index.html
|
||||
regexp: "Our Features"
|
||||
replace: "{{ api_key }}"
|
||||
|
||||
- name: Start Docker Compose
|
||||
community.docker.docker_compose:
|
||||
project_src: /home/ubuntu/ansible-docker/docker-compose
|
||||
state: present
|
||||
@@ -0,0 +1 @@
|
||||
password
|
||||
@@ -0,0 +1 @@
|
||||
api_key: SuperSecretPassword
|
||||
@@ -0,0 +1,24 @@
|
||||
---
|
||||
- name: Playbook
|
||||
hosts: all
|
||||
become: true
|
||||
|
||||
vars:
|
||||
omz_install_zsh: true
|
||||
users:
|
||||
- name: "user"
|
||||
group: "user"
|
||||
settings: ""
|
||||
tasks:
|
||||
- name: Run ansible-role-oh-my-zsh.
|
||||
include_role:
|
||||
name: "ctorgalson.oh-my-zsh"
|
||||
vars:
|
||||
omz_user: "{{ item }}"
|
||||
# Only create `.zshrc` for user 'user'; item.settings will be
|
||||
# appended to `.zshrc` for the user 'user'.
|
||||
omz_zshrc_create: "{{ (item.name == 'user') | ternary(true, false) }}"
|
||||
omz_plugins:
|
||||
- "kubectl"
|
||||
- "git"
|
||||
with_items: "{{ users }}"
|
||||
@@ -0,0 +1,131 @@
|
||||
# Ansible Role Oh My ZSH
|
||||
|
||||
This is a basic Ansible role to enable and configure Oh My Zsh on Fedora,
|
||||
Ubuntu, or MacOS. It should also work on many other \*nix variants. It
|
||||
performs the following tasks:
|
||||
|
||||
- Install and minimally configure Zsh:
|
||||
- make sure it exists,
|
||||
- set it as the default shell for the user specified by the role.
|
||||
- Install Oh My Zsh for each specified user (in `~/.oh-my-zsh` by default).
|
||||
- Configure (Oh My) Zsh by optionally creating a `.zshrc` file for each
|
||||
specified user.
|
||||
- Alternately, configure Zsh by adding a block of lines to individual
|
||||
users' `.zshrc` files.
|
||||
|
||||
## Role variables
|
||||
|
||||
| Variable name | Default value | Description |
|
||||
|----------------|---------------|-------------|
|
||||
| `omz_install_zsh` | `false` | Defines whether or not the role should attempt to install Zsh. |
|
||||
| `omz_user` | `[]` | The user to install/configure (Oh My) Zsh for. See below for its properties. |
|
||||
| `omz_user.name` | `-` | The name of the user. |
|
||||
| `omz_user.group` | `-` | The group of the user |
|
||||
| `omz_user.settings` | `-` | Extra settings (as a mult-line string) such as variable exports or aliases to add to the user's `.zshrc` file. Only used if `omz_zshrc_create` is `true`. |
|
||||
| `omz_git_repository` | `https://github.com/robbyrussell/oh-my-zsh.git` | The git repo to clone Oh My Zsh from. |
|
||||
| `omz_install_directory` | `.oh-my-zsh` | The name of the directory to clone Oh My Zsh into. |
|
||||
| `omz_zshrc_create` | `true` | Whether or not to create `.zshrc`. If `true`, will create `.zshrc` from a template. |
|
||||
| `omz_zshrc_template` | `templates/zshrc.zsh-template.j2` | The template used to create the user's `.zshrc` file when `omz_zshrc_create` is `true`. |
|
||||
| `omz_zshrc_backup` | `true` | Whether or not to create backup the existing `.zshrc` files when the role changes it. |
|
||||
| `omz_zsh_theme` | `robbyrussell` | See `templates/zshrc.zsh-template`. |
|
||||
| `omz_case_sensitive` | `false` | See `templates/zshrc.zsh-template`. |
|
||||
| `omz_hyphen_insensitive` | `false` | See `templates/zshrc.zsh-template`. |
|
||||
| `omz_disable_auto_update` | `false` | See `templates/zshrc.zsh-template`. |
|
||||
| `omz_update_zsh_days` | `13` | See `templates/zshrc.zsh-template`. |
|
||||
| `omz_disable_ls_colors` | `false` | See `templates/zshrc.zsh-template`. |
|
||||
| `omz_disable_auto_title` | `false` | See `templates/zshrc.zsh-template`. |
|
||||
| `omz_enable_correction` | `false` | See `templates/zshrc.zsh-template`. |
|
||||
| `omz_completion_waiting_dots` | `false` | See `templates/zshrc.zsh-template`. |
|
||||
| `omz_disable_untracked_files_dirty` | `false` | See `templates/zshrc.zsh-template`. |
|
||||
| `omz_hist_stamps` | `mm/dd/yyyy` | See `templates/zshrc.zsh-template`. |
|
||||
| `omz_zsh_custom` | `$ZSH/custom` | See `templates/zshrc.zsh-template`. |
|
||||
| `omz_plugins` | `[]` | A list of Oh My Zsh plugins to enable. |
|
||||
|
||||
## Role task files
|
||||
|
||||
### `main.yml`: task coordination
|
||||
|
||||
This file includes files that peform specific subsets of tasks.
|
||||
|
||||
### `zsh.yml`: Zsh setup
|
||||
|
||||
This task installs and sets zsh as the default shell for a user.
|
||||
|
||||
#### Variables used
|
||||
|
||||
- `omz_user`
|
||||
|
||||
### `oh-my-zsh-install.yml`: Oh My Zsh installation
|
||||
|
||||
This task clones the Oh My Zsh repository into the user directory of each
|
||||
specified user and sets the appropriate permissions on the directory.
|
||||
|
||||
#### Variables used
|
||||
|
||||
- `omz_user`
|
||||
- `omz_install_directory`
|
||||
- `omz_git_repository`
|
||||
- `omz_install_path`
|
||||
|
||||
### `oh-my-zsh-zshrc.yml`: Oh My Zsh configuration
|
||||
|
||||
This task creates the user a `.zshrc` file containing global values for various
|
||||
Oh My Zsh options based on [the `.zshrc` template in the oh-my-zsh repository](https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/templates/zshrc.zsh-template).
|
||||
The task can be configured to back up any existing `.zshrc` file.
|
||||
|
||||
This task only runs when `omz_zshrc_create` is set to `true`.
|
||||
|
||||
#### Variables used
|
||||
|
||||
- `omz_user`
|
||||
- `omz_zshrc_template`
|
||||
- `omz_zshrc_backup`
|
||||
|
||||
### `zsh-zshrc.yml`: final Zsh configuration
|
||||
|
||||
This task adds individual lines to the `.zshrc` file. This is useful for adding
|
||||
Zsh settings on an already-existing `.zshrc` file without creating it
|
||||
from scratch.
|
||||
|
||||
This task only runs when `omz_zshrc_create` is set to `false`.
|
||||
|
||||
#### Variables used
|
||||
|
||||
- `omz_user`
|
||||
- `omz_zshrc_backup`
|
||||
|
||||
## Sample playbook
|
||||
|
||||
---
|
||||
- name: Playbook
|
||||
hosts: all
|
||||
become: true
|
||||
|
||||
vars:
|
||||
omz_install_zsh: true
|
||||
users:
|
||||
- name: "lorem"
|
||||
group: "lorem"
|
||||
settings: ""
|
||||
- name: "ipsum"
|
||||
group: "ipsum"
|
||||
settings: |
|
||||
export PATH="/usr/local/sbin:$path"
|
||||
alias l="ls -AF"
|
||||
tasks:
|
||||
- name: Run ansible-role-oh-my-zsh.
|
||||
include_role:
|
||||
name: "ansible-role-oh-my-zsh"
|
||||
vars:
|
||||
omz_user: "{{ item }}"
|
||||
# Only create `.zshrc` for user 'lorem'; item.settings will be
|
||||
# appended to `.zshrc` for the user 'ipsum'.
|
||||
omz_zshrc_create: "{{ (item.name == 'lorem') | ternary(true, false) }}"
|
||||
omz_plugins:
|
||||
- "autojump"
|
||||
- "git"
|
||||
with_items: "{{ users }}"
|
||||
|
||||
```bash
|
||||
ansible-playbook -i inventory playbooks/ansible-role-oh-my-zsh/playbook.yml -l 'dev303' -K
|
||||
```
|
||||
@@ -0,0 +1,35 @@
|
||||
---
|
||||
# Role vars.
|
||||
omz_install_zsh: false
|
||||
|
||||
# User vars.
|
||||
omz_user: []
|
||||
# - name: "someuser"
|
||||
# group: "somegroup"
|
||||
# settings: |
|
||||
# export PATH="/usr/local/sbin:$path"
|
||||
# alias l="ls -AF"
|
||||
|
||||
# Oh My ZSH vars.
|
||||
omz_git_repository: "https://github.com/robbyrussell/oh-my-zsh.git"
|
||||
omz_install_directory: ".oh-my-zsh"
|
||||
|
||||
# Oh My ZSH template vars.
|
||||
omz_zshrc_create: true
|
||||
omz_zshrc_template: "templates/zshrc.zsh-template.j2"
|
||||
omz_custom_theme_template: "templates/custom.zsh-theme.j2"
|
||||
omz_zshrc_backup: true
|
||||
omz_zshrc_force: true
|
||||
omz_zsh_theme: "robbyrussell"
|
||||
omz_case_sensitive: false
|
||||
omz_hyphen_insensitive: false
|
||||
omz_disable_auto_update: false
|
||||
omz_update_zsh_days: 13
|
||||
omz_disable_ls_colors: false
|
||||
omz_disable_auto_title: false
|
||||
omz_enable_correction: false
|
||||
omz_completion_waiting_dots: false
|
||||
omz_disable_untracked_files_dirty: false
|
||||
omz_hist_stamps: "mm/dd/yyyy"
|
||||
omz_zsh_custom: "$ZSH/custom"
|
||||
omz_plugins: []
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
# Make sure zsh is installed and set to the user's default shell.
|
||||
- name: "OMZ | include zsh.yml tasks."
|
||||
include_tasks: "zsh.yml"
|
||||
tags:
|
||||
- "zsh"
|
||||
- "configure"
|
||||
- "configurezsh"
|
||||
|
||||
# Install oh-my-zsh.
|
||||
- name: "OMZ | include oh-my-zsh.yml tasks."
|
||||
include_tasks: oh-my-zsh-install.yml
|
||||
tags:
|
||||
- "oh-my-zsh"
|
||||
- "install"
|
||||
- "installohmyzsh"
|
||||
|
||||
# Configure oh-my-zsh with a custom .zshrc template if omz_zshrc_create
|
||||
# is set to 'true'.
|
||||
- name: "OMZ | include oh-my-zsh-zshrc.yml tasks."
|
||||
include_tasks: oh-my-zsh-zshrc.yml
|
||||
tags:
|
||||
- "oh-my-zsh"
|
||||
- "configure"
|
||||
- "configureohmyzsh"
|
||||
|
||||
# Finally, add exports etc to .zshrc /last/ (i.e. so they get added to whaterver
|
||||
# .zshrc exists.
|
||||
- name: "OMZ | include zsh-zshrc.yml tasks."
|
||||
include_tasks: zsh-zshrc.yml
|
||||
tags:
|
||||
- "zsh"
|
||||
- "configure"
|
||||
- "configurezsh"
|
||||
@@ -0,0 +1,21 @@
|
||||
---
|
||||
- name: "OMZ | establish install location."
|
||||
set_fact:
|
||||
omz_install_path: "/{{ omz_user_home_dir }}/{{ omz_user.name }}/{{ omz_install_directory }}"
|
||||
|
||||
- name: "OMZ | clone Oh My ZSH repo for user."
|
||||
git:
|
||||
repo: "{{ omz_git_repository }}"
|
||||
dest: "{{ omz_install_path }}"
|
||||
update: "true"
|
||||
accept_hostkey: "true"
|
||||
version: "master"
|
||||
register: "omz_clone"
|
||||
|
||||
- name: "OMZ | set ownership on newly cloned repository."
|
||||
file:
|
||||
path: "{{ omz_install_path }}"
|
||||
owner: "{{ omz_user.name }}"
|
||||
group: "{{ omz_user.group }}"
|
||||
recurse: "true"
|
||||
when: "omz_clone is changed"
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
- name: "OMZ | derive user .zshrc path."
|
||||
set_fact:
|
||||
omz_user_zshrc_path: "/{{ omz_user_home_dir }}/{{ omz_user.name }}/.zshrc"
|
||||
|
||||
- name: "OMZ | template .zshrc into place if required."
|
||||
template:
|
||||
src: "{{ omz_zshrc_template }}"
|
||||
dest: "{{ omz_user_zshrc_path }}"
|
||||
owner: "{{ omz_user.name }}"
|
||||
group: "{{ omz_user.group }}"
|
||||
backup: "{{ omz_zshrc_backup }}"
|
||||
force: "{{ omz_zshrc_force }}"
|
||||
when: "omz_zshrc_create"
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
# Note that we assume this file exists! lineinfile will fail if the file is
|
||||
# not present.
|
||||
- name: "OMZ | export vars to .zshrc if required."
|
||||
blockinfile:
|
||||
dest: "{{ omz_user_zshrc_path }}"
|
||||
block: "{{ omz_user.settings }}"
|
||||
backup: "{{ omz_zshrc_backup }}"
|
||||
when:
|
||||
- "omz_user.settings is defined"
|
||||
# Don't flag this line for checking if the value is empty--checking for an
|
||||
# empty value makes perfect sense.
|
||||
- "omz_user.settings != ''" # noqa 602
|
||||
- "not omz_zshrc_create"
|
||||
@@ -0,0 +1,32 @@
|
||||
---
|
||||
- name: "OMZ | establish home directory."
|
||||
set_fact:
|
||||
omz_user_home_dir: "{{ (ansible_system == 'Darwin') | ternary('Users', 'home') }}"
|
||||
|
||||
- name: "OMZ | ensure zsh is installed."
|
||||
block:
|
||||
- name: "OMZ | install zsh for Linux."
|
||||
package:
|
||||
name: "zsh"
|
||||
state: "present"
|
||||
when:
|
||||
- "ansible_system == 'Linux'"
|
||||
- "omz_install_zsh"
|
||||
|
||||
- name: "OMZ | install zsh for macOS."
|
||||
homebrew:
|
||||
name: "zsh"
|
||||
state: "present"
|
||||
when:
|
||||
- "ansible_system == 'Darwin'"
|
||||
- "omz_install_zsh"
|
||||
|
||||
- name: "OMZ | get zsh installed path."
|
||||
shell: "command -v zsh"
|
||||
register: omz_zsh_installed_path
|
||||
changed_when: "false"
|
||||
|
||||
- name: "OMZ | get user shell to zsh."
|
||||
user:
|
||||
name: "{{ omz_user.name }}"
|
||||
shell: "{{ omz_zsh_installed_path.stdout }}"
|
||||
@@ -0,0 +1,269 @@
|
||||
# vim:ft=zsh ts=2 sw=2 sts=2
|
||||
#
|
||||
# agnoster's Theme - https://gist.github.com/3712874
|
||||
# A Powerline-inspired theme for ZSH
|
||||
#
|
||||
# # README
|
||||
#
|
||||
# In order for this theme to render correctly, you will need a
|
||||
# [Powerline-patched font](https://github.com/Lokaltog/powerline-fonts).
|
||||
# Make sure you have a recent version: the code points that Powerline
|
||||
# uses changed in 2012, and older versions will display incorrectly,
|
||||
# in confusing ways.
|
||||
#
|
||||
# In addition, I recommend the
|
||||
# [Solarized theme](https://github.com/altercation/solarized/) and, if you're
|
||||
# using it on Mac OS X, [iTerm 2](https://iterm2.com/) over Terminal.app -
|
||||
# it has significantly better color fidelity.
|
||||
#
|
||||
# If using with "light" variant of the Solarized color schema, set
|
||||
# SOLARIZED_THEME variable to "light". If you don't specify, we'll assume
|
||||
# you're using the "dark" variant.
|
||||
#
|
||||
# # Goals
|
||||
#
|
||||
# The aim of this theme is to only show you *relevant* information. Like most
|
||||
# prompts, it will only show git information when in a git working directory.
|
||||
# However, it goes a step further: everything from the current user and
|
||||
# hostname to whether the last call exited with an error to whether background
|
||||
# jobs are running in this shell will all be displayed automatically when
|
||||
# appropriate.
|
||||
|
||||
### Segment drawing
|
||||
# A few utility functions to make it easy and re-usable to draw segmented prompts
|
||||
|
||||
CURRENT_BG='NONE'
|
||||
|
||||
case ${SOLARIZED_THEME:-dark} in
|
||||
light) CURRENT_FG='black';;
|
||||
*) CURRENT_FG='white';;
|
||||
esac
|
||||
|
||||
# Special Powerline characters
|
||||
|
||||
() {
|
||||
local LC_ALL="" LC_CTYPE="en_US.UTF-8"
|
||||
# NOTE: This segment separator character is correct. In 2012, Powerline changed
|
||||
# the code points they use for their special characters. This is the new code point.
|
||||
# If this is not working for you, you probably have an old version of the
|
||||
# Powerline-patched fonts installed. Download and install the new version.
|
||||
# Do not submit PRs to change this unless you have reviewed the Powerline code point
|
||||
# history and have new information.
|
||||
# This is defined using a Unicode escape sequence so it is unambiguously readable, regardless of
|
||||
# what font the user is viewing this source code in. Do not replace the
|
||||
# escape sequence with a single literal character.
|
||||
# Do not change this! Do not make it '\u2b80'; that is the old, wrong code point.
|
||||
SEGMENT_SEPARATOR=$'\ue0b0'
|
||||
}
|
||||
|
||||
# Begin a segment
|
||||
# Takes two arguments, background and foreground. Both can be omitted,
|
||||
# rendering default background/foreground.
|
||||
prompt_segment() {
|
||||
local bg fg
|
||||
[[ -n $1 ]] && bg="%K{$1}" || bg="%k"
|
||||
[[ -n $2 ]] && fg="%F{$2}" || fg="%f"
|
||||
if [[ $CURRENT_BG != 'NONE' && $1 != $CURRENT_BG ]]; then
|
||||
echo -n " %{$bg%F{$CURRENT_BG}%}$SEGMENT_SEPARATOR%{$fg%} "
|
||||
else
|
||||
echo -n "%{$bg%}%{$fg%} "
|
||||
fi
|
||||
CURRENT_BG=$1
|
||||
[[ -n $3 ]] && echo -n $3
|
||||
}
|
||||
|
||||
# End the prompt, closing any open segments
|
||||
prompt_end() {
|
||||
if [[ -n $CURRENT_BG ]]; then
|
||||
echo -n " %{%k%F{$CURRENT_BG}%}$SEGMENT_SEPARATOR"
|
||||
else
|
||||
echo -n "%{%k%}"
|
||||
fi
|
||||
echo -n "%{%f%}"
|
||||
CURRENT_BG=''
|
||||
}
|
||||
|
||||
### Prompt components
|
||||
# Each component will draw itself, and hide itself if no information needs to be shown
|
||||
|
||||
# Context: user@hostname (who am I and where am I)
|
||||
prompt_context() {
|
||||
if [[ "$USERNAME" != "$DEFAULT_USER" || -n "$SSH_CLIENT" ]]; then
|
||||
prompt_segment black default "%(!.%{%F{yellow}%}.)%n@%m"
|
||||
fi
|
||||
}
|
||||
|
||||
# Git: branch/detached head, dirty status
|
||||
prompt_git() {
|
||||
(( $+commands[git] )) || return
|
||||
if [[ "$(git config --get oh-my-zsh.hide-status 2>/dev/null)" = 1 ]]; then
|
||||
return
|
||||
fi
|
||||
local PL_BRANCH_CHAR
|
||||
() {
|
||||
local LC_ALL="" LC_CTYPE="en_US.UTF-8"
|
||||
PL_BRANCH_CHAR=$'\ue0a0' #
|
||||
}
|
||||
local ref dirty mode repo_path
|
||||
|
||||
if [[ "$(git rev-parse --is-inside-work-tree 2>/dev/null)" = "true" ]]; then
|
||||
repo_path=$(git rev-parse --git-dir 2>/dev/null)
|
||||
dirty=$(parse_git_dirty)
|
||||
ref=$(git symbolic-ref HEAD 2> /dev/null) || ref="➦ $(git rev-parse --short HEAD 2> /dev/null)"
|
||||
if [[ -n $dirty ]]; then
|
||||
prompt_segment yellow black
|
||||
else
|
||||
prompt_segment green $CURRENT_FG
|
||||
fi
|
||||
|
||||
local ahead behind
|
||||
ahead=$(git log --oneline @{upstream}.. 2>/dev/null)
|
||||
behind=$(git log --oneline ..@{upstream} 2>/dev/null)
|
||||
if [[ -n "$ahead" ]] && [[ -n "$behind" ]]; then
|
||||
PL_BRANCH_CHAR=$'\u21c5'
|
||||
elif [[ -n "$ahead" ]]; then
|
||||
PL_BRANCH_CHAR=$'\u21b1'
|
||||
elif [[ -n "$behind" ]]; then
|
||||
PL_BRANCH_CHAR=$'\u21b0'
|
||||
fi
|
||||
|
||||
if [[ -e "${repo_path}/BISECT_LOG" ]]; then
|
||||
mode=" <B>"
|
||||
elif [[ -e "${repo_path}/MERGE_HEAD" ]]; then
|
||||
mode=" >M<"
|
||||
elif [[ -e "${repo_path}/rebase" || -e "${repo_path}/rebase-apply" || -e "${repo_path}/rebase-merge" || -e "${repo_path}/../.dotest" ]]; then
|
||||
mode=" >R>"
|
||||
fi
|
||||
|
||||
setopt promptsubst
|
||||
autoload -Uz vcs_info
|
||||
|
||||
zstyle ':vcs_info:*' enable git
|
||||
zstyle ':vcs_info:*' get-revision true
|
||||
zstyle ':vcs_info:*' check-for-changes true
|
||||
zstyle ':vcs_info:*' stagedstr '✚'
|
||||
zstyle ':vcs_info:*' unstagedstr '±'
|
||||
zstyle ':vcs_info:*' formats ' %u%c'
|
||||
zstyle ':vcs_info:*' actionformats ' %u%c'
|
||||
vcs_info
|
||||
echo -n "${${ref:gs/%/%%}/refs\/heads\//$PL_BRANCH_CHAR }${vcs_info_msg_0_%% }${mode}"
|
||||
fi
|
||||
}
|
||||
|
||||
prompt_bzr() {
|
||||
(( $+commands[bzr] )) || return
|
||||
|
||||
# Test if bzr repository in directory hierarchy
|
||||
local dir="$PWD"
|
||||
while [[ ! -d "$dir/.bzr" ]]; do
|
||||
[[ "$dir" = "/" ]] && return
|
||||
dir="${dir:h}"
|
||||
done
|
||||
|
||||
local bzr_status status_mod status_all revision
|
||||
if bzr_status=$(bzr status 2>&1); then
|
||||
status_mod=$(echo -n "$bzr_status" | head -n1 | grep "modified" | wc -m)
|
||||
status_all=$(echo -n "$bzr_status" | head -n1 | wc -m)
|
||||
revision=${$(bzr log -r-1 --log-format line | cut -d: -f1):gs/%/%%}
|
||||
if [[ $status_mod -gt 0 ]] ; then
|
||||
prompt_segment yellow black "bzr@$revision ✚"
|
||||
else
|
||||
if [[ $status_all -gt 0 ]] ; then
|
||||
prompt_segment yellow black "bzr@$revision"
|
||||
else
|
||||
prompt_segment green black "bzr@$revision"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
prompt_hg() {
|
||||
(( $+commands[hg] )) || return
|
||||
local rev st branch
|
||||
if $(hg id >/dev/null 2>&1); then
|
||||
if $(hg prompt >/dev/null 2>&1); then
|
||||
if [[ $(hg prompt "{status|unknown}") = "?" ]]; then
|
||||
# if files are not added
|
||||
prompt_segment red white
|
||||
st='±'
|
||||
elif [[ -n $(hg prompt "{status|modified}") ]]; then
|
||||
# if any modification
|
||||
prompt_segment yellow black
|
||||
st='±'
|
||||
else
|
||||
# if working copy is clean
|
||||
prompt_segment green $CURRENT_FG
|
||||
fi
|
||||
echo -n ${$(hg prompt "☿ {rev}@{branch}"):gs/%/%%} $st
|
||||
else
|
||||
st=""
|
||||
rev=$(hg id -n 2>/dev/null | sed 's/[^-0-9]//g')
|
||||
branch=$(hg id -b 2>/dev/null)
|
||||
if `hg st | grep -q "^\?"`; then
|
||||
prompt_segment red black
|
||||
st='±'
|
||||
elif `hg st | grep -q "^[MA]"`; then
|
||||
prompt_segment yellow black
|
||||
st='±'
|
||||
else
|
||||
prompt_segment green $CURRENT_FG
|
||||
fi
|
||||
echo -n "☿ ${rev:gs/%/%%}@${branch:gs/%/%%}" $st
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Dir: current working directory
|
||||
prompt_dir() {
|
||||
prompt_segment blue $CURRENT_FG '%~'
|
||||
}
|
||||
|
||||
# Virtualenv: current working virtualenv
|
||||
prompt_virtualenv() {
|
||||
if [[ -n "$VIRTUAL_ENV" && -n "$VIRTUAL_ENV_DISABLE_PROMPT" ]]; then
|
||||
prompt_segment blue black "(${VIRTUAL_ENV:t:gs/%/%%})"
|
||||
fi
|
||||
}
|
||||
|
||||
# Status:
|
||||
# - was there an error
|
||||
# - am I root
|
||||
# - are there background jobs?
|
||||
prompt_status() {
|
||||
local -a symbols
|
||||
|
||||
[[ $RETVAL -ne 0 ]] && symbols+="%{%F{red}%}✘"
|
||||
[[ $UID -eq 0 ]] && symbols+="%{%F{yellow}%}⚡"
|
||||
[[ $(jobs -l | wc -l) -gt 0 ]] && symbols+="%{%F{cyan}%}⚙"
|
||||
|
||||
[[ -n "$symbols" ]] && prompt_segment black default "$symbols"
|
||||
}
|
||||
|
||||
#AWS Profile:
|
||||
# - display current AWS_PROFILE name
|
||||
# - displays yellow on red if profile name contains 'production' or
|
||||
# ends in '-prod'
|
||||
# - displays black on green otherwise
|
||||
prompt_aws() {
|
||||
[[ -z "$AWS_PROFILE" || "$SHOW_AWS_PROMPT" = false ]] && return
|
||||
case "$AWS_PROFILE" in
|
||||
*-prod|*production*) prompt_segment red yellow "AWS: ${AWS_PROFILE:gs/%/%%}" ;;
|
||||
*) prompt_segment green black "AWS: ${AWS_PROFILE:gs/%/%%}" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
## Main prompt
|
||||
build_prompt() {
|
||||
RETVAL=$?
|
||||
prompt_status
|
||||
prompt_virtualenv
|
||||
prompt_aws
|
||||
prompt_context
|
||||
prompt_dir
|
||||
prompt_git
|
||||
prompt_bzr
|
||||
prompt_hg
|
||||
prompt_end
|
||||
}
|
||||
|
||||
PROMPT='%{%f%b%k%}$(build_prompt) '
|
||||
@@ -0,0 +1,89 @@
|
||||
# Managed by Ansible. This file may be overwritten when playbooks are run!
|
||||
|
||||
# If you come from bash you might have to change your $PATH.
|
||||
# export PATH=$HOME/bin:/usr/local/bin:$PATH
|
||||
|
||||
# Path to your oh-my-zsh installation.
|
||||
export ZSH=/{{ omz_user_home_dir }}/{{ omz_user.name }}/{{ omz_install_directory }}
|
||||
|
||||
# Set name of the theme to load. Optionally, if you set this to "random"
|
||||
# it'll load a random theme each time that oh-my-zsh is loaded.
|
||||
# See https://github.com/robbyrussell/oh-my-zsh/wiki/Themes
|
||||
ZSH_THEME="{{ omz_zsh_theme }}"
|
||||
|
||||
# Uncomment the following line to use case-sensitive completion.
|
||||
CASE_SENSITIVE="{{ omz_case_sensitive }}"
|
||||
|
||||
# Uncomment the following line to use hyphen-insensitive completion. Case
|
||||
# sensitive completion must be off. _ and - will be interchangeable.
|
||||
HYPHEN_INSENSITIVE="{{ omz_hyphen_insensitive }}"
|
||||
|
||||
# Uncomment the following line to disable bi-weekly auto-update checks.
|
||||
DISABLE_AUTO_UPDATE="{{ omz_disable_auto_update }}"
|
||||
|
||||
# Uncomment the following line to change how often to auto-update (in days).
|
||||
export UPDATE_ZSH_DAYS={{ omz_update_zsh_days }}
|
||||
|
||||
# Uncomment the following line to disable colors in ls.
|
||||
DISABLE_LS_COLORS="{{ omz_disable_ls_colors }}"
|
||||
|
||||
# Uncomment the following line to disable auto-setting terminal title.
|
||||
DISABLE_AUTO_TITLE="{{ omz_disable_auto_title }}"
|
||||
|
||||
# Uncomment the following line to enable command auto-correction.
|
||||
ENABLE_CORRECTION="{{ omz_enable_correction }}"
|
||||
|
||||
# Uncomment the following line to display red dots whilst waiting for completion.
|
||||
COMPLETION_WAITING_DOTS="{{ omz_completion_waiting_dots }}"
|
||||
|
||||
# Uncomment the following line if you want to disable marking untracked files
|
||||
# under VCS as dirty. This makes repository status check for large repositories
|
||||
# much, much faster.
|
||||
DISABLE_UNTRACKED_FILES_DIRTY="{{ omz_disable_untracked_files_dirty }}"
|
||||
|
||||
# Uncomment the following line if you want to change the command execution time
|
||||
# stamp shown in the history command output.
|
||||
# The optional three formats: "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd"
|
||||
HIST_STAMPS="{{ omz_hist_stamps }}"
|
||||
|
||||
# Would you like to use another custom folder than $ZSH/custom?
|
||||
ZSH_CUSTOM={{ omz_zsh_custom }}
|
||||
|
||||
# Which plugins would you like to load? (plugins can be found in ~/.oh-my-zsh/plugins/*)
|
||||
# Custom plugins may be added to ~/.oh-my-zsh/custom/plugins/
|
||||
# Example format: plugins=(rails git textmate ruby lighthouse)
|
||||
# Add wisely, as too many plugins slow down shell startup.
|
||||
plugins=({{ omz_plugins | join(" ") }})
|
||||
|
||||
source $ZSH/oh-my-zsh.sh
|
||||
|
||||
# User configuration
|
||||
|
||||
# export MANPATH="/usr/local/man:$MANPATH"
|
||||
|
||||
# You may need to manually set your language environment
|
||||
# export LANG=en_US.UTF-8
|
||||
|
||||
# Preferred editor for local and remote sessions
|
||||
# if [[ -n $SSH_CONNECTION ]]; then
|
||||
# export EDITOR='vim'
|
||||
# else
|
||||
# export EDITOR='mvim'
|
||||
# fi
|
||||
|
||||
# Compilation flags
|
||||
# export ARCHFLAGS="-arch x86_64"
|
||||
|
||||
# ssh
|
||||
# export SSH_KEY_PATH="~/.ssh/dsa_id"
|
||||
|
||||
# Set personal aliases, overriding those provided by oh-my-zsh libs,
|
||||
# plugins, and themes. Aliases can be placed here, though oh-my-zsh
|
||||
# users are encouraged to define aliases within the ZSH_CUSTOM folder.
|
||||
# For a full list of active aliases, run `alias`.
|
||||
#
|
||||
# Example aliases
|
||||
# alias zshconfig="mate ~/.zshrc"
|
||||
# alias ohmyzsh="mate ~/.oh-my-zsh"
|
||||
|
||||
{{ omz_user.settings }}
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
collections:
|
||||
- name: ansible.utils
|
||||
- name: community.general
|
||||
- name: ansible.posix
|
||||
- name: kubernetes.core
|
||||
@@ -0,0 +1,27 @@
|
||||
os: "linux"
|
||||
arch: "amd64"
|
||||
|
||||
talos_version: v1.7.5
|
||||
talosctl_version: v1.7.5
|
||||
control_plane_ip: 192.168.50.195
|
||||
|
||||
control_plane_2: 192.168.50.196
|
||||
control_plane_3: 192.168.50.197
|
||||
|
||||
worker_1: 192.168.50.198
|
||||
worker_2: 192.168.50.199
|
||||
|
||||
config_directory: "/home/{{ ansible_user }}/.talos"
|
||||
config_file: "/home/{{ ansible_user }}/.talos/talosconfig"
|
||||
|
||||
kube_vip_version: "v0.8.0"
|
||||
vip_interface: null
|
||||
vip: 192.168.50.220
|
||||
|
||||
metallb_version: v0.13.12
|
||||
lb_range: 192.168.50.240-192.168.50.250
|
||||
lb_pool_name: first-pool
|
||||
|
||||
ansible_user: ubuntu
|
||||
ansible_become: true
|
||||
ansible_become_method: sudo
|
||||
@@ -0,0 +1,13 @@
|
||||
# Make sure Ansible host has access to these devices
|
||||
# Good idea to snapshot all machines and deploy uing cloud-template
|
||||
[ansible]
|
||||
127.0.0.1 ansible_connection=local
|
||||
|
||||
[servers]
|
||||
server1 ansible_host=192.168.50.195
|
||||
server2 ansible_host=192.168.50.196
|
||||
server3 ansible_host=192.168.50.197
|
||||
|
||||
[agents]
|
||||
agent1 ansible_host=192.168.50.198
|
||||
agent2 ansible_host=192.168.50.199
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
# Generate Machine Configurations. This is using the qemu agent as per: https://www.talos.dev/v1.7/talos-guides/install/virtualized-platforms/proxmox/
|
||||
- name: Apply config to first worker
|
||||
ansible.builtin.command:
|
||||
cmd: talosctl apply-config --insecure --nodes {{ worker_1 }} --file {{ config_directory }}/worker.yaml
|
||||
changed_when: true
|
||||
|
||||
- name: Apply config to second worker
|
||||
ansible.builtin.command:
|
||||
cmd: talosctl apply-config --insecure --nodes {{ worker_2 }} --file {{ config_directory }}/worker.yaml
|
||||
changed_when: true
|
||||
@@ -0,0 +1,16 @@
|
||||
---
|
||||
# Generate Machine Configurations. This is using the qemu agent as per: https://www.talos.dev/v1.7/talos-guides/install/virtualized-platforms/proxmox/
|
||||
- name: Apply config to first node
|
||||
ansible.builtin.command:
|
||||
cmd: talosctl apply-config --insecure --nodes {{ control_plane_ip }} --file {{ config_directory }}/controlplane.yaml
|
||||
changed_when: true
|
||||
|
||||
- name: Apply config to second node
|
||||
ansible.builtin.command:
|
||||
cmd: talosctl apply-config --insecure --nodes {{ control_plane_2 }} --file {{ config_directory }}/controlplane.yaml
|
||||
changed_when: true
|
||||
|
||||
- name: Apply config to first node
|
||||
ansible.builtin.command:
|
||||
cmd: talosctl apply-config --insecure --nodes {{ control_plane_3 }} --file {{ config_directory }}/controlplane.yaml
|
||||
changed_when: true
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
- name: Check that the config file doesn't already exist
|
||||
ansible.builtin.stat:
|
||||
path: "{{ config_file }}"
|
||||
register: stat_result
|
||||
|
||||
# Generate Machine Configurations. This is using the qemu agent as per: https://www.talos.dev/v1.7/talos-guides/install/virtualized-platforms/proxmox/
|
||||
- name: Generate config for cluster
|
||||
when: "not stat_result.stat.exists"
|
||||
ansible.builtin.command: talosctl gen config talos-proxmox-cluster https://{{ control_plane_ip }}:6443 --output-dir {{ config_directory }} --install-image factory.talos.dev/installer/770f94a47e708326b61f3e641bb733dc879c544dee1972e74763798fe93a1f6d:{{ talos_version }}
|
||||
changed_when: true
|
||||
@@ -0,0 +1,26 @@
|
||||
---
|
||||
# Update TalosCTL
|
||||
- name: Update TalosCTL configs
|
||||
ansible.builtin.command: talosctl config endpoint {{ control_plane_ip }} --talosconfig {{ config_file }}
|
||||
changed_when: true
|
||||
|
||||
- name: Update TalosCTL configs
|
||||
ansible.builtin.command: talosctl config node {{ control_plane_ip }} --talosconfig {{ config_file }}
|
||||
changed_when: true
|
||||
|
||||
#################################
|
||||
# WAIT FOR REBOOT & BOOTSTRAP #
|
||||
#################################
|
||||
- name: Keep trying to bootstrap
|
||||
ansible.builtin.command:
|
||||
cmd: "talosctl bootstrap --talosconfig {{ config_file }}"
|
||||
register: bootstrap_result
|
||||
retries: 10
|
||||
delay: 30
|
||||
until: bootstrap_result.rc == 0
|
||||
changed_when: bootstrap_result.rc == 0
|
||||
|
||||
# Grab Kubeconfig
|
||||
- name: Get Kubeconfig
|
||||
ansible.builtin.command: talosctl kubeconfig . --talosconfig {{ config_file }}
|
||||
changed_when: true
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
# Ansible Playbook to install Talos
|
||||
- name: Download talosctl for Linux (amd64)
|
||||
ansible.builtin.get_url:
|
||||
url: https://github.com/siderolabs/talos/releases/download/{{ talosctl_version }}/talosctl-linux-amd64
|
||||
dest: /usr/local/bin/talosctl
|
||||
mode: '0755' # Make the binary executable
|
||||
register: download_result # Register the result for debugging or verification
|
||||
|
||||
- name: Display download result
|
||||
ansible.builtin.debug:
|
||||
var: download_result # Display the result of the download task
|
||||
@@ -0,0 +1,37 @@
|
||||
# Hello, thanks for using my playbook, hopefully you can help to improve it.
|
||||
|
||||
# Install TalosCTL on Ansible node
|
||||
- name: Install TalosCTL
|
||||
hosts: ansible
|
||||
gather_facts: true # enables us to gather lots of useful variables: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/setup_module.html
|
||||
become: true
|
||||
roles:
|
||||
- install-talosctl
|
||||
|
||||
# Configure Cluster Configuration
|
||||
- name: Configure Cluster
|
||||
hosts: ansible
|
||||
gather_facts: true
|
||||
roles:
|
||||
- configure-cluster
|
||||
|
||||
# Apply Cluster Configuration
|
||||
- name: Configure Cluster
|
||||
hosts: ansible
|
||||
gather_facts: true
|
||||
roles:
|
||||
- apply-config
|
||||
|
||||
# Configure TalosCTL
|
||||
- name: Configure TalosCTL
|
||||
hosts: ansible
|
||||
gather_facts: true
|
||||
roles:
|
||||
- configure-talosctl
|
||||
|
||||
# Add Workers
|
||||
- name: Add Workers
|
||||
hosts: ansible
|
||||
gather_facts: true
|
||||
roles:
|
||||
- add-workers
|
||||
@@ -0,0 +1,9 @@
|
||||
# Add to Hosts File (change ansible_user if required)
|
||||
```
|
||||
[all:vars]
|
||||
ansible_user='user'
|
||||
ansible_become=yes
|
||||
ansible_become_method=sudo
|
||||
|
||||
ansible-playbook site.yaml -i inventory/hosts.ini --key-file ~/.ssh/id_rsa -K
|
||||
```
|
||||
@@ -0,0 +1,24 @@
|
||||
---
|
||||
- hosts: all
|
||||
gather_facts: yes
|
||||
become: yes
|
||||
|
||||
tasks:
|
||||
- name: Perform a distro upgrade
|
||||
ansible.builtin.apt:
|
||||
upgrade: dist
|
||||
update_cache: yes
|
||||
|
||||
- name: Check if a reboot is required
|
||||
ansible.builtin.stat:
|
||||
path: /var/run/reboot-required
|
||||
get_checksum: no
|
||||
register: reboot_required_file
|
||||
|
||||
- name: Reboot the server (if necessary)
|
||||
ansible.builtin.reboot:
|
||||
when: reboot_required_file.stat.exists == true
|
||||
|
||||
- name: Remove dependencies that are no longer needed
|
||||
ansible.builtin.apt:
|
||||
autoremove: yes
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
- name: Update APT package list and upgrade packages
|
||||
# hosts: "dc00,dc01,dc02,dc03,dc04,dc05,dc09"
|
||||
hosts: all
|
||||
become: true
|
||||
become_method: su
|
||||
|
||||
vars:
|
||||
ansible_user: user
|
||||
|
||||
tasks:
|
||||
- name: Update APT package list
|
||||
ansible.builtin.apt:
|
||||
update_cache: true
|
||||
upgrade: dist
|
||||
|
||||
- name: Check if a reboot is required.
|
||||
stat:
|
||||
path: /var/run/reboot-required
|
||||
register: reboot_required_file
|
||||
|
||||
- name: Reboot the server (if required).
|
||||
debug:
|
||||
msg: "Ansible Version: {{ reboot_required_file.stdout }}"
|
||||
when: reboot_required_file.stat.exists == true
|
||||
|
||||
- name: Remove dependencies that are no longer required.
|
||||
apt:
|
||||
autoremove: yes
|
||||
@@ -0,0 +1,23 @@
|
||||
---
|
||||
- hosts: all
|
||||
become: true
|
||||
tasks:
|
||||
- name: Update apt repo and cache on all Debian/Ubuntu boxes
|
||||
apt: update_cache=yes force_apt_get=yes cache_valid_time=3600
|
||||
|
||||
- name: Upgrade all packages on servers
|
||||
apt: upgrade=dist force_apt_get=yes
|
||||
|
||||
- name: Check if a reboot is needed on all servers
|
||||
register: reboot_required_file
|
||||
stat: path=/var/run/reboot-required get_checksum=false
|
||||
|
||||
- name: Reboot the box if kernel updated
|
||||
reboot:
|
||||
msg: "Reboot initiated by Ansible for kernel updates"
|
||||
connect_timeout: 5
|
||||
reboot_timeout: 300
|
||||
pre_reboot_delay: 0
|
||||
post_reboot_delay: 30
|
||||
test_command: uptime
|
||||
when: reboot_required_file.stat.exists
|
||||
@@ -0,0 +1,45 @@
|
||||
x86_64:
|
||||
hosts:
|
||||
dc00:
|
||||
ansible_host: 192.168.50.210
|
||||
ansible_user: user
|
||||
ansible_become_method: su
|
||||
dc09:
|
||||
ansible_host: 192.168.50.209
|
||||
ansible_user: user
|
||||
ansible_become_method: su
|
||||
arm64:
|
||||
hosts:
|
||||
dc01:
|
||||
ansible_host: 192.168.50.201
|
||||
ansible_user: user
|
||||
ansible_become_method: sudo
|
||||
dc02:
|
||||
ansible_host: 192.168.50.202
|
||||
ansible_user: user
|
||||
ansible_become_method: sudo
|
||||
dc03:
|
||||
ansible_host: 192.168.50.203
|
||||
ansible_user: user
|
||||
ansible_become_method: sudo
|
||||
dc04:
|
||||
ansible_host: 192.168.50.204
|
||||
ansible_user: user
|
||||
ansible_become_method: sudo
|
||||
dc05:
|
||||
ansible_host: 192.168.50.205
|
||||
ansible_user: user
|
||||
ansible_become_method: sudo
|
||||
node07:
|
||||
ansible_host: 192.168.50.207
|
||||
ansible_user: user
|
||||
ansible_become_method: sudo
|
||||
node08:
|
||||
ansible_host: 192.168.50.208
|
||||
ansible_user: user
|
||||
ansible_become_method: sudo
|
||||
|
||||
prod:
|
||||
children:
|
||||
x86_64:
|
||||
arm64:
|
||||
@@ -0,0 +1,34 @@
|
||||
backend:
|
||||
hosts:
|
||||
nfs:
|
||||
ansible_host: 192.168.50.225
|
||||
ansible_user: root
|
||||
ansible_become_method: su
|
||||
swarm:
|
||||
ansible_host: 192.168.50.220
|
||||
ansible_user: user
|
||||
ansible_become_method: sudo
|
||||
firewall:
|
||||
ansible_host: 192.168.50.170
|
||||
ansible_user: root
|
||||
ansible_become_method: su
|
||||
|
||||
dev:
|
||||
hosts:
|
||||
dev301:
|
||||
ansible_host: 192.168.50.71
|
||||
ansible_user: user
|
||||
ansible_become_method: sudo
|
||||
dev302:
|
||||
ansible_host: 192.168.1.10
|
||||
ansible_user: user
|
||||
ansible_become_method: sudo
|
||||
dev303:
|
||||
ansible_host: 192.168.50.30
|
||||
ansible_user: user
|
||||
ansible_become_method: sudo
|
||||
|
||||
virtual:
|
||||
children:
|
||||
backend:
|
||||
dev:
|
||||
@@ -0,0 +1,7 @@
|
||||
# Ansible
|
||||
|
||||
## Update all packages
|
||||
```bash
|
||||
ansible-playbook -i inventory playbooks/update/update-noreboot.yml -l '!node08' -K
|
||||
ansible-playbook -i inventory playbooks/update/update-noreboot.yml -l 'prod' -K
|
||||
```
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
collections:
|
||||
- name: ansible.utils
|
||||
- name: community.general
|
||||
- name: ansible.posix
|
||||
- name: kubernetes.core
|
||||
@@ -0,0 +1,8 @@
|
||||
tls-san:
|
||||
- 192.168.50.190
|
||||
- 192.168.50.209
|
||||
-
|
||||
-
|
||||
write-kubeconfig-mode: 0644
|
||||
disable:
|
||||
- rke2-ingress-nginx
|
||||
@@ -0,0 +1,20 @@
|
||||
os: "linux"
|
||||
# arch: "amd64"
|
||||
# Set your timezone
|
||||
system_timezone: "Asia/Singapore"
|
||||
|
||||
kube_vip_version: "v0.8.1"
|
||||
vip_interface: null
|
||||
vip: 192.168.50.210
|
||||
|
||||
metallb_version: v0.14.5
|
||||
lb_range: 192.168.50.190-192.168.50.199
|
||||
lb_pool_name: first-pool
|
||||
|
||||
rke2_version: "v1.28.11+rke2r1"
|
||||
rke2_install_dir: "/usr/local/bin"
|
||||
rke2_binary_url: "https://github.com/rancher/rke2/releases/download/{{ rke2_version }}"
|
||||
|
||||
ansible_user: user
|
||||
ansible_become: true
|
||||
ansible_become_method: sudo
|
||||
@@ -0,0 +1,8 @@
|
||||
# Make sure Ansible host has access to these devices
|
||||
# Good idea to snapshot all machines and deploy uing cloud-init
|
||||
|
||||
[servers]
|
||||
server1 ansible_host=192.168.50.132
|
||||
|
||||
[agents]
|
||||
agent1 ansible_host=192.168.50.131
|
||||
@@ -0,0 +1,89 @@
|
||||
apiVersion: apps/v1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
app.kubernetes.io/name: kube-vip-ds
|
||||
app.kubernetes.io/version: v0.8.1
|
||||
name: kube-vip-ds
|
||||
namespace: kube-system
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: kube-vip-ds
|
||||
template:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
app.kubernetes.io/name: kube-vip-ds
|
||||
app.kubernetes.io/version: v0.8.1
|
||||
spec:
|
||||
affinity:
|
||||
nodeAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
nodeSelectorTerms:
|
||||
- matchExpressions:
|
||||
- key: node-role.kubernetes.io/master
|
||||
operator: Exists
|
||||
- matchExpressions:
|
||||
- key: node-role.kubernetes.io/control-plane
|
||||
operator: Exists
|
||||
containers:
|
||||
- args:
|
||||
- manager
|
||||
env:
|
||||
- name: vip_arp
|
||||
value: "true"
|
||||
- name: port
|
||||
value: "6443"
|
||||
- name: vip_interface
|
||||
value: null
|
||||
- name: vip_cidr
|
||||
value: "32"
|
||||
- name: cp_enable
|
||||
value: "true"
|
||||
- name: cp_namespace
|
||||
value: kube-system
|
||||
- name: vip_ddns
|
||||
value: "false"
|
||||
- name: svc_enable
|
||||
value: "false"
|
||||
- name: svc_leasename
|
||||
value: plndr-svcs-lock
|
||||
- name: vip_leaderelection
|
||||
value: "true"
|
||||
- name: vip_leasename
|
||||
value: plndr-cp-lock
|
||||
- name: vip_leaseduration
|
||||
value: "5"
|
||||
- name: vip_renewdeadline
|
||||
value: "3"
|
||||
- name: vip_retryperiod
|
||||
value: "1"
|
||||
- name: address
|
||||
value: "192.168.50.210"
|
||||
- name: prometheus_server
|
||||
value: :2112
|
||||
image: ghcr.io/kube-vip/kube-vip:v0.8.1
|
||||
imagePullPolicy: Always
|
||||
name: kube-vip
|
||||
resources: {}
|
||||
securityContext:
|
||||
capabilities:
|
||||
add:
|
||||
- NET_ADMIN
|
||||
- NET_RAW
|
||||
hostNetwork: true
|
||||
serviceAccountName: kube-vip
|
||||
tolerations:
|
||||
- effect: NoSchedule
|
||||
operator: Exists
|
||||
- effect: NoExecute
|
||||
operator: Exists
|
||||
updateStrategy: {}
|
||||
status:
|
||||
currentNumberScheduled: 0
|
||||
desiredNumberScheduled: 0
|
||||
numberMisscheduled: 0
|
||||
numberReady: 0
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo -e " \033[33;2m __ _ _ ___ \033[0m"
|
||||
echo -e " \033[33;2m \ \(_)_ __ ___( )__ / _ \__ _ _ __ __ _ __ _ ___ \033[0m"
|
||||
echo -e " \033[33;2m \ \ | '_ \` _ \/ __| / /_\/ _\` | '__/ _\` |/ _\` |/ _ \ \033[0m"
|
||||
echo -e " \033[33;2m /\_/ / | | | | | \__ \ / /_\\ (_| | | | (_| | (_| | __/ \033[0m"
|
||||
echo -e " \033[33;2m \___/|_|_| |_| |_|___/ \____/\__,_|_| \__,_|\__, |\___| \033[0m"
|
||||
echo -e " \033[33;2m |___/ \033[0m"
|
||||
echo -e " \033[35;2m __ _ \033[0m"
|
||||
echo -e " \033[35;2m / / ___ _ __ __ _| |__ ___ _ __ _ __ \033[0m"
|
||||
echo -e " \033[35;2m / / / _ \| '_ \ / _\` | '_ \ / _ \| '__| '_ \ \033[0m"
|
||||
echo -e " \033[35;2m / /__| (_) | | | | (_| | | | | (_) | | | | | | \033[0m"
|
||||
echo -e " \033[35;2m \____/\___/|_| |_|\__, |_| |_|\___/|_| |_| |_| \033[0m"
|
||||
echo -e " \033[35;2m |___/ \033[0m"
|
||||
echo -e " \033[36;2m \033[0m"
|
||||
echo -e " \033[32;2m https://youtube.com/@jims-garage \033[0m"
|
||||
echo -e " \033[32;2m \033[0m"
|
||||
|
||||
#############################################
|
||||
# YOU SHOULD ONLY NEED TO EDIT THIS SECTION #
|
||||
#############################################
|
||||
|
||||
# THIS SCRIPT IS FOR RKE2, NOT K3S!
|
||||
# THIS SCRIPT IS FOR RKE2, NOT K3S!
|
||||
# THIS SCRIPT IS FOR RKE2, NOT K3S!
|
||||
|
||||
# Set the IP addresses of master1
|
||||
master1=192.168.50.209
|
||||
|
||||
# Set the IP addresses of your Longhorn nodes
|
||||
longhorn1=192.168.50.205
|
||||
|
||||
# User of remote machines
|
||||
user=furyhawk
|
||||
|
||||
# Interface used on remotes
|
||||
interface=eth0
|
||||
|
||||
# Set the virtual IP address (VIP)
|
||||
vip=192.168.50.210
|
||||
|
||||
# Array of longhorn nodes
|
||||
storage=($longhorn1)
|
||||
|
||||
#ssh certificate name variable
|
||||
certName=id_rsa
|
||||
|
||||
#############################################
|
||||
# DO NOT EDIT BELOW #
|
||||
#############################################
|
||||
# For testing purposes - in case time is wrong due to VM snapshots
|
||||
sudo timedatectl set-ntp off
|
||||
sudo timedatectl set-ntp on
|
||||
|
||||
# add ssh keys for all nodes
|
||||
for node in "${storage[@]}"; do
|
||||
ssh-copy-id $user@$node
|
||||
done
|
||||
|
||||
# add open-iscsi - needed for Debian and non-cloud Ubuntu
|
||||
if ! command -v sudo service open-iscsi status &> /dev/null
|
||||
then
|
||||
echo -e " \033[31;5mOpen-ISCSI not found, installing\033[0m"
|
||||
sudo apt install open-iscsi
|
||||
else
|
||||
echo -e " \033[32;5mOpen-ISCSI already installed\033[0m"
|
||||
fi
|
||||
|
||||
# Step 1: Add new longhorn nodes to cluster (note: label added)
|
||||
# Set token variable needed for RKE2 (not required for K3S)
|
||||
token=`cat token`
|
||||
for newnode in "${storage[@]}"; do
|
||||
ssh -tt $user@$newnode -i ~/.ssh/$certName sudo su <<EOF
|
||||
mkdir -p /etc/rancher/rke2
|
||||
touch /etc/rancher/rke2/config.yaml
|
||||
echo "token: $token" >> /etc/rancher/rke2/config.yaml
|
||||
echo "server: https://$vip:9345" >> /etc/rancher/rke2/config.yaml
|
||||
echo "node-label:" >> /etc/rancher/rke2/config.yaml
|
||||
echo " - longhorn=true" >> /etc/rancher/rke2/config.yaml
|
||||
curl -sfL https://get.rke2.io | INSTALL_RKE2_TYPE="agent" sh -
|
||||
systemctl enable rke2-agent.service
|
||||
systemctl start rke2-agent.service
|
||||
exit
|
||||
EOF
|
||||
echo -e " \033[32;5mLonghorn node joined successfully!\033[0m"
|
||||
done
|
||||
|
||||
# Step 2: Install Longhorn (using modified Official to pin to Longhorn Nodes)
|
||||
# kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/v1.6.2/deploy/longhorn.yaml
|
||||
kubectl apply -f https://raw.githubusercontent.com/JamesTurland/JimsGarage/main/Kubernetes/Longhorn/longhorn.yaml
|
||||
kubectl get pods \
|
||||
--namespace longhorn-system \
|
||||
--watch
|
||||
|
||||
# Step 3: Print out confirmation
|
||||
|
||||
kubectl get nodes
|
||||
kubectl get svc -n longhorn-system
|
||||
|
||||
echo -e " \033[32;5mHappy Kubing! Access Longhorn through Rancher UI\033[0m"
|
||||
@@ -0,0 +1,41 @@
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: kube-vip
|
||||
namespace: kube-system
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
annotations:
|
||||
rbac.authorization.kubernetes.io/autoupdate: "true"
|
||||
name: system:kube-vip-role
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["services/status"]
|
||||
verbs: ["update"]
|
||||
- apiGroups: [""]
|
||||
resources: ["services", "endpoints"]
|
||||
verbs: ["list","get","watch", "update"]
|
||||
- apiGroups: [""]
|
||||
resources: ["nodes"]
|
||||
verbs: ["list","get","watch", "update", "patch"]
|
||||
- apiGroups: ["coordination.k8s.io"]
|
||||
resources: ["leases"]
|
||||
verbs: ["list", "get", "watch", "update", "create"]
|
||||
- apiGroups: ["discovery.k8s.io"]
|
||||
resources: ["endpointslices"]
|
||||
verbs: ["list","get","watch", "update"]
|
||||
---
|
||||
kind: ClusterRoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: system:kube-vip-binding
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: system:kube-vip-role
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: kube-vip
|
||||
namespace: kube-system
|
||||
@@ -0,0 +1,121 @@
|
||||
# RKE2 playbook
|
||||
|
||||
/etc/hosts
|
||||
```
|
||||
127.0.0.1 localhost
|
||||
127.0.1.1 c1.local c1
|
||||
|
||||
# The following lines are desirable for IPv6 capable hosts
|
||||
::1 localhost ip6-localhost ip6-loopback
|
||||
ff02::1 ip6-allnodes
|
||||
ff02::2 ip6-allrouters
|
||||
```
|
||||
|
||||
|
||||
```bash
|
||||
export LC_ALL=en_US.UTF-8
|
||||
ansible-playbook site.yaml -i inventory/hosts.ini --key-file ~/.ssh/id_rsa -K
|
||||
k get pods --all-namespaces
|
||||
kubectl create namespace cattle-system
|
||||
# kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.15.1/cert-manager.crds.yaml
|
||||
# install helm
|
||||
curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null
|
||||
sudo apt-get install apt-transport-https --yes
|
||||
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
|
||||
sudo apt-get update
|
||||
sudo apt-get install helm
|
||||
|
||||
helm repo add jetstack https://charts.jetstack.io --force-update
|
||||
helm repo update
|
||||
helm install \
|
||||
cert-manager jetstack/cert-manager \
|
||||
--namespace cert-manager \
|
||||
--create-namespace \
|
||||
--version v1.15.2 \
|
||||
--set crds.enabled=true
|
||||
```
|
||||
NAME: cert-manager
|
||||
LAST DEPLOYED: Sat Aug 3 21:38:31 2024
|
||||
NAMESPACE: cert-manager
|
||||
STATUS: deployed
|
||||
REVISION: 1
|
||||
TEST SUITE: None
|
||||
NOTES:
|
||||
cert-manager v1.15.2 has been deployed successfully!
|
||||
|
||||
In order to begin issuing certificates, you will need to set up a ClusterIssuer
|
||||
or Issuer resource (for example, by creating a 'letsencrypt-staging' issuer).
|
||||
|
||||
More information on the different types of issuers and how to configure them
|
||||
can be found in our documentation:
|
||||
|
||||
https://cert-manager.io/docs/configuration/
|
||||
|
||||
For information on how to configure cert-manager to automatically provision
|
||||
Certificates for Ingress resources, take a look at the `ingress-shim`
|
||||
documentation:
|
||||
|
||||
https://cert-manager.io/docs/usage/ingress/
|
||||
|
||||
|
||||
https://www.suse.com/suse-rancher/support-matrix/all-supported-versions/rancher-v2-8-5/
|
||||
```bash
|
||||
kubectl get pods --namespace cert-manager
|
||||
kubectl create namespace cattle-system
|
||||
helm repo add rancher-latest https://releases.rancher.com/server-charts/latest
|
||||
helm install rancher rancher-latest/rancher \
|
||||
--namespace cattle-system \
|
||||
--set hostname=rancher.local \
|
||||
--set bootstrapPassword=admin
|
||||
```
|
||||
If you provided your own bootstrap password during installation, browse to https://rancher.local to get started.
|
||||
|
||||
If this is the first time you installed Rancher, get started by running this command and clicking the URL it generates:
|
||||
|
||||
```
|
||||
echo https://rancher.local/dashboard/?setup=$(kubectl get secret --namespace cattle-system bootstrap-secret -o go-template='{{.data.bootstrapPassword|base64decode}}')
|
||||
```
|
||||
https://node03/dashboard/?setup=admin
|
||||
|
||||
To get just the bootstrap password on its own, run:
|
||||
|
||||
```
|
||||
kubectl get secret --namespace cattle-system bootstrap-secret -o go-template='{{.data.bootstrapPassword|base64decode}}{{ "\n" }}'
|
||||
```
|
||||
|
||||
```bash
|
||||
sudo service open-iscsi status
|
||||
sudo apt install open-iscsi
|
||||
kubectl -n cattle-system get deploy rancher
|
||||
|
||||
kubectl -n cattle-system rollout status deploy/rancher
|
||||
kubectl -n cattle-system get deploy rancher
|
||||
kubectl get svc -n cattle-system
|
||||
kubectl expose deployment rancher --name=rancher-lb --port=443 --type=LoadBalancer -n cattle-system
|
||||
kubectl get svc -n cattle-system
|
||||
# kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/v1.6.2/deploy/longhorn.yaml
|
||||
# k delete -f https://raw.githubusercontent.com/longhorn/longhorn/v1.6.2/deploy/longhorn.yaml
|
||||
helm repo add longhorn https://charts.longhorn.io
|
||||
helm repo update
|
||||
k apply -f longhorn.yaml
|
||||
helm install longhorn longhorn/longhorn --namespace longhorn-system --create-namespace --version 1.6.2
|
||||
kubectl get pods \
|
||||
--namespace longhorn-system \
|
||||
--watch
|
||||
kubectl -n longhorn-system get pod
|
||||
kubectl get svc
|
||||
kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.1/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml
|
||||
kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.1/docs/content/reference/dynamic-configuration/kubernetes-crd-rbac.yml
|
||||
helm repo add traefik https://traefik.github.io/charts
|
||||
helm install traefik traefik/traefik --create-namespace -n 'traefik' -f traefik.yaml
|
||||
helm list -n traefik
|
||||
kubectl -n traefik port-forward $(kubectl get pods --selector "app.kubernetes.io/name=traefik" --output=name -A) 9000:9000 --address 0.0.0.0
|
||||
# Update repository
|
||||
helm repo update
|
||||
# See current Chart & Traefik version
|
||||
helm search repo traefik/traefik
|
||||
# Update CRDs (Traefik Proxy v3 CRDs)
|
||||
kubectl apply --server-side --force-conflicts -k https://github.com/traefik/traefik-helm-chart/traefik/crds/
|
||||
# Upgrade Traefik
|
||||
helm upgrade traefik traefik/traefik
|
||||
```
|
||||
Executable
+260
@@ -0,0 +1,260 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo -e " \033[33;5m __ _ _ ___ \033[0m"
|
||||
echo -e " \033[33;5m \ \(_)_ __ ___( )__ / _ \__ _ _ __ __ _ __ _ ___ \033[0m"
|
||||
echo -e " \033[33;5m \ \ | '_ \` _ \/ __| / /_\/ _\` | '__/ _\` |/ _\` |/ _ \ \033[0m"
|
||||
echo -e " \033[33;5m /\_/ / | | | | | \__ \ / /_\\ (_| | | | (_| | (_| | __/ \033[0m"
|
||||
echo -e " \033[33;5m \___/|_|_| |_| |_|___/ \____/\__,_|_| \__,_|\__, |\___| \033[0m"
|
||||
echo -e " \033[33;5m |___/ \033[0m"
|
||||
|
||||
echo -e " \033[36;5m ___ _ _____ ___ \033[0m"
|
||||
echo -e " \033[36;5m | _ \ |/ / __|_ ) \033[0m"
|
||||
echo -e " \033[36;5m | / ' <| _| / / \033[0m"
|
||||
echo -e " \033[36;5m |_|_\_|\_\___/___| \033[0m"
|
||||
echo -e " \033[36;5m \033[0m"
|
||||
echo -e " \033[32;5m https://youtube.com/@jims-garage \033[0m"
|
||||
echo -e " \033[32;5m \033[0m"
|
||||
|
||||
|
||||
#############################################
|
||||
# YOU SHOULD ONLY NEED TO EDIT THIS SECTION #
|
||||
#############################################
|
||||
|
||||
# Version of Kube-VIP to deploy
|
||||
KVVERSION="v0.6.3"
|
||||
|
||||
# Set the IP addresses of the admin, masters, and workers nodes
|
||||
admin=192.168.50.143
|
||||
master1=192.168.50.132
|
||||
worker1=192.168.50.131
|
||||
|
||||
# User of remote machines
|
||||
user=furyhawk
|
||||
|
||||
# Interface used on remotes
|
||||
interface=eth0
|
||||
|
||||
# Set the virtual IP address (VIP)
|
||||
vip=192.168.50.190
|
||||
|
||||
# Array of all master nodes
|
||||
allmasters=($master1)
|
||||
|
||||
# Array of master nodes
|
||||
masters=($master2 $master3)
|
||||
|
||||
# Array of worker nodes
|
||||
workers=($worker1)
|
||||
|
||||
# Array of all
|
||||
all=($master1 $worker1)
|
||||
|
||||
# Array of all minus master1
|
||||
allnomaster1=($master2 $master3 $worker1)
|
||||
|
||||
#Loadbalancer IP range
|
||||
lbrange=192.168.3.191-192.168.3.199
|
||||
|
||||
#ssh certificate name variable
|
||||
certName=id_rsa
|
||||
|
||||
#############################################
|
||||
# DO NOT EDIT BELOW #
|
||||
#############################################
|
||||
# For testing purposes - in case time is wrong due to VM snapshots
|
||||
sudo timedatectl set-ntp off
|
||||
sudo timedatectl set-ntp on
|
||||
|
||||
# Move SSH certs to ~/.ssh and change permissions
|
||||
cp /home/$user/{$certName,$certName.pub} /home/$user/.ssh
|
||||
chmod 600 /home/$user/.ssh/$certName
|
||||
chmod 644 /home/$user/.ssh/$certName.pub
|
||||
|
||||
# Install Kubectl if not already present
|
||||
if ! command -v kubectl version &> /dev/null
|
||||
then
|
||||
echo -e " \033[31;5mKubectl not found, installing\033[0m"
|
||||
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
|
||||
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
|
||||
else
|
||||
echo -e " \033[32;5mKubectl already installed\033[0m"
|
||||
fi
|
||||
|
||||
# Create SSH Config file to ignore checking (don't use in production!)
|
||||
sed -i '1s/^/StrictHostKeyChecking no\n/' ~/.ssh/config
|
||||
|
||||
#add ssh keys for all nodes
|
||||
for node in "${all[@]}"; do
|
||||
ssh-copy-id $user@$node
|
||||
done
|
||||
|
||||
# Step 1: Create Kube VIP
|
||||
# create RKE2's self-installing manifest dir
|
||||
sudo mkdir -p /var/lib/rancher/rke2/server/manifests
|
||||
# Install the kube-vip deployment into rke2's self-installing manifest folder
|
||||
curl -sO https://raw.githubusercontent.com/JamesTurland/JimsGarage/main/Kubernetes/RKE2/kube-vip
|
||||
cat kube-vip | sed 's/$interface/'$interface'/g; s/$vip/'$vip'/g' > $HOME/kube-vip.yaml
|
||||
sudo mv kube-vip.yaml /var/lib/rancher/rke2/server/manifests/kube-vip.yaml
|
||||
|
||||
# Find/Replace all k3s entries to represent rke2
|
||||
sudo sed -i 's/k3s/rke2/g' /var/lib/rancher/rke2/server/manifests/kube-vip.yaml
|
||||
# copy kube-vip.yaml to home directory
|
||||
sudo cp /var/lib/rancher/rke2/server/manifests/kube-vip.yaml ~/kube-vip.yaml
|
||||
# change owner
|
||||
sudo chown $user:$user kube-vip.yaml
|
||||
# make kube folder to run kubectl later
|
||||
mkdir ~/.kube
|
||||
|
||||
# create the rke2 config file
|
||||
sudo mkdir -p /etc/rancher/rke2
|
||||
touch config.yaml
|
||||
echo "tls-san:" >> config.yaml
|
||||
echo " - $vip" >> config.yaml
|
||||
echo " - $master1" >> config.yaml
|
||||
echo "write-kubeconfig-mode: 0644" >> config.yaml
|
||||
echo "disable:" >> config.yaml
|
||||
echo " - rke2-ingress-nginx" >> config.yaml
|
||||
# copy config.yaml to rancher directory
|
||||
sudo cp ~/config.yaml /etc/rancher/rke2/config.yaml
|
||||
|
||||
# update path with rke2-binaries
|
||||
echo 'export KUBECONFIG=/etc/rancher/rke2/rke2.yaml' >> ~/.bashrc ; echo 'export PATH=${PATH}:/var/lib/rancher/rke2/bin' >> ~/.bashrc ; echo 'alias k=kubectl' >> ~/.bashrc ; source ~/.bashrc ;
|
||||
|
||||
# Step 2: Copy kube-vip.yaml and certs to all masters
|
||||
for newnode in "${allmasters[@]}"; do
|
||||
scp -i ~/.ssh/$certName $HOME/kube-vip.yaml $user@$newnode:~/kube-vip.yaml
|
||||
scp -i ~/.ssh/$certName $HOME/config.yaml $user@$newnode:~/config.yaml
|
||||
scp -i ~/.ssh/$certName ~/.ssh/{$certName,$certName.pub} $user@$newnode:~/.ssh
|
||||
echo -e " \033[32;5mCopied successfully!\033[0m"
|
||||
done
|
||||
|
||||
# Step 3: Connect to Master1 and move kube-vip.yaml and config.yaml. Then install RKE2, copy token back to admin machine. We then use the token to bootstrap additional masternodes
|
||||
ssh -tt $user@$master1 -i ~/.ssh/$certName sudo su <<EOF
|
||||
mkdir -p /var/lib/rancher/rke2/server/manifests
|
||||
mv kube-vip.yaml /var/lib/rancher/rke2/server/manifests/kube-vip.yaml
|
||||
mkdir -p /etc/rancher/rke2
|
||||
mv config.yaml /etc/rancher/rke2/config.yaml
|
||||
echo 'export KUBECONFIG=/etc/rancher/rke2/rke2.yaml' >> ~/.bashrc ; echo 'export PATH=${PATH}:/var/lib/rancher/rke2/bin' >> ~/.bashrc ; echo 'alias k=kubectl' >> ~/.bashrc ; source ~/.bashrc ;
|
||||
curl -sfL https://get.rke2.io | sh -
|
||||
systemctl enable rke2-server.service
|
||||
systemctl start rke2-server.service
|
||||
echo "StrictHostKeyChecking no" > ~/.ssh/config
|
||||
ssh-copy-id -i /home/$user/.ssh/$certName $user@$admin
|
||||
scp -i /home/$user/.ssh/$certName /var/lib/rancher/rke2/server/token $user@$admin:~/token
|
||||
scp -i /home/$user/.ssh/$certName /etc/rancher/rke2/rke2.yaml $user@$admin:~/.kube/rke2.yaml
|
||||
exit
|
||||
EOF
|
||||
echo -e " \033[32;5mMaster1 Completed\033[0m"
|
||||
|
||||
# Step 4: Set variable to the token we just extracted, set kube config location
|
||||
token=`cat token`
|
||||
sudo cat ~/.kube/rke2.yaml | sed 's/127.0.0.1/'$master1'/g' > $HOME/.kube/config
|
||||
sudo chown $(id -u):$(id -g) $HOME/.kube/config
|
||||
export KUBECONFIG=${HOME}/.kube/config
|
||||
sudo cp ~/.kube/config /etc/rancher/rke2/rke2.yaml
|
||||
kubectl get nodes
|
||||
|
||||
# Step 5: Install kube-vip as network LoadBalancer - Install the kube-vip Cloud Provider
|
||||
kubectl apply -f https://kube-vip.io/manifests/rbac.yaml
|
||||
kubectl apply -f https://raw.githubusercontent.com/kube-vip/kube-vip-cloud-provider/main/manifest/kube-vip-cloud-controller.yaml
|
||||
|
||||
# Step 6: Add other Masternodes, note we import the token we extracted from step 3
|
||||
# for newnode in "${masters[@]}"; do
|
||||
# ssh -tt $user@$newnode -i ~/.ssh/$certName sudo su <<EOF
|
||||
# mkdir -p /etc/rancher/rke2
|
||||
# touch /etc/rancher/rke2/config.yaml
|
||||
# echo "token: $token" >> /etc/rancher/rke2/config.yaml
|
||||
# echo "server: https://$master1:9345" >> /etc/rancher/rke2/config.yaml
|
||||
# echo "tls-san:" >> /etc/rancher/rke2/config.yaml
|
||||
# echo " - $vip" >> /etc/rancher/rke2/config.yaml
|
||||
# echo " - $master1" >> /etc/rancher/rke2/config.yaml
|
||||
# echo " - $master2" >> /etc/rancher/rke2/config.yaml
|
||||
# echo " - $master3" >> /etc/rancher/rke2/config.yaml
|
||||
# curl -sfL https://get.rke2.io | sh -
|
||||
# systemctl enable rke2-server.service
|
||||
# systemctl start rke2-server.service
|
||||
# exit
|
||||
# EOF
|
||||
# echo -e " \033[32;5mMaster node joined successfully!\033[0m"
|
||||
# done
|
||||
|
||||
kubectl get nodes
|
||||
|
||||
# Step 7: Add Workers
|
||||
for newnode in "${workers[@]}"; do
|
||||
ssh -tt $user@$newnode -i ~/.ssh/$certName sudo su <<EOF
|
||||
mkdir -p /etc/rancher/rke2
|
||||
touch /etc/rancher/rke2/config.yaml
|
||||
echo "token: $token" >> /etc/rancher/rke2/config.yaml
|
||||
echo "server: https://$vip:9345" >> /etc/rancher/rke2/config.yaml
|
||||
echo "node-label:" >> /etc/rancher/rke2/config.yaml
|
||||
echo " - worker=true" >> /etc/rancher/rke2/config.yaml
|
||||
echo " - longhorn=true" >> /etc/rancher/rke2/config.yaml
|
||||
curl -sfL https://get.rke2.io | INSTALL_RKE2_TYPE="agent" sh -
|
||||
systemctl enable rke2-agent.service
|
||||
systemctl start rke2-agent.service
|
||||
exit
|
||||
EOF
|
||||
echo -e " \033[32;5mWorker node joined successfully!\033[0m"
|
||||
done
|
||||
|
||||
kubectl get nodes
|
||||
|
||||
# Step 8: Install Metallb
|
||||
echo -e " \033[32;5mDeploying Metallb\033[0m"
|
||||
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/namespace.yaml
|
||||
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.12/config/manifests/metallb-native.yaml
|
||||
# Download ipAddressPool and configure using lbrange above
|
||||
curl -sO https://raw.githubusercontent.com/JamesTurland/JimsGarage/main/Kubernetes/RKE2/ipAddressPool
|
||||
cat ipAddressPool | sed 's/$lbrange/'$lbrange'/g' > $HOME/ipAddressPool.yaml
|
||||
|
||||
# Step 9: Deploy IP Pools and l2Advertisement
|
||||
echo -e " \033[32;5mAdding IP Pools, waiting for Metallb to be available first. This can take a long time as we're likely being rate limited for container pulls...\033[0m"
|
||||
kubectl wait --namespace metallb-system \
|
||||
--for=condition=ready pod \
|
||||
--selector=component=controller \
|
||||
--timeout=1800s
|
||||
kubectl apply -f ipAddressPool.yaml
|
||||
kubectl apply -f https://raw.githubusercontent.com/JamesTurland/JimsGarage/main/Kubernetes/RKE2/l2Advertisement.yaml
|
||||
|
||||
# Step 10: Install Rancher (Optional - Delete if not required)
|
||||
#Install Helm
|
||||
echo -e " \033[32;5mInstalling Helm\033[0m"
|
||||
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
|
||||
chmod 700 get_helm.sh
|
||||
./get_helm.sh
|
||||
|
||||
# Add Rancher Helm Repo & create namespace
|
||||
helm repo add rancher-latest https://releases.rancher.com/server-charts/latest
|
||||
kubectl create namespace cattle-system
|
||||
|
||||
# Install Cert-Manager
|
||||
echo -e " \033[32;5mDeploying Cert-Manager\033[0m"
|
||||
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.2/cert-manager.crds.yaml
|
||||
helm repo add jetstack https://charts.jetstack.io
|
||||
helm repo update
|
||||
helm install cert-manager jetstack/cert-manager \
|
||||
--namespace cert-manager \
|
||||
--create-namespace \
|
||||
--version v1.13.2
|
||||
kubectl get pods --namespace cert-manager
|
||||
|
||||
# Install Rancher
|
||||
echo -e " \033[32;5mDeploying Rancher\033[0m"
|
||||
helm install rancher rancher-latest/rancher \
|
||||
--namespace cattle-system \
|
||||
--set hostname=rancher.my.org \
|
||||
--set bootstrapPassword=admin
|
||||
kubectl -n cattle-system rollout status deploy/rancher
|
||||
kubectl -n cattle-system get deploy rancher
|
||||
|
||||
# Add Rancher LoadBalancer
|
||||
kubectl get svc -n cattle-system
|
||||
kubectl expose deployment rancher --name=rancher-lb --port=443 --type=LoadBalancer -n cattle-system
|
||||
while [[ $(kubectl get svc -n cattle-system 'jsonpath={..status.conditions[?(@.type=="Pending")].status}') = "True" ]]; do
|
||||
sleep 5
|
||||
echo -e " \033[32;5mWaiting for LoadBalancer to come online\033[0m"
|
||||
done
|
||||
kubectl get svc -n cattle-system
|
||||
|
||||
echo -e " \033[32;5mAccess Rancher from the IP above - Password is admin!\033[0m"
|
||||
@@ -0,0 +1,17 @@
|
||||
# Copy agent config to all agents - we need to change agent2 & 3 later with the token
|
||||
- name: Deploy RKE2 Agent Configuration
|
||||
ansible.builtin.template:
|
||||
src: templates/rke2-agent-config.j2
|
||||
dest: /etc/rancher/rke2/config.yaml
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
when: inventory_hostname in groups['agents']
|
||||
|
||||
# Check agents have restarted to pick up config
|
||||
- name: Ensure RKE2 agents are enabled and running
|
||||
ansible.builtin.systemd:
|
||||
name: rke2-agent
|
||||
enabled: true
|
||||
state: restarted
|
||||
daemon_reload: true
|
||||
@@ -0,0 +1,6 @@
|
||||
write-kubeconfig-mode: "0644"
|
||||
token: {{ hostvars['server1']['token'] }}
|
||||
server: https://{{ hostvars['server1']['ansible_host'] }}:9345
|
||||
node-label:
|
||||
- "agent=true"
|
||||
- "longhorn=true"
|
||||
@@ -0,0 +1,53 @@
|
||||
# Copy server config with token to all servers except server 1 (this has token)
|
||||
- name: Deploy RKE2 server Configuration
|
||||
ansible.builtin.template:
|
||||
src: templates/rke2-server-config.j2
|
||||
dest: /etc/rancher/rke2/config.yaml
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
when: inventory_hostname != groups['servers'][0]
|
||||
|
||||
# Keep checking the cluster API until it's functioning (deployed)
|
||||
- name: Wait for cluster API to be ready (can take 5-10 mins depending on internet/hardware)
|
||||
ansible.builtin.command:
|
||||
cmd: "kubectl get nodes"
|
||||
register: kubectl_output
|
||||
until: "'connection refused' not in kubectl_output.stderr"
|
||||
retries: 120
|
||||
delay: 10
|
||||
changed_when: true
|
||||
become_user: "{{ ansible_user }}"
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
|
||||
# Use kubectl to deploy yaml. Perhaps this can be added to the manifest folder initially
|
||||
- name: Apply kube vip configuration file
|
||||
ansible.builtin.command:
|
||||
cmd: kubectl --kubeconfig /etc/rancher/rke2/rke2.yaml apply -f https://kube-vip.io/manifests/rbac.yaml
|
||||
changed_when: true
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
|
||||
# Apply the kube-vip configration. Perhaps this can be added to the manifest folder initially
|
||||
- name: Apply kube vip configuration file
|
||||
ansible.builtin.command:
|
||||
cmd: kubectl --kubeconfig /etc/rancher/rke2/rke2.yaml apply -f https://raw.githubusercontent.com/kube-vip/kube-vip-cloud-provider/main/manifest/kube-vip-cloud-controller.yaml
|
||||
changed_when: true
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
|
||||
# Check that additional servers are restarted
|
||||
- name: Ensure additional RKE2 servers are enabled and running
|
||||
ansible.builtin.systemd:
|
||||
name: rke2-server
|
||||
enabled: true
|
||||
state: restarted
|
||||
daemon_reload: true
|
||||
when: inventory_hostname != groups['servers'][0]
|
||||
|
||||
# enable additional servers
|
||||
- name: Ensure RKE2 server is enabled and running
|
||||
ansible.builtin.systemd:
|
||||
name: rke2-server
|
||||
enabled: true
|
||||
state: restarted
|
||||
daemon_reload: true
|
||||
when: inventory_hostname != groups['servers'][0]
|
||||
@@ -0,0 +1,8 @@
|
||||
write-kubeconfig-mode: "0644"
|
||||
token: {{ hostvars['server1']['token'] }}
|
||||
server: https://{{ hostvars['server1']['ansible_host'] }}:9345
|
||||
tls-san:
|
||||
- {{ vip }}
|
||||
- {{ hostvars['server1']['ansible_host'] }}
|
||||
node-label:
|
||||
- server=true
|
||||
@@ -0,0 +1,60 @@
|
||||
# Wait for Server 1 to be ready before continuing with metallb deployment
|
||||
- name: Wait for k8s nodes with node label 'server=true' to be ready, otherwise we cannot start metallb deployment
|
||||
ansible.builtin.command:
|
||||
cmd: "kubectl wait --for=condition=Ready nodes --selector server=true --timeout=600s"
|
||||
register: nodes_ready
|
||||
retries: 120
|
||||
delay: 10
|
||||
changed_when: true
|
||||
become_user: "{{ ansible_user }}"
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
|
||||
# Create namespace so that we can deploy metallb
|
||||
- name: Apply metallb namespace
|
||||
ansible.builtin.command:
|
||||
cmd: kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/namespace.yaml
|
||||
become_user: "{{ ansible_user }}"
|
||||
changed_when: true
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
|
||||
# Apply metallb manifest
|
||||
- name: Apply metallb manifest
|
||||
ansible.builtin.command:
|
||||
cmd: kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/{{ metallb_version }}/config/manifests/metallb-native.yaml
|
||||
become_user: "{{ ansible_user }}"
|
||||
changed_when: true
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
|
||||
# Wait for metallb deployment pods to be alive before deploying metallb manifests
|
||||
- name: Wait for metallb pods to be ready, otherwise we cannot start metallb deployment
|
||||
ansible.builtin.command:
|
||||
cmd: "kubectl wait --namespace metallb-system --for=condition=ready pod --selector=component=controller --timeout=1800s"
|
||||
changed_when: true
|
||||
become_user: "{{ ansible_user }}"
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
|
||||
# Apply L2 Advertisement for metallb
|
||||
- name: Apply metallb L2 Advertisement
|
||||
ansible.builtin.command:
|
||||
cmd: kubectl apply -f https://raw.githubusercontent.com/JamesTurland/JimsGarage/main/Kubernetes/RKE2/l2Advertisement.yaml
|
||||
become_user: "{{ ansible_user }}"
|
||||
changed_when: true
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
|
||||
# Deploy metal IP Pool to Server 1
|
||||
- name: Copy metallb IPPool to server 1
|
||||
ansible.builtin.template:
|
||||
src: templates/metallb-ippool.j2
|
||||
dest: /home/{{ ansible_user }}/ippool.yaml
|
||||
owner: "{{ ansible_user }}"
|
||||
group: "{{ ansible_user }}"
|
||||
mode: '0755'
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
|
||||
# don't think this will work as nodes are no execute, might need agents first
|
||||
- name: Apply metallb ipppool
|
||||
ansible.builtin.command:
|
||||
cmd: kubectl apply -f /home/{{ ansible_user }}/ippool.yaml
|
||||
become_user: "{{ ansible_user }}"
|
||||
changed_when: true
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
@@ -0,0 +1,8 @@
|
||||
apiVersion: metallb.io/v1beta1
|
||||
kind: IPAddressPool
|
||||
metadata:
|
||||
name: {{ lb_pool_name }}
|
||||
namespace: metallb-system
|
||||
spec:
|
||||
addresses:
|
||||
- {{ lb_range }}
|
||||
@@ -0,0 +1,17 @@
|
||||
# Create directory to deploy kube-vip manifest
|
||||
- name: Create directory for Kube VIP Manifest
|
||||
ansible.builtin.file:
|
||||
path: "/var/lib/rancher/rke2/server/manifests"
|
||||
state: directory
|
||||
mode: '0644'
|
||||
when: inventory_hostname in groups['servers']
|
||||
|
||||
# Copy kube-vip to server 1 manifest folder for auto deployment at bootstrap
|
||||
- name: Deploy Kube VIP Configuration
|
||||
ansible.builtin.template:
|
||||
src: templates/kube-vip-config.j2
|
||||
dest: /var/lib/rancher/rke2/server/manifests/kube-vip.yaml
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
@@ -0,0 +1,88 @@
|
||||
apiVersion: apps/v1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
app.kubernetes.io/name: kube-vip-ds
|
||||
app.kubernetes.io/version: {{ kube_vip_version }}
|
||||
name: kube-vip-ds
|
||||
namespace: kube-system
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: kube-vip-ds
|
||||
template:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
app.kubernetes.io/name: kube-vip-ds
|
||||
app.kubernetes.io/version: {{ kube_vip_version }}
|
||||
spec:
|
||||
affinity:
|
||||
nodeAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
nodeSelectorTerms:
|
||||
- matchExpressions:
|
||||
- key: node-role.kubernetes.io/master
|
||||
operator: Exists
|
||||
- matchExpressions:
|
||||
- key: node-role.kubernetes.io/control-plane
|
||||
operator: Exists
|
||||
containers:
|
||||
- args:
|
||||
- manager
|
||||
env:
|
||||
- name: vip_arp
|
||||
value: "true"
|
||||
- name: port
|
||||
value: "6443"
|
||||
- name: vip_interface
|
||||
value: {{ vip_interface }}
|
||||
- name: vip_cidr
|
||||
value: "32"
|
||||
- name: cp_enable
|
||||
value: "true"
|
||||
- name: cp_namespace
|
||||
value: kube-system
|
||||
- name: vip_ddns
|
||||
value: "false"
|
||||
- name: svc_enable
|
||||
value: "false"
|
||||
- name: svc_leasename
|
||||
value: plndr-svcs-lock
|
||||
- name: vip_leaderelection
|
||||
value: "true"
|
||||
- name: vip_leasename
|
||||
value: plndr-cp-lock
|
||||
- name: vip_leaseduration
|
||||
value: "5"
|
||||
- name: vip_renewdeadline
|
||||
value: "3"
|
||||
- name: vip_retryperiod
|
||||
value: "1"
|
||||
- name: address
|
||||
value: {{ vip }}
|
||||
- name: prometheus_server
|
||||
value: :2112
|
||||
image: ghcr.io/kube-vip/kube-vip:{{ kube_vip_version }}
|
||||
imagePullPolicy: Always
|
||||
name: kube-vip
|
||||
resources: {}
|
||||
securityContext:
|
||||
capabilities:
|
||||
add:
|
||||
- NET_ADMIN
|
||||
- NET_RAW
|
||||
hostNetwork: true
|
||||
serviceAccountName: kube-vip
|
||||
tolerations:
|
||||
- effect: NoSchedule
|
||||
operator: Exists
|
||||
- effect: NoExecute
|
||||
operator: Exists
|
||||
updateStrategy: {}
|
||||
status:
|
||||
currentNumberScheduled: 0
|
||||
desiredNumberScheduled: 0
|
||||
numberMisscheduled: 0
|
||||
numberReady: 0
|
||||
@@ -0,0 +1,15 @@
|
||||
- name: Enable IPv4 forwarding
|
||||
ansible.posix.sysctl:
|
||||
name: net.ipv4.ip_forward
|
||||
value: "1"
|
||||
state: present
|
||||
reload: true
|
||||
tags: sysctl
|
||||
|
||||
- name: Enable IPv6 forwarding
|
||||
ansible.posix.sysctl:
|
||||
name: net.ipv6.conf.all.forwarding
|
||||
value: "1"
|
||||
state: present
|
||||
reload: true
|
||||
tags: sysctl
|
||||
@@ -0,0 +1,31 @@
|
||||
# Create a directory to download RKE2 binary to
|
||||
- name: Create directory for RKE2 binary
|
||||
ansible.builtin.file:
|
||||
path: "{{ rke2_install_dir }}"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
|
||||
# Download the RKE2 binary
|
||||
- name: Download RKE2 amd64 binary
|
||||
ansible.builtin.get_url:
|
||||
url: "{{ rke2_binary_url }}/rke2.linux-amd64"
|
||||
dest: "{{ rke2_install_dir }}/rke2"
|
||||
mode: '0755'
|
||||
when: ansible_facts.architecture == "x86_64"
|
||||
|
||||
- name: Download RKE2 arm64 binary
|
||||
ansible.builtin.get_url:
|
||||
url: "{{ rke2_binary_url }}/rke2.linux-arm64"
|
||||
dest: "{{ rke2_install_dir }}/rke2"
|
||||
mode: '0755'
|
||||
when:
|
||||
- ( ansible_facts.architecture is search("arm") and
|
||||
ansible_facts.userspace_bits == "64" ) or
|
||||
ansible_facts.architecture is search("aarch64")
|
||||
|
||||
# Set permissions on the RKE2 binary
|
||||
- name: Set executable permissions on the RKE2 binary
|
||||
ansible.builtin.file:
|
||||
path: "{{ rke2_install_dir }}/rke2"
|
||||
mode: '0755'
|
||||
state: file
|
||||
@@ -0,0 +1,134 @@
|
||||
- name: Create directory for RKE2 config
|
||||
ansible.builtin.file:
|
||||
path: "/etc/rancher/rke2"
|
||||
state: directory
|
||||
mode: '0644'
|
||||
|
||||
- name: Create directory for RKE2 token
|
||||
ansible.builtin.file:
|
||||
path: "/var/lib/rancher/rke2/server"
|
||||
state: directory
|
||||
mode: '0644'
|
||||
|
||||
# Copy server config to server 1 for bootstrap - we need to change server2 & 3 later with the token
|
||||
- name: Deploy RKE2 server Configuration
|
||||
ansible.builtin.template:
|
||||
src: templates/rke2-server-config.j2
|
||||
dest: /etc/rancher/rke2/config.yaml
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
when: inventory_hostname in groups['servers']
|
||||
|
||||
- name: Create systemd service file for RKE2 server
|
||||
ansible.builtin.template:
|
||||
src: templates/rke2-server.service.j2
|
||||
dest: /etc/systemd/system/rke2-server.service
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
when: inventory_hostname in groups['servers']
|
||||
|
||||
- name: Create systemd service file for RKE2 agent
|
||||
ansible.builtin.template:
|
||||
src: templates/rke2-agent.service.j2
|
||||
dest: /etc/systemd/system/rke2-agent.service
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
when: inventory_hostname in groups['agents']
|
||||
|
||||
# we enable the first server to generate tokens etc, copy this afterwards to other servers
|
||||
- name: Ensure RKE2 server is enabled and running
|
||||
ansible.builtin.systemd:
|
||||
name: rke2-server
|
||||
enabled: true
|
||||
state: restarted
|
||||
daemon_reload: true
|
||||
when: inventory_hostname in groups['servers'][0]
|
||||
|
||||
# wait for node token to be availale so that we can copy it, we need this to join other nodes
|
||||
- name: Wait for node-token
|
||||
ansible.builtin.wait_for:
|
||||
path: /var/lib/rancher/rke2/server/node-token
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
|
||||
# wait for kubectl to be downloaded, part of the rke2 installation
|
||||
- name: Wait for kubectl
|
||||
ansible.builtin.wait_for:
|
||||
path: /var/lib/rancher/rke2/bin/kubectl
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
|
||||
# copy kubectl to usr bin so that all users can run kubectl commands
|
||||
- name: Copy kubectl to user bin
|
||||
ansible.builtin.copy:
|
||||
src: /var/lib/rancher/rke2/bin/kubectl
|
||||
dest: /usr/local/bin/kubectl
|
||||
mode: '0755'
|
||||
remote_src: true
|
||||
become: true
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
|
||||
# wait for the kubectl copy to complete
|
||||
- name: Wait for kubectl
|
||||
ansible.builtin.wait_for:
|
||||
path: /usr/local/bin/kubectl
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
|
||||
# modify token access
|
||||
- name: Register node-token file access mode
|
||||
ansible.builtin.stat:
|
||||
path: /var/lib/rancher/rke2/server
|
||||
register: p
|
||||
|
||||
- name: Change file access for node-token
|
||||
ansible.builtin.file:
|
||||
path: /var/lib/rancher/rke2/server
|
||||
mode: "g+rx,o+rx"
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
|
||||
# Save token as variable
|
||||
- name: Fetch the token from the first server node
|
||||
ansible.builtin.slurp:
|
||||
src: /var/lib/rancher/rke2/server/token
|
||||
register: rke2_token
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
run_once: true
|
||||
|
||||
# convert token to fact
|
||||
- name: Save Master node-token for later
|
||||
ansible.builtin.set_fact:
|
||||
token: "{{ rke2_token.content | b64decode | regex_replace('\n', '') }}"
|
||||
|
||||
# revert token file access
|
||||
- name: Restore node-token file access
|
||||
ansible.builtin.file:
|
||||
path: /var/lib/rancher/rke2/server
|
||||
mode: "{{ p.stat.mode }}"
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
|
||||
# check .kube folder exists so that we can use kubectl (config resides here)
|
||||
- name: Ensure .kube directory exists in user's home
|
||||
ansible.builtin.file:
|
||||
path: "/home/{{ ansible_user }}/.kube"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
become: true
|
||||
|
||||
# copy kubectl config file to .kube folder
|
||||
- name: Copy config file to user home directory
|
||||
ansible.builtin.copy:
|
||||
src: /etc/rancher/rke2/rke2.yaml
|
||||
dest: "/home/{{ ansible_user }}/.kube/config"
|
||||
remote_src: true
|
||||
owner: "{{ ansible_user }}"
|
||||
mode: "u=rw,g=,o="
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
|
||||
# change IP from local to server 1 IP
|
||||
- name: Replace IP address with server1
|
||||
ansible.builtin.replace:
|
||||
path: /home/{{ ansible_user }}/.kube/config
|
||||
regexp: '127.0.0.1'
|
||||
replace: "{{ hostvars['server1']['ansible_host'] }}"
|
||||
when: inventory_hostname == groups['servers'][0]
|
||||
@@ -0,0 +1,13 @@
|
||||
# rke2-agent.service.j2
|
||||
[Unit]
|
||||
Description=RKE2 Agent
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/local/bin/rke2 agent
|
||||
KillMode=process
|
||||
Restart=on-failure
|
||||
RestartSec=5s
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,8 @@
|
||||
write-kubeconfig-mode: "0644"
|
||||
tls-san:
|
||||
- {{ vip }}
|
||||
- {{ hostvars['server1']['ansible_host'] }}
|
||||
node-label:
|
||||
- server=true
|
||||
disable:
|
||||
- rke2-ingress-nginx
|
||||
@@ -0,0 +1,13 @@
|
||||
# rke2-server.service.j2
|
||||
[Unit]
|
||||
Description=RKE2 server
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/local/bin/rke2 server
|
||||
KillMode=process
|
||||
Restart=on-failure
|
||||
RestartSec=5s
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,61 @@
|
||||
# Hello, thanks for using my playbook, hopefully you can help to improve it.
|
||||
# Things that need adding: (there are many more)
|
||||
# 1) Support different OS & architectures
|
||||
# 2) Support multiple CNIs
|
||||
# 3) Improve the wait logic
|
||||
# 4) Use kubernetes Ansible plugins more sensibly
|
||||
# 5) Optimise flow logic
|
||||
# 6) Clean up
|
||||
|
||||
###############################################################
|
||||
# MAKE SURE YOU CHANGE group_vars/all.yaml VARIABLES!!!!!!!!!!!
|
||||
###############################################################
|
||||
|
||||
# bootstraps first server and copies configs for others/agents
|
||||
- name: Prepare all nodes
|
||||
hosts: servers,agents
|
||||
gather_facts: true # enables us to gather lots of useful variables: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/setup_module.html
|
||||
roles:
|
||||
- prepare-nodes
|
||||
|
||||
# creates directories for download and then downloads RKE2 and changes permissions
|
||||
- name: Download RKE2
|
||||
hosts: servers,agents
|
||||
gather_facts: true
|
||||
roles:
|
||||
- rke2-download
|
||||
|
||||
# Creates RKE2 bootstrap manifests folder and copies kube-vip template over (configured with variables)
|
||||
- name: Deploy Kube VIP
|
||||
hosts: servers
|
||||
gather_facts: true
|
||||
roles:
|
||||
- kube-vip
|
||||
|
||||
# bootstraps the first server, copies configs to nodes, saves token to use later
|
||||
- name: Prepare RKE2 on Servers and Agents
|
||||
hosts: servers,agents
|
||||
gather_facts: true
|
||||
roles:
|
||||
- rke2-prepare
|
||||
|
||||
# Adds additional servers using the token from the previous task
|
||||
- name: Add additional RKE2 Servers
|
||||
hosts: servers
|
||||
gather_facts: true
|
||||
roles:
|
||||
- add-server
|
||||
|
||||
# Adds agents to the cluster
|
||||
- name: Add additional RKE2 Agents
|
||||
hosts: agents
|
||||
gather_facts: true
|
||||
roles:
|
||||
- add-agent
|
||||
|
||||
# Finish kube-vip, add metallb
|
||||
- name: Apply manifests after cluster is created
|
||||
hosts: servers
|
||||
gather_facts: true
|
||||
roles:
|
||||
- apply-manifests
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user