I’m looking into using secret_string_wo
for aws_secretsmanager_secret_version
, but I’ve encountered an issue where users without KMS key access permissions fail when running terraform plan
after the secret is created.
I think this error is being triggered by the implicitly executed terraform refresh
. Are there any good ways to avoid this error?
test code
resource "aws_secretsmanager_secret" "secret" {
name = "hoge"
kms_key_id = aws_kms_key.hoge.key_id
recovery_window_in_days = 7
policy = <<EOT
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::${local.aws_account_id}:role/aws-read-only"
},
"Action": "secretsmanager:GetSecretValue",
"Resource": "*"
}
]
}
EOT
}
resource "aws_secretsmanager_secret_version" "credential" {
secret_id = aws_secretsmanager_secret.secret.id
secret_string_wo = <<EOT
{
"password": "testpassword"
}
EOT
secret_string_wo_version = 1
}
Expected behavior
Terraform plan completes without errors.
Actual behavior
Terraform plan failed with following errors.
Planning failed. Terraform encountered an error while generating this plan.
╷
│ Error: reading Secrets Manager Secret Version (arn:aws:secretsmanager:ap-northeast-1:111111111:secret:hoge-xxxx|terraform-11111111111111111111111111111): operation error Secrets Manager: GetSecretValue, https response error StatusCode: 400, RequestID: 1111-1111-1111-1111-1111111111, api error AccessDeniedException: Access to KMS is not allowed
│
│ with aws_secretsmanager_secret_version.credential,
│ on secret.tf line 43, in resource "aws_secretsmanager_secret_version" "credential":
│ 43: resource "aws_secretsmanager_secret_version" "credential" {
│
It’s not “deterministic” make a plan without access the KMS to solve the dependency.
For the user, when running a plan, the key can:
- not exists
- have arn invalid
- don’t have perm.
- kms is invalid to encrypt in this secret.
You can solve this creating a staging kms for final users test their plans and change for real kms when apply.
Here in my work we use atlantis to create a plan with privileged user with final user code.
1 Like
Thank you for your answer.
You can solve this creating a staging kms for final users test their plans and change for real kms when apply.
Could you please tell me the specific method for replacing the KMS key?
I thought it could be achieved with the following code, but this would save the NOT staging KMS key(aws_kms_key.kms.key_id
) in tfstate, which would prevent the final user from running terraform plan due to insufficient permissions.
resource "aws_secretsmanager_secret" "example" {
name = "example"
kms_key_id = var.is_privileged_user ? aws_kms_key.kms.key_id : aws_kms_key.staging-kms.key_id
recovery_window_in_days = 7
}
Please correct me if my understanding is wrong.
I thought to use this resource, based in your piece of code:
resource "aws_secretsmanager_secret" "example" {
name = "example"
kms_key_id = local.is_a_privileged_user ? aws_kms_key.kms.key_id : aws_kms_key.staging-kms.key_id
recovery_window_in_days = 7
}
the local
you can get by assumed_role
when the user run plan/apply:
data "aws_caller_identity" "current" {}
locals {
is_a_privileged_user = < some calculation with data.aws_caller_identity.current.arn >
}
Copy
You can detect the role assumed by user and detect if is a admin or a developer…
But…
Why developers cannot access list/read kms? do you don’t need enable access to read content from kms, only read properties, list and “encrypt data”.
Why developers cannot access list/read kms? do you don’t need enable access to read content from kms, only read properties, list and “encrypt data”.
As you mentioned, the developer doesn’t need KMS access. The problem is that Terraform throws an error because it tries to read the kms_key_id
for the aws_secretsmanager_secret
. I tried the code you suggested too, but it also failed with an error when trying to read aws_kms_key.kms.key_id
.
Error: reading Secrets Manager Secret Version (arn:aws:secretsmanager:ap-northeast1:11111111:secret:hoge|terraform-111111111111111111111): operation error Secrets Manager: GetSecretValue, https response error StatusCode: 400, RequestID: xxxxxxxxxxxxxx, api error AccessDeniedException: Access to KMS is not allowed
Thank you for your answer. I’ll try to think about it myself.
1 Like