Sometimes it’s important to set proper timezone on the server and recently I’ve got this task: set proper timezone automatically based on the server’s location in Azure Cloud. Moreover, I needed timezone to be set automatically by Terraform upon virtual machine creation. In my case I had Ubuntu VMs in Azure and here is the simple and elegant solution I came with:
Detect server’s timezone based on the location with World Time API
Amazing resource that shows all time-related information in either JSON or text format.
For example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# curl "http://worldtimeapi.org/api/ip" { "abbreviation": "EEST", "client_ip": "99.168.22.12", "datetime": "2023-04-19T14:49:15.009388+03:00", "day_of_week": 3, "day_of_year": 109, "dst": true, "dst_from": "2023-03-26T01:00:00+00:00", "dst_offset": 3600, "dst_until": "2023-10-29T01:00:00+00:00", "raw_offset": 7200, "timezone": "Asia/Singapore", "unixtime": 1681904955, "utc_datetime": "2023-04-19T11:49:15.009388+00:00", "utc_offset": "+03:00", "week_number": 16 } |
To get the same information in simple text format prepend the request with “.txt
” as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# curl "http://worldtimeapi.org/api/ip.txt" abbreviation: +08 client_ip: 4.188.111.99 datetime: 2023-04-19T20:24:33.870226+08:00 day_of_week: 3 day_of_year: 109 dst: false dst_from: dst_offset: 0 dst_until: raw_offset: 28800 timezone: Asia/Singapore unixtime: 1681907073 utc_datetime: 2023-04-19T12:24:33.870226+00:00 utc_offset: +08:00 |
And timezone can be easily get with standard bash
commands “grep
” and “cut
” as follows:
1 2 |
$ curl -s "http://worldtimeapi.org/api/ip.txt" | grep "timezone" | cut -d" " -f 2 Asia/Singapore |
In Ubuntu timezone can be set as:
1 |
# timedatectl set-timezone {timezone} |
So what we need now is to use results from World Time API as an argument to timedatectl
command. As simple as:
1 |
sudo timedatectl set-timezone `curl -s "http://worldtimeapi.org/api/ip.txt" | grep "timezone" | cut -d" " -f 2` |
Notice backticks around curl… command! It means “fill this place with execution result”.
And the last piece of the puzzle:
Set timezone automatically in Terraform
The command above can be used in remote-exec
provisioner right after VM is created:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
provisioner "remote-exec" { connection { host = self.public_ip_address type = "ssh" user = var.vm_user private_key = file(var.private_key) } inline = [ "some usefull stuff", "sudo timedatectl set-timezone `curl -s \"http://worldtimeapi.org/api/ip.txt\" | grep timezone | cut -d\" \" -f 2`", "sudo timedatectl set-ntp true", "timedatectl" ] } |
The last three commands: set virtual machine’s timezone based on it’s location, enable NTP syncronization and display current date/time and other timezone information so you can ensure it was set correctly.
That’s it! Have fun!