hashicorp / terraform-provider-aws

The AWS Provider enables Terraform to manage AWS resources.
https://registry.terraform.io/providers/hashicorp/aws
Mozilla Public License 2.0
9.77k stars 9.13k forks source link

resource/aws_key_pair: Terraform state leaks on interrupt #31731

Open ialidzhikov opened 1 year ago

ialidzhikov commented 1 year ago

Terraform Core Version

v1.3.9

AWS Provider Version

v4.55.0

Affected Resource(s)

Expected Behavior

terraform/terraform-provider-aws to be resilient to interrupts and to do not leak terraform state when interrupt is received. We run terraform in quite automated manner without human interaction. Everytime state leaks, a human operator has to analyse it and fix it manually.

Actual Behavior

terraform/terraform-provider-aws leaks state when first terraform apply (that creates the resources) is interrupted.

Relevant Error/Panic Output Snippet

No response

Terraform Configuration Files

terraform {
  required_providers {
    aws = {
      version = "4.55.0"
    }
    null = {
      version = "3.2.1"
    }
  }
}

provider "aws" {
  access_key = var.ACCESS_KEY_ID
  secret_key = var.SECRET_ACCESS_KEY
  region     = "eu-west-1"
}

resource "aws_key_pair" "kubernetes" {
  key_name   = "shoot--foo--bar-ssh-publickey"
  public_key = "ssh-rsa <omitted>"
}

//=====================================================================
//= Output variables
//=====================================================================

output "keyName" {
  value = aws_key_pair.kubernetes.key_name
}
variable "ACCESS_KEY_ID" {
  description = "AWS Access Key ID of technical user"
  type        = string
}

variable "SECRET_ACCESS_KEY" {
  description = "AWS Secret Access Key of technical user"
  type        = string
}

Steps to Reproduce

  1. Run terraform apply -auto-approve and interrupt the terraform process (Ctrl + C) when it start creating the key pair.
aws_key_pair.kubernetes: Creating...
^C
Interrupt received.
Please wait for Terraform to exit or data loss may occur.
Gracefully shutting down...

Stopping operation...
╷
│ Error: execution halted
│
│
╵
╷
│ Error: execution halted
│
│
╵
╷
│ Error: importing EC2 Key Pair (shoot--foo--bar-ssh-publickey): RequestCanceled: request context canceled
│ caused by: context canceled
│
│   with aws_key_pair.kubernetes,
│   on main.tf line 19, in resource "aws_key_pair" "kubernetes":
│   19: resource "aws_key_pair" "kubernetes" {
│
╵
  1. Run terraform apply -auto-approve again. Make sure that state for some security group rules is not saved in the terraform state but they actually exist in AWS.
Plan: 1 to add, 0 to change, 0 to destroy.
aws_key_pair.kubernetes: Creating...
╷
│ Error: importing EC2 Key Pair (shoot--foo--bar-ssh-publickey): InvalidKeyPair.Duplicate: The keypair already exists
│   status code: 400, request id: <omitted>
│
│   with aws_key_pair.kubernetes,
│   on main.tf line 19, in resource "aws_key_pair" "kubernetes":
│   19: resource "aws_key_pair" "kubernetes" {
│
╵

Any subsequent terraform apply run fails with the above error InvalidKeyPair.Duplicate: The keypair already exists.

Debug Output

No response

Panic Output

No response

Important Factoids

No response

References

Would you like to implement a fix?

None

github-actions[bot] commented 1 year ago

Community Note

Voting for Prioritization

Volunteering to Work on This Issue

DhruvinSoni30 commented 1 year ago

@ialidzhikov Did you check whether the key has been created in your AWS account or not?

ialidzhikov commented 1 year ago

When the key pair creation fails with InvalidKeyPair.Duplicate: The keypair already exists, it obviously gets created in AWS..

DhruvinSoni30 commented 1 year ago

Agree with your point but the thing here is if the state file is having an entry of key pair and when you interrupt the terraform action then it is obvious that the state file won't delete the entry of the key pair right?

ialidzhikov commented 1 year ago

Obviously it is not saved in the terraform state due to the interrupt and that's why it tries to create it again.

DhruvinSoni30 commented 1 year ago

This error InvalidKeyPair.Duplicate: The keypair already exists indicates that the key's identity is present in the state file

ialidzhikov commented 1 year ago

Are you sure? I think that this is the error returned by the AWS API.

DhruvinSoni30 commented 1 year ago

I am sure about that, you can check the state file.

ialidzhikov commented 1 year ago

I don't think so. If it is present in the state file, it should not try to create it again. Anyways, I already provided detailed enough steps to reproduce. You can also reproduce on your side to confirm/reject your assumption.

DhruvinSoni30 commented 1 year ago

Sure, I'll try to reproduce it.