Part 2: Docker & Vault Agent with Dynamic Secrets
Part 3: Docker & Vault Agent with Docker Compose
Terraform
Sve prethodne dijelove ovog serijala smo pratili kroz izvršavanje naredbi u terminalu međutim, kao i u svim slučajevima, takav pristup je podložan pogreškama te bi bilo smislenije koristiti neki orkestrator tipa Hashicorp Terraform.
Preuzmite repozitorij na adresi https://github.com/myros/docker-vault-agent-terraform
git clone https://github.com/myros/docker-vault-agent-terraform
Repozitorij sadrži sve potrebno za praćenje ovog teksta stoga ga ne treba dodatno modificirati.
Spin up Vault
Prvo pokrenemo Vault container na slijedeći način:
terraform apply --target=docker_container.vault
Nakon planiranja i prikaza promjena, Terraform će tražiti potvrdu da se slažete sa izvršavanjem te će pokrenuti Vault container i pripremiti policu koju ćemo koristiti kasnije. Terraform log izgleda ovako:
...
Plan: 2 to add, 0 to change, 0 to destroy.
docker_network.private_network: Creating...
docker_network.private_network: Creation complete after 2s [id=f7640502520b3ad38c980122f033545140f8549b4742c42f4f2b284f7d7cd3fa]
docker_container.vault: Creating...
docker_container.vault: Creation complete after 0s [id=b2c1587c05189f4e68d5750d4d98a116d4993d559243ec71ded56e5f71799664]
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
Možete provjeriti da je Docker container zaista pokrenut
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b2c1587c0518 6a1ffdd512ce "docker-entrypoint.s…" 2 minutes ago Up 2 minutes (unhealthy) 0.0.0.0:8200->8200/tcp vault
a možemo se i prijaviti u UI na adresi http://localhost:8200 sa tokenom root
Vault Agent i Baze
Nakon što se uvjerimo da je sve ok, pokrenimo ostale dijelove.
terraform apply --auto-approve
Nakon izvršavanja pogledajmo stanje
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8607daf84720 6a1ffdd512ce "docker-entrypoint.s…" 38 seconds ago Up 36 seconds 8200/tcp vault-agent
cb57659215a9 30873abfecef "docker-entrypoint.s…" 38 seconds ago Up 36 seconds 3306/tcp, 33060/tcp mysql
06706c1b09cc 080ed0ed8312 "/docker-entrypoint.…" 38 seconds ago Up 37 seconds 0.0.0.0:80->80/tcp nginx
596f2a7c7ff5 236fd2f7b949 "docker-entrypoint.s…" 38 seconds ago Up 36 seconds 5432/tcp postgres
b2c1587c0518 6a1ffdd512ce "docker-entrypoint.s…" 5 minutes ago Up 5 minutes (unhealthy) 0.0.0.0:8200->8200/tcp vault
Vidimo da je sve u redu, baze su prisutne i agent je ovdje.
Napomena: Ukoliko dobijete slijedeću pogrešku, pričekajte par sekundi i izvršite terraform apply ponovo. Radi se samo o tome da baza nije spremna ali će biti dovoljno brzo da ne treba čekati predugo.
Error: error configuring database connection "mysql/config/items": Error making API request.
│
│ URL: PUT http://localhost:8200/v1/mysql/config/items
│ Code: 400. Errors:
│
│ * error creating database object: error verifying - ping: dial tcp 172.21.0.3:3306: connect: connection refused
│
│ with vault_database_secrets_mount.mysql,
│ on main.tf line 258, in resource "vault_database_secrets_mount" "mysql":
│ 258: resource "vault_database_secrets_mount" "mysql" {
Obzirom da datotke sadrže sve potrebno fokusirajmo se na Vault Agent i njegove logove.
$ docker logs -f vault-agent
==> Vault Agent started! Log data will stream in below:
==> Vault Agent configuration:
Api Address 1: http://bufconn
Cgo: disabled
Log Level:
2023-04-17T17:26:00.859Z [INFO] agent.sink.file: creating file sink
Version: Vault v1.13.1, built 2023-03-23T12:51:35Z
2023-04-17T17:26:00.864Z [INFO] agent.sink.file: file sink configured: path=/tmp/.token mode=-rw-r--r--
Version Sha: 4472e4a3fbcc984b7e3dc48f5a8283f3efe6f282
2023-04-17T17:26:00.864Z [INFO] agent.template.server: starting template server
2023-04-17T17:26:00.864Z [INFO] agent.auth.handler: starting auth handler
2023-04-17T17:26:00.864Z [INFO] agent.sink.server: starting sink server
2023-04-17T17:26:00.864Z [INFO] agent.auth.handler: authenticating
2023-04-17T17:26:00.864Z [INFO] (runner) creating new runner (dry: false, once: false)
2023-04-17T17:26:00.865Z [INFO] (runner) creating watcher
2023-04-17T17:26:00.866Z [INFO] agent.auth.handler: authentication successful, sending token to sinks
2023-04-17T17:26:00.866Z [INFO] agent.auth.handler: starting renewal process
2023-04-17T17:26:00.866Z [INFO] agent.sink.file: token written: path=/tmp/.token
2023-04-17T17:26:00.867Z [INFO] agent.auth.handler: renewed auth token
2023-04-17T17:26:00.875Z [INFO] agent.template.server: template server received new token
2023-04-17T17:26:00.875Z [INFO] (runner) stopping
2023-04-17T17:26:00.875Z [INFO] (runner) creating new runner (dry: false, once: false)
2023-04-17T17:26:00.875Z [INFO] (runner) creating watcher
2023-04-17T17:26:00.875Z [INFO] (runner) starting
2023-04-17T17:26:00.878Z [WARN] (view) vault.read(postgres/creds/nginx): vault.read(postgres/creds/nginx): Error making API request.
...
* unknown role: nginx (retry attempt 6 after "8s")
2023-04-17T17:26:16.641Z [WARN] (view) vault.read(postgres/creds/nginx): vault.read(postgres/creds/nginx): Error making API request.
URL: GET http://vault:8200/v1/postgres/creds/nginx
Code: 400. Errors:
* unknown role: nginx (retry attempt 7 after "16s")
2023-04-17T17:26:16.641Z [WARN] (view) vault.read(mysql/creds/nginx): vault.read(mysql/creds/nginx): Error making API request.
URL: GET http://vault:8200/v1/mysql/creds/nginx
Code: 400. Errors:
* unknown role: nginx (retry attempt 7 after "16s")
2023-04-17T17:26:32.654Z [INFO] (runner) rendered "/agent/psql.tmpl" => "/usr/share/nginx/html/psql.html"
2023-04-17T17:26:32.657Z [INFO] (runner) rendered "/agent/rails.tmpl" => "/usr/share/nginx/html/rails.yaml"
2023-04-17T17:26:32.661Z [INFO] (runner) rendered "/agent/mysql.tmpl" => "/usr/share/nginx/html/mysql.html"
Primjećujemo puno grešaka i puno prigovora od strane Agenta međutim na kraju vidimo 3 renderirane datoteke i ako pristupimo adresi http://localhost/kv.html vidjet ćemo podatke iz Vaulta.
U razgovoru s klijentima, uvijek preporučujem upotrebu Terraforma ispred ručnog izvršavanja naredbi ili upotrebe Postmana i to iz više razloga:
- Open Source ili besplatna Cloud verzija je dovoljno moćna za većinu korisnika
- Smanjuje se mogućnost pogreške ili zlouporabe te je kontrola nad izvršavanjem daleko veća
- Kod se može nalaziti u repozitoriju (Github, Gitlab, …) pa uz standardne procedure smanjujemo mogućnost nehotične izmjene infrastrukture
- Ako se kod nalazi u repozitoriju, možemo raditi Code Reviews
- Ako koristimo Terraform Cloud (TFC), obično je postavljen tako da TFC ima veća korisnička prava nego sam korisnik
- Povijest izvršavanja koju Vault nema, primjerice, izmjena police