Skip to content

Commit af937a9

Browse files
authored
Merge pull request #40 from binplz/jmc/dns
Elastic IP and automatic DNS updates
2 parents 80b47ae + cc4825e commit af937a9

7 files changed

Lines changed: 172 additions & 91 deletions

File tree

deploy/.terraform.lock.hcl

Lines changed: 32 additions & 13 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

deploy/main.tf

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,22 @@ chmod 0600 /root/nixbuild.pem
4343
EOF
4444
}
4545

46-
output "server_ip_addr" {
47-
value = aws_instance.binplz_server.public_ip
46+
output "public_ip_addr" {
47+
value = aws_eip.binplz_eip.public_ip
48+
}
49+
50+
resource "aws_eip" "binplz_eip" {
51+
instance = aws_instance.binplz_server.id
52+
}
53+
54+
resource "null_resource" "dns_update" {
55+
triggers = {
56+
# Note that after deploying binplz at least once, we will likely never re-provision this Elastic IP, so it is very unlikely to ever change.
57+
ip_change = aws_eip.binplz_eip.public_ip
58+
}
59+
provisioner "local-exec" {
60+
command = "python update_dns.py ${aws_eip.binplz_eip.public_ip}"
61+
}
4862
}
4963

5064
resource "aws_security_group" "my_security_group" {

deploy/update_dns.py

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
"""Binplz DNS update script
2+
3+
Usage: python update_dns.py <root IP address>
4+
5+
Where <root IP address> is the IP address that the A record for the binplz.dev root domain should point to.
6+
7+
This script talks to the transip API to update the binplz.dev settings.
8+
To do so, we
9+
1. Request an API token, signing the request with our transip account's private key
10+
2. Request a DNS record update, passing the API token
11+
"""
12+
import random
13+
import requests
14+
import json
15+
import datetime
16+
import base64
17+
import OpenSSL.crypto as ssl
18+
import sys
19+
import ipaddress
20+
21+
ip = ipaddress.ip_address(sys.argv[1])
22+
23+
# API docs: https://api.transip.nl/rest/docs.html
24+
api_root = "https://api.transip.nl/v6"
25+
username = "jonascarpay"
26+
27+
print(f"Starting update of DNS record to {ip}...")
28+
29+
print("Preparing and signing Token request...")
30+
31+
timestamp: str = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
32+
token_request_body = {
33+
"login": username,
34+
"nonce": str(random.randint(0, 999999999)),
35+
"read_only": False,
36+
"expiration_time": "30 minutes",
37+
"label": f"Binplz DNS update key {timestamp}",
38+
"global_key": True,
39+
}
40+
token_request_body_ascii = json.dumps(token_request_body).encode("ascii")
41+
42+
with open("../secrets/plaintext/transip_key.pem", "r") as f:
43+
private_key: str = f.read().strip()
44+
45+
signature = ssl.sign(
46+
pkey=ssl.load_privatekey(ssl.FILETYPE_PEM, private_key),
47+
data=token_request_body_ascii,
48+
digest="sha512",
49+
)
50+
51+
print("Requesting new API token...")
52+
token_response = requests.post(
53+
url=api_root + "/auth",
54+
data=token_request_body_ascii,
55+
headers={"Signature": base64.b64encode(signature).decode("ascii")},
56+
)
57+
58+
assert token_response.status_code == 201
59+
60+
token = token_response.json()["token"]
61+
62+
dns_update_request_body = {
63+
"dnsEntries": [
64+
{
65+
"name": "@",
66+
"expire": 86400, # 1 day
67+
"type": "A",
68+
"content": str(ip),
69+
},
70+
{
71+
"name": "docs",
72+
"expire": 86400,
73+
"type": "CNAME",
74+
"content": "binplz.github.io.",
75+
},
76+
]
77+
}
78+
79+
print("Updating DNS Entries...")
80+
dns_update_response = requests.put(
81+
url=api_root + "/domains/binplz.dev/dns",
82+
data=json.dumps(dns_update_request_body),
83+
headers={"Authorization": f"Bearer {token}"},
84+
)
85+
86+
assert dns_update_response.status_code == 204
87+
print("Success!")

flake.nix

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,11 @@
159159
pkgs.rlwrap
160160
pkgs.sqlite
161161
pkgs.age
162+
163+
(pkgs.python3.withPackages (p: [
164+
p.pyopenssl
165+
p.requests
166+
]))
162167
];
163168
TF_VAR_binplz_ami_path = "${inputs.self.packages.${system}.server-ami}/${image-name}.vhd";
164169
# Image name on AWS. The purpose is to invalidate when the image contents change.

secrets/encrypted/aws_credentials

Lines changed: 32 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,37 @@
11
age-encryption.org/v1
22
-> ssh-rsa HFk/YQ
3-
DwzfyX0GKSdhaWPe+86a3BlmSKKMLt9b3c1OyJ3U6iqxrV3+tT8lIsbMWBiAIip6
4-
nxTgg/gyLYhOlgX5E/cpMAcfsWJ43BjPZ8NcLNYBmoTYFSIDG6w3G0iwKdBf2dDA
5-
atQKAp4Jy1AC05Km5EwtwQm2b0ou4POpaXGHJIaUUAh4SzPOm+FA5C1XKt/8rQXh
6-
YiaJCmYCf8LftaAdAhfdysTkRK7HnpsTaw13jsQNq88dOVZWjuha8LWPGDockvl8
7-
1kuhDdguTAbD/DM3epO34uE76BBh89+fyFj1Usi8NdNJJ4isl4IeTPnKD6oK88VJ
8-
gHsMhAdwgj0zpORR/IYENQ6LdRE2rGIK4Fh6r980Sr+3wKzHPuIfNll+PmEYBY90
9-
q6bxfMVCm/IN15Gi2BRqJIsUG9nCg1s/5BJnEyUN2xsbfcLPkZDkBQhJ0XSP4IKo
10-
Exorpj05Fua4xZWLYV4OwE1fa7Q6lw8VsPDR5cYb/cuAJ0URRXSyOf4Dvu060MW9
11-
1cOQC9TT50VQnO2/8urq9CTTtTm7Te7TbX+ZBIGeK+wfVsSeGftrYAyyfgWQtnDb
12-
vo5UFdT0xE+2QXMvQ96JbA2tNSj/wechXG2Nt4ESCfKr0xmsnEDt62PBhKrqDtMr
13-
rs/ZhgUOFCPw9RAg+iUIAPdYgBgmvY2niAsq4RrnKFM
14-
-> ssh-rsa LQjD8A
15-
LfzwH65cwgTOn5Mce5pyYsXX3gmOJRMh8iaogp9tFUdNbbaiBfnVzdzkD3lD43rp
16-
teqlDZT3ouNd7B3NCyAwK3dL352lgE9E5cGyvQowbExzqAPaCRTOEMjzokylQGFF
17-
7OuBWsxQEriaKJzQqwUIWjI6P+9wemn5GDTQDiZH5U3mCNwgsU27W6um8Jsxq4ji
18-
XcODNqpp1EPcAapXpg4JyPJFc9GRmDIlK3vablJBcxakf6gi6ELK8fGF65b33IC4
19-
+7jWMaV9V5Ib/K0GiFTTKk+HieMOn1nBHSIVJSAsdLFFuMEXaPn9XOCoEmAM3IFS
20-
qieoXjx2ztWaIbR/DPCF2/tq5OB5xEXZmde3XGDn0DSkhj3hJ5mYkIPmxT11/fZO
21-
KSFVGTOMY5ErbPo3ubRgJxT0DbJlYxFSX0zIYykGfuoHXXoYgm3dLe6IFMN9DxCy
22-
DG/bm7Z4zpvXEWpxGRq6N5NAKrkwGS1K51rKuFRp3mkjln86eR3pozZQYKKbyyuP
23-
27YLuIxo0vjIT7WL3fLyF1+ZFd67hs8+qLCUk0e8VL+75wIIXSjZSrAmt/cwq9Gi
24-
OhzKSeFzGomrKhDcTNsBeLaXl6fzpTv9FhCwSJGKJ8pnpScqhf+f6Kpi4/W2PwV8
25-
wAWRZKe/WQCDHeAl+UfuQrSNjBKJaw8tYGMVShIJ91s
26-
-> ssh-rsa trQevA
27-
WoZoDZAhW/wulhAFDPl9ruix9+vtsI8NaBtYpWxTHKpk5avThziqY3AxrTaIhea+
28-
rGanOwfoG66gLFD1ZGm5ZWnPATsKPg5AFFGGB9GKPX+Yv0espNRVtjkjo9Ur8A6K
29-
TnCJYQ4+O9JdnDavsl+yAAwxOTgjp788LuAdL048qab+YTnHJkGXvMSUn1/fEQpq
30-
u2vQfCJCwhA4Ej4lI8URUrDlP5lI8ZZL3GVQro1Ij1qc3w82WG9DSYiOYY877eyf
31-
qcY2NnNXJzD8WPhGBCCU2Wrfu3U+yMdlTjAED3mxq6nxw5kZ0AzERIZSOUccjxrz
32-
nbyg9l83Y2Z2ei52iZ3AmsplVGFOgmjLOfjouFix38827kt5XThE7+SvIsWylFi6
33-
cegM00H5bdLRvSsSD+EkbEv9uzf9szNo0ImYahh+tZFmv4MUvRaL8qltJPCJa4Qw
34-
3PZGoMAsidITQ89YzcjrTxJT1cNuFN3XZAQtufJfBUBMsU3y+x8OmSLEHv1bKsuu
35-
5gSyP3Tn0bdMGbbGMoY4sSRvwI7POU+Y1O7wcCyDwledLF7d/5OIZZgxkiBQ6Jec
36-
5cFUjaqjZMaRZLbIDYZCr6XwL3bB/61Jw7i3qP7fMVOP6Lpqvbyr+6Q5kO3ijhP2
37-
aa10g6Jb7J2P/Ysf2pzzO993q6UhqA92ArBI60jmGtU
3+
kEfgMP3rgqDJ/ELiCaHBt5wnFbdAbwBFy/Be9AdTfYq8NucYUifgGZVRXizDx5OK
4+
whO+kfqTGmRUWD7po4t+WAXnwZNxjSOh/QeV4UOlZiB02z37hzYbaV2gFB76jmWi
5+
sfgpN9Nph3nrFOtHXnqJ6xL5I9s5faQywexMi7A6q+qfUKC+Bxxyj9SAnPijQUvo
6+
8iAEe1zrsk8sjkqmDXZ1SUWc0Vcog1TK6Ty0KCAyME1n0Aczd/NwM05cxtFR8lKH
7+
R196ogzsJB/y6wqgaEOMieHVr4j56J6ziK10z0KQcVMklcGXuAp1WqzECsozvP/Y
8+
5Xcy7wWkG/PKySZ2Bh5SJ+ZUd2hvvg4D3KGI8eAr7EksmeaUQ3FeJUiLOSszcHnB
9+
kAuRy9Hob3Zs1iJz7N60PeirKWFBqoG2t5o2o4m6450ew53JGSjxQvaamsFXDJsc
10+
UnRZwx48SjaI86P9OjEiUxbvgCn5VqGDsPWYk+n7Fh9vSdT77e6eIHr8FM0o5XTW
11+
wxowwKDuC80s6oHm5oHqLjRMoQUphNDzWJ4fSnDo8a+DazsfAheKDcoQY1eBuGcL
12+
btJATtdMvdmADD5M00AGd0ONGGsOvkwYQdW0zmukhMFlow3PP+ka4Por8YBelCWZ
13+
Qgpa2AkWiRwpk77pFGelzd4/MhKdNhJm1/JYshqPwF8
3814
-> ssh-rsa 43vRYw
39-
Ta+xiaWeMIXzV1VbB3Ylxbn6uqd0IMUBsDIXCgJ0eGeqXHzmhqtM183n9She/tbw
40-
5/50UlIM44YURNd7GSDAwItJvBtFTR+WV7PIRBnPaKpsH6L5QIQmNsuwHMfrD0bo
41-
qlK9MhXeh21U2YWnpVGNS0dyabGXcjRnz33p9pweIJb+jI92QuBZE0lANJVTZOpP
42-
i9JTO49G48Ahj35UTxqgHFa1p0Zg2RR7IynKylcMi0CfOYUegSjOGjbHXFKMqH09
43-
G4HGDB+auUwxv7P/hvNhn8lAJN2ROsDoO5YXx56xRiUDhcTDt1PSolIs8S8It8nF
44-
ZYLMXPcYrapq7Mq+YeRLnq/2LfQUa7tvtylsNa0i3u9oQeApINhlpi/R0Ppyvzl/
45-
Nqh+aVkXkzGoBbnGtYjs7dxv8zDoscp7ccQSAjWN3sSDoS3CjadBNqu+aU1drMyp
46-
ZJL8ztsoLu4dJfTebvmIq+F0gxS7wyDBlW0zmfZTb9mI/Y/3VWbJxsalNrnGVqAJ
47-
3PPMs53mxgrSLxNH24/4Tw9CAWXHf5kAQsDgFbhv8F1H1V2RBtLi9MKZomOxuIsa
48-
pDBLbHKSfsBRmLx/aApvIapvJRCnF381PoBV+8k+d9KaXS6I0ixc3vwbUyF86SUi
49-
FpYpuM3a/g2Tb6U6ABRnS01QH8B6BFcZ1oSXOfExjSY
50-
-> ssh-ed25519 8K5cMg vg36Nr0v41XnBXO4Ud68NrIBtv7Vb+ZHe/wZ0n+25gs
51-
MHUNjfEYpMXMNf27aktzERWKUCoEme+yuKWm3MVrlIc
52-
-> ssh-rsa lJgVkA
53-
czcCI5LPmjYXc0GGoCQwZ/25zT6dgXXihnOu3ymDUgwHJ30bHP5eDEpbRQS/38q2
54-
8wHbB+DoaeKBFpmsJMNY/b5zCKMGdrHIjf0N0ChJAz1SYiQa2/3fWwhVUOVF+hU4
55-
lHBD06PUOn+MWB8acOdK0QVbARLwvODPYojk0YCPCHOQJT3EG3lAuDjxItlI5okD
56-
tHM0J3rs8RtGwhNcHA8zPjAxpRhoG6DXDuj8LPybwkapQpYm+2aF8053gwpLRJab
57-
n4jC43KF5h7wkVftfbkrEg1x6pbz21R65yYW2R8FmnkQ+YCNsbqWYS4CH/gF+N1X
58-
6mSFWnutLZu6JhPXRrqXrg
15+
RWb3vXyDvfq3ImWnMmvkXwn/CXgy9ec8a0ixPPRfjGY82DYUYPCgHiLIGnrUUEU9
16+
hv8kU1IZ9OODKbiF321W/O0Y2eqM5B9spvBxEG1g9qUc1vCNsPCWrjcFgI3+NHOQ
17+
rkQb9HH/YQxi/4/vB+VPVr7Q1+9Z0Qzyh/2bofNHaS3JxmcFpuMhHi+8enHTS7/P
18+
gZ6WjW4W2p9t3DkQB5cX/MGxQVdIpIl83cl7mCfypz2EzZ87oNcILd5DPv210PDV
19+
kNZJs55oNNQ4u9oHn65/TAZhXxqFUr6CLix11brAIK/ZMBMwN8UOoLLEJ6xb2Mmr
20+
WvJGm6Ak6WvaCNUjfTwq8wu7LjHf/+fdgdoU2ygHmQB/bkm5znVuYydyO4g3Wgqi
21+
QKHXSv7FImN354IJvpwHjWxO4rhEDUB6brpRDZk6nb8f4IZr5S7n+KPV2LY4L1Z6
22+
rCOjTd1XzkSSW1NaXK8kw/AL0u85V0s9pkMS1DWEWlsxS+nI6BbbCKg5VBkf2rfI
23+
UqeQ21T3ecnTYQipbm8wB7a9ZOCNr8YSGgDmUSjPaG9WibgtSPJw9k05LsOjlVy1
24+
aGEw6Rex4sFECP4/KZNm8xNW1RSnU9rbvTYdMPcA6kjiFnvjs+EKcvI6v1JpufaU
25+
AgVeLAPal0jFC2fejR5qDkBnLK4U00iTi33emnVHARw
5926
-> ssh-rsa puikOQ
60-
kjVVIahUb1LCtnLfo5DggoTWcMXUw+VdVlNKtBr1hbMUkpPZHnHq0A1VjEQCZpG6
61-
/A9/GT6chbLfnkL7iAGf96MK5zP60qPu981poV2xvL6p3fd6FpJxYtquPx4ik4Zj
62-
LpajO171toGl7KkzntgFD4w9zJwuJOEC6lrPNDZurC8bkRgrI7l/0WCSixbh2ojt
63-
RZmjAkZPTqMtgE21Kj0Yzy21GbiaQRY9rQZTwzZcw/iWFjyp/44xIuBixxpaODul
64-
TkVlp1YWzI28ouEnrMiKu+cC/7ta7GlpTBYXL5i+J5eZQdwIYpMonOnKi2ebpNtg
65-
eIO9+hNeLtj7eD+KD5jUJ4ciF3j9eedJyb+ONdZEYSz50BPy6chSq4t/0VABW5EL
66-
Fu11rHOoNKIV/rpbJiO04zPKB2xJO5RemTuLdAiCebIohhJg/wIC8uGwr94JYAn5
67-
jkv4mMbHPi46dLP0D/Glb8ISSpwoUB1ujWXxym/aRZVnKZw2IMUMLDSzTOhImss2
27+
BxtFi4Bz0saBe+oNnG8u5n1jrbQJyOM4TuxQxkz/UTTuko24msoB5gwj3KOv5Ulq
28+
1TR1rU/sYOCabIr97bFM16Aw+v87O8FY70TRZKmRse7WSc/dl2oep8iH4E2ws3dF
29+
1AeTKJlekTXPvhqr4+jsRW9VlxXSgTTYuTQqf5bvnmwVlamBtSE9ZNNgktnuXd6R
30+
AtIiH+BYM4QVSZ116EzCeQOP/z7i+i397VxUuH4YNsoOUhKYp62OeNbBHcQMaEap
31+
twwH4CCx8VEV0hQeauGVDdlQ96JiM6I7deCXRaUjbpFhVVjORsBUhuFqllsw3scd
32+
79Fi7eES1I+HiK5qlztRTztQD/uaIbJ+msdWg5j8x2UwLQWQlwxONQRj4kd0yiXg
33+
+ckfDSRoMIgkEOq1RmySh2SRcwY1C9vzR02tw2oIkDduaUYjBSnHpiRcgObYXxSr
34+
sF+APb2jJwHvTXen7TpLr7GbfC76DefEQ4XltJVesbHcQOYHAA2DoLxB2tfMI39H
6835

69-
-> ssh-rsa SmsMKw
70-
TFBLpCQeXHEdp82MU9H1pJyWvEtRgRwSnljXpLgNVnhWE+qEqGPdj0n8bnp7op4L
71-
yw80edZd0mXG53Rhsw4rfDDAnx54QeBC/KemiYysBjxPc210qrX5V8XJcyMLyugp
72-
R/529VDp0gjp4EypCd403dVF9kzjFHHR2644nFjbl/DBV+mEPsyNRs1/Czrkbeqr
73-
L3r0I3GQBeETh0KWNJQYrPU62cVRRhVbl3koA/FD2wyM9ebk4VrIRZMu9KJ7F2Ts
74-
t66FEBwnXPnnhvrZCzVO/R5B0Obn/s2rLhgTE24h4rLW6nqBsCSLUQuB6yFo7vb+
75-
adQNvG8CHJvb93JjqZCrSyVp2GvyrcYquTw4m+7VVZJRdZGtzjIWKehoazzIITks
76-
/2pFwhGdp6L5VMceDrl++UCm1Xt7l+U8le8gMiUlZp+NUJGpjcTnueX81iuuP4aF
77-
vDU/7InHOAIhKJCnBVXvciWBK+kr7uZpyOFzd4fZlz1jRuotXmowAsVbhz9s6gzi
78-
79-
--- 9/GA0HcgMlwbIqz9zSLUJ5qTXK3LRVIwIAoeFg7MYjE
80-
��!үxzlˊ�y|�a4Dwbښ�Q��)CN�����ܻ�ҹ�ꊾ=�*�b��\,���V'�Y+�E~v�kH�1�UQ����<�@N�zg¡���Y| }q��fʌ��=��b���9���G
81-
I�8���A����O
36+
--- cKCGLz95aR1gJv8UoQI2EYQBdZEPrY7b+tFdOlE8wn4
37+
"��^(mw�^&���J�s�ZD��gP����+|� �!Q�g�u����SY�(v�`W�0S�r�B��3�˹gJ�}r!X�*������B�: >M��9\�n��g0̼ ��ᙈ(M�4O ѭ���E����k�Ӯ�Ѕ

secrets/encrypted/nixbuild.pem

-2.38 KB
Binary file not shown.

secrets/encrypted/transip_key.pem

3.68 KB
Binary file not shown.

0 commit comments

Comments
 (0)