AWS hat ein Produkt, dass AWS Secretsmanager heisst und einem unglaublich wenig Speicherplatz für unglaublich teuer Geld anbietet.
Ab und an braucht man Geheimnisse auf seiner EC2 Instanz. Geheimnisse die ich nicht in meinen Sourcecode einchecken will, aber irgendie maschinenlesbar abgespeichert werden müssen.
Mittels oben genanntem SecretsManager und dem aws
Commandline Tool lassen sich diese Secrets anzeigen.
Pricing?
Ein Secret kostet $0.40. Außerdem darf ein Secret maximal 65536 bytes groß sein. Wenn man das auf den Preis pro GB hochrechnet, kostet 1GB schlappe $6103,20. Zum Vergleich, 1GB S3 kostet $0.023 pro GB.
Ich schweife ab.
IAM Polciies
Der normale Weg mit aws
Commandline Tool wäre, mich mittels Access Key und
Secret Key einzuloggen. Da ich aber nicht auf jeder meiner EC2 Instanzen
Credentials ablegen will, kann ich eine IAM Policy erstellen, die jeder
Instanz ohne Credentials den Zugang zu bestimmten Secrets erlaubt.
Beispielhaft ein Terraform IAM Policy Document
data "aws_iam_policy_document" "this" {
statement {
actions = [
"secretsmanager:ListSecrets",
"secretsmanager:DescribeSecret",
"secretsmanager:GetResourcePolicy",
"secretsmanager:GetSecretValue",
"secretsmanager:ListSecretVersionIds"
]
resources = [
"arn:aws:secretsmanager:eu-central-1:xxx:secret:prod_rds-xxx",
]
effect = "Allow"
}
}
aws
Commandline Tool und jq
Wenn das Instanzprofil jetzt der EC2 Instanz zugewiesen ist, kann man aws
und jq
benutzen, um die Values aus dem Secret auszulesen.
$ aws secretsmanager get-secret-value --secret-id prod_rds
{
"Name": "prod_rds",
"SecretString": "{\"password\":\"secret1\",\"user\":\"username1\"}",
"VersionStages": [
"AWSCURRENT"
],
"CreatedDate": 1637933085.518,
"ARN": "arn:aws:secretsmanager:eu-central-1:xxx:secret:prod_rds-xxx"
}
Problem hierbei ist, dass der Output in Json und der SecretString erneut in
Json encodiert ist. Aber dafür gibt es eine Lösung. jq
.
$ aws secretsmanager get-secret-value --secret-id prod_rds \
| jq -r '.SecretString'
{"password":"secret1","user":"username1"}
Der Trick ist jetzt, mittels fromjson
die Value eines Attributs erneut zu
parsen. Danach kann man nämlich auf die eingebetteten Attribute wie
password
zugreifen.
$ aws secretsmanager get-secret-value --secret-id prod_rds \
| jq -r '.SecretString | fromjson | .password'
secret1
Das kann ich jetzt mittels Ansible oder CloudInit oder sonst was für meine eigentliche Applikation einbetten und weiterverarbeiten.
Credentials im Repo? Nein danke :)