Skip to content

Commit 5aa6675

Browse files
Merge pull request #3 from AndrewChubatiuk/added-firewall
added firewall, placement group support
2 parents 5c59fcb + 904b283 commit 5aa6675

File tree

10 files changed

+408
-381
lines changed

10 files changed

+408
-381
lines changed

README.md

Lines changed: 112 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,99 +1,123 @@
1-
# nomad-hcloud-autoscaler
1+
# Hetzner Cloud Server Target Plugin
22

3-
## Demo
4-
Run `terraform apply` in [demo](demo/setup) folder to create:
5-
- nomad server which runs services for:
6-
- nomad-autoscaler
7-
- prometheus
8-
- redis
3+
The `hcloud-server` target plugin allows for the scaling of the Nomad cluster clients via manipulating [Hetzner Cloud Servers][hcloud_servers].
94

10-
Autoscaler scales hcloud nodes for redis. After successful run both Nomad and Consul are wide-world open and credentials for both you can find in terraform output
5+
## Agent Configuration Options
116

7+
To use the `hcloud-server` target plugin, the agent configuration needs to be populated with the appropriate target block.
128

13-
## Configuration
14-
15-
`config.hcl`
16-
```
17-
template {
18-
data = <<-EOF
19-
nomad {
20-
address = "http://{{env "attr.unique.network.ip-address" }}:4646"
21-
}
22-
23-
telemetry {
24-
prometheus_metrics = true
25-
disable_hostname = true
26-
}
27-
28-
apm "prometheus" {
29-
driver = "prometheus"
30-
config = {
31-
address = "http://{{ range service "prometheus" }}{{ .Address }}:{{ .Port }}{{ end }}"
32-
}
33-
}
34-
35-
strategy "target-value" {
36-
driver = "target-value"
37-
38-
}
39-
40-
target "hcloud-server" {
41-
driver = "hcloud-server"
42-
config = {
43-
hcloud_token = "YOUR_HCLOUD_TOKEN"
44-
}
45-
}
46-
47-
EOF
48-
49-
destination = "${NOMAD_TASK_DIR}/config.hcl"
50-
change_mode = "signal"
51-
change_signal = "SIGHUP"
9+
```hcl
10+
target "hcloud-server" {
11+
driver = "hcloud-server"
12+
config = {
13+
hcloud_token = "YOUR_HCLOUD_TOKEN"
14+
}
5215
}
5316
```
5417

55-
`policy`
18+
- `hcloud_token` `(string: required)` - The [Hetzner Cloud token][hcloud_token] used to authenticate to connect to and where resources should be managed.
19+
20+
- `hcloud_random_suffix_len` `(string: "10")` - Random Server name suffix length
21+
22+
- `hcloud_retry_interval` `(string: "1m")` - Hetzner Cloud API retry interval
23+
24+
- `hcloud_retry_limit` `(string: "5")` - Hetzner Cloud API retry limit
5625

26+
- `hcloud_items_per_page` `(string: "50")` - Hetzner Cloud API request page size
27+
28+
- `hcloud_group_id_label_selector` `(string: "group-id")` - Server group id label selector
29+
30+
- `hcloud_node_attr_id` `(string: "unique.hostname")` - Nomad Node attribute id
31+
32+
### Nomad ACL
33+
34+
When using a Nomad cluster with ACLs enabled, the plugin will require an ACL token which provides the following permissions:
35+
36+
```hcl
37+
node {
38+
policy = "write"
39+
}
5740
```
58-
template {
59-
data = <<-EOF
60-
scaling "cluster_class-batch" {
61-
enabled = true
62-
min = 1
63-
max = 2
64-
65-
policy {
66-
cooldown = "5m"
67-
evaluation_interval = "5m"
68-
69-
check "test-scale" {
70-
source = "prometheus"
71-
query = "YOUR_DESIRED_METRIC"
72-
73-
strategy "target-value" {
74-
target = 2
75-
}
76-
}
77-
78-
target "hcloud-server" {
79-
// datacenter = "XXX"
80-
node_class = "XXX"
81-
dry-run = "false"
82-
// node_selector_strategy = "newest_create_index"
83-
hcloud_location = "XXX"
84-
hcloud_image = "XXX"
85-
hcloud_user_data = ""
86-
hcloud_ssh_keys = "XXX"
87-
hcloud_server_type = "cx11"
88-
hcloud_group_id = "XXX"
89-
hcloud_labels = "XXX_node=true"
90-
hcloud_networks = "XXX"
91-
}
92-
}
93-
}
94-
EOF
95-
destination = "${NOMAD_TASK_DIR}/policies/hcloud.hcl"
96-
change_mode = "signal"
97-
change_signal = "SIGHUP"
41+
42+
## Policy Configuration Options
43+
44+
```hcl
45+
check "hashistack-allocated-cpu" {
46+
# ...
47+
target "hcloud-server" {
48+
datacenter = "XXX"
49+
node_class = "XXX"
50+
node_drain_deadline = "5m"
51+
node_purge = "true"
52+
node_selector_strategy = "newest_create_index"
53+
hcloud_location = "XXX"
54+
hcloud_image = "XXX"
55+
hcloud_user_data = "#cloud-config\npackages:\n - jq"
56+
hcloud_b64_user_data_encoded = "false"
57+
hcloud_ssh_keys = "XXX"
58+
hcloud_server_type = "cx11"
59+
hcloud_group_id = "XXX"
60+
hcloud_labels = "XXX_node=true"
61+
hcloud_networks = "XXX"
62+
}
63+
# ...
9864
}
9965
```
66+
67+
- `hcloud_location` `(string: "")` - ID or name of [Location][hcloud_location] to create Server in (must not be used together with `hcloud_datacenter`).
68+
69+
- `hcloud_datacenter` `(string: "")` - ID or name of [Datacenter][hcloud_datacenter] to create Server in (must not be used together with `hcloud_location`).
70+
71+
- `hcloud_firewalls` `(string: "")` - Comma-separated list of [Firewall][hcloud_firewall] IDs
72+
73+
- `hcloud_placement_group` `(string: "")` - [Placement Group][hcloud_placement_group] ID
74+
75+
- `hcloud_image` `(string: required)` - ID or name of the [Image][hcloud_image] the Server is created from.
76+
77+
- `hcloud_group_id` `(string: required)` - Server group name used for filtering targeted HCloud hosts. `group-id` label is attached to a server during creation.
78+
79+
- `hcloud_user_data` `(string: required)` - [Cloud-Init][cloud_init] user data to use during Server creation. This field is limited to 32KiB.
80+
81+
- `hcloud_b64_user_data_encoded` `(string: "false")` - Identifies if `hcloud_user_data` is base64 encoded or not.
82+
83+
- `hcloud_ssh_keys` `(string: required)` - Comma-separated IDs or names of SSH keys which should be injected into the server at creation time.
84+
85+
- `hcloud_labels` `(string: "")` - User-defined labels (key-value pairs) string in a format `key1=value1,key2=value2,...,keyN=valueN`.
86+
87+
- `hcloud_networks` `(string: "")` - [Network][hcloud_networks] IDs which should be attached to the server private network interface at the creation time.
88+
89+
- `datacenter` `(string: "")` - The Nomad client [datacenter][nomad_datacenter] identifier used to group nodes into a pool of resource.
90+
91+
- `node_class` `(string: "")` - The Nomad [client node class][nomad_node_class] identifier used to group nodes into a pool of resource.
92+
93+
- `node_drain_deadline` `(duration: "15m")` The Nomad [drain deadline][nomad_node_drain_deadline] to use when performing node draining actions.
94+
95+
- `node_drain_ignore_system_jobs` `(bool: "false")` A boolean flag used to control if system jobs should be stopped when performing node draining actions.
96+
97+
- `node_purge` `(bool: "false")` A boolean flag to determine whether Nomad clients should be [purged][nomad_node_purge] when performing scale in actions.
98+
99+
- `node_selector_strategy` `(string: "least_busy")` The strategy to use when selecting nodes for termination. Refer to the [node selector strategy][node_selector_strategy] documentation for more information.
100+
101+
[hcloud_servers]: https://docs.hetzner.com/cloud/servers
102+
[hcloud_datacenter]: https://www.hetzner.com/unternehmen/rechenzentrum
103+
[hcloud_token]: https://docs.hetzner.com/dns-console/dns/general/api-access-token/
104+
[hcloud_location]: https://docs.hetzner.com/cloud/general/locations/
105+
[hcloud_placement_group]: https://docs.hetzner.com/cloud/placement-groups/overview/
106+
[hcloud_image]: https://docs.hetzner.com/robot/dedicated-server/operating-systems/standard-images/
107+
[hcloud_networks]: https://docs.hetzner.com/cloud/networks/overview
108+
[hcloud_firewall]: https://docs.hetzner.com/robot/dedicated-server/firewall/
109+
[cloud_init]: https://cloudinit.readthedocs.io/en/latest/
110+
[nomad_datacenter]: /docs/configuration#datacenter
111+
[nomad_node_class]: /docs/configuration/client#node_class
112+
[nomad_node_drain_deadline]: /api-docs/nodes#deadline
113+
[nomad_node_purge]: /api-docs/nodes#purge-node
114+
[node_selector_strategy]: /tools/autoscaling/internals/node-selector-strategy
115+
116+
## Demo
117+
Run `terraform apply` in [demo](demo/setup) folder to create:
118+
- nomad server which runs services for:
119+
- nomad-autoscaler
120+
- prometheus
121+
- redis
122+
123+
Autoscaler scales hcloud nodes for redis. After successful run both Nomad and Consul are wide-world open and credentials for both you can find in terraform output

demo/modules/user-data/data/nomad.hcl.tmpl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
region = "global"
22
log_level = "INFO"
33
data_dir = "/opt/nomad"
4+
%{ if datacenter != "" }
5+
datacenter = "${datacenter}"
6+
%{ endif }
47
bind_addr = "0.0.0.0"
58
server = {
69
enabled = %{ if length(servers) == 0 }true%{else}false%{ endif }

demo/setup/jobs/autoscaler.hcl

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ job "autoscaler" {
1414
driver = "docker"
1515

1616
config {
17-
image = "achubatiuk/nomad-autoscaler:fix-scaler"
17+
image = "achubatiuk/nomad-autoscaler:main"
1818
command = "nomad-autoscaler"
1919
args = ["agent", "-config", "${NOMAD_TASK_DIR}/config.hcl", "-plugin-dir", "/plugins"]
2020
force_pull = true
@@ -40,12 +40,11 @@ scaling "cluster_class-batch" {
4040
4141
target "hcloud-server" {
4242
node_class = "redis"
43-
hcloud_location = "fsn1"
44-
hcloud_image = "ubuntu-20.04"
43+
datacenter = "dc1"
4544
hcloud_ssh_keys = "nomad"
46-
hcloud_server_type = "cx11"
4745
hcloud_group_id = "redis"
4846
hcloud_labels = "key1=value1"
47+
hcloud_location = "fsn1"
4948
hcloud_user_data = "{{ key "secrets/nomad/redis/user-data" }}"
5049
hcloud_b64_user_data_encoded = "true"
5150
}

demo/setup/main.tf

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ module "server_user_data" {
1616
source = "../modules/user-data"
1717
input = {
1818
"node_class" = "nomad-server"
19+
"datacenter" = "dc1"
1920
"servers" = []
2021
"interface" = "eth0"
2122
"consul_token" = ""
@@ -27,6 +28,7 @@ module "redis_client_user_data" {
2728
source = "../modules/user-data"
2829
input = {
2930
"node_class" = "redis"
31+
"datacenter" = "dc1"
3032
"servers" = module.nomad.ipv4_addresses
3133
"interface" = "eth0"
3234
"consul_token" = jsondecode(data.local_file.creds.content)["consul"]

go.mod

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ go 1.16
44

55
require (
66
github.com/armon/go-metrics v0.3.10 // indirect
7+
github.com/creasty/defaults v1.6.0
78
github.com/fatih/color v1.13.0 // indirect
9+
github.com/go-playground/locales v0.14.0
10+
github.com/go-playground/universal-translator v0.18.0
11+
github.com/go-playground/validator/v10 v10.10.1
812
github.com/google/go-cmp v0.5.7 // indirect
913
github.com/google/uuid v1.3.0
1014
github.com/gorilla/websocket v1.5.0 // indirect
@@ -20,12 +24,14 @@ require (
2024
github.com/hetznercloud/hcloud-go v1.33.1
2125
github.com/mattn/go-colorable v0.1.12 // indirect
2226
github.com/mitchellh/copystructure v1.2.0 // indirect
27+
github.com/mitchellh/mapstructure v1.4.3
2328
github.com/oklog/run v1.1.0 // indirect
2429
github.com/prometheus/common v0.33.0 // indirect
2530
github.com/stretchr/testify v1.7.1
2631
github.com/zclconf/go-cty v1.10.0 // indirect
2732
golang.org/x/net v0.0.0-20220412020605-290c469a71a5 // indirect
28-
golang.org/x/sys v0.0.0-20220412071739-889880a91fd5 // indirect
33+
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect
2934
google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac // indirect
30-
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
3135
)
36+
37+
replace github.com/hetznercloud/hcloud-go v1.33.1 => github.com/AndrewChubatiuk/hcloud-go v1.33.2

0 commit comments

Comments
 (0)