Search code examples
amazon-web-servicesterraformterraform-provider-awsamazon-kmsterraform0.12+

Terraform AWS VPC and KMS: Reading KMS Key AccessDeniedException


module.vpc.aws_route.private_nat_gateway[0]: Refreshing state... [id=r-rtb-0757df1e6d39122912345678987] module.vpc_endpoints.data.aws_vpc_endpoint_service.this["s3"]: Read complete after 0s [id=421234567] module.vpc_endpoints.aws_vpc_endpoint.this["s3"]: Refreshing state... [id=vpce-0c225a51234567898]

Error: reading KMS Key (999999999-c13c-8888-a5cb-9876554321): reading KMS Key (999999999-c13c-8888-a5cb-9876554321): AccessDeniedException: User: arn:aws:iam::12345678998765:user/peter.user is not authorized to perform: kms:DescribeKey on resource: arn:aws:kms:us-east-2:12345678998765:key/999999999-c13c-8888-a5cb-9876554321 because no resource-based policy allows the kms:DescribeKey action

I got above KMS key errors when I run the code as follows to provision VPC. I have three questions:

  1. Why the code as follows uses the KMS Key?
  2. How to make the code as follows to not using the KMS key someone created (Note: the person who created the key has left)?
  3. I created my own key, how to use the KMS key I created instead?
module "vpc" {
  source = "terraform-aws-modules/vpc/aws"
  version = "5.0.0"

  azs                                             = local.availability_zones
  cidr                                            = local.vpc_cidr
  create_database_subnet_group                    = false
  create_flow_log_cloudwatch_iam_role             = true
  create_flow_log_cloudwatch_log_group            = true
  database_subnets                                = local.database_subnets
  enable_dhcp_options                             = true
  enable_dns_hostnames                            = true
  enable_dns_support                              = true
  enable_flow_log                                 = true
  enable_nat_gateway                              = true
  flow_log_cloudwatch_log_group_retention_in_days = var.days
  flow_log_max_aggregation_interval               = var.interval
  name                                            = var.environment
  one_nat_gateway_per_az                          = false
  private_subnets                                 = local.private_subnets
  public_subnets                                  = local.public_subnets
  single_nat_gateway                              = true
  tags                                            = var.tags
}

module "vpc_endpoints" {
  source = "terraform-aws-modules/vpc/aws//modules/vpc-endpoints"
  version = "5.0.0"
  vpc_id = module.vpc.vpc_id
  tags   = var.tags

  endpoints = {
    s3 = {
      route_table_ids = flatten([module.vpc.private_route_table_ids, module.vpc.public_route_table_ids])
      service         = "s3"
      service_type    = "Gateway"
      tags            = { Name = "s3-vpc-endpoint" }
    }
  }
}

Solution

  • Check the key resource policy if it allows your principle and also check if your IAM policy on your user is able to access and decrypt with the KMS key.

    You won't be able to solve it another way because Terraform needs a describe key to get the state of the resource so it fails in the plan stage before it can finish the plan.