How to rsadecrypt and get password_data from AWS Windows Server instance?

I’m using Terraform to deploy a Windows Server 2016 instance on AWS. I don’t see a single working example online for how to get the instance password.

With some code:

resource “aws_instance” “vmware_poc_server” {
ami = “ami-08bf5f54919fada4a”
instance_type = “t3.xlarge”
key_name = aws_key_pair.vmware_poc.key_name
vpc_security_group_ids = ["${aws_security_group.vmware_poc_server.id}"]
associate_public_ip_address = “false”
get_password_data = “true”

root_block_device {
volume_size = “100”
volume_type = “standard”
delete_on_termination = “true”
}
}
output “Administrator_Password” {
value = “${rsadecrypt(aws_instance.vmware_poc_server.password_data, file(var.private_key))}”
}

I get:

Call to function “rsadecrypt” failed: asn1: structure error: tags don’t match
(16 vs {class:1 tag:15 length:112 isCompound:true}) {optional:false
explicit:false application:false private:false defaultValue: tag:
stringType:0 timeType:0 set:false omitEmpty:false} pkcs1PrivateKey @2.

Does anyone have working examples for this?

It works for me, here is my experience for what it’s worth. I created my key pair using ssh-keygen on my Mac (Catalina OS). That sadly wouldn’t work with AWS out of the box when you apply it against third party tools like Terraform. It may work for the AWS console, likely because they have conversion tools in the console.

In saying that, if I used a key pair that I generated on AWS directly, it actually works for me.
Use your private key (*.pem) you download from the Key Pair Generation tool in EC2 AWS Console when it comes time to decrypt the password. At the time when you are creating the instance, definitely use the public key associated with the *.pem file you downloaded from AWS Console. Also remember to set get_password_data = true in the aws_instance snippet.

Good luck, and please let me know how that goes for you.
Here is a sample of the code I used and it works.


provider "aws" {
  region = "${var.aws_region}"
  access_key = "${var.aws_access_key}"
  secret_key = "${var.aws_secret_key}"
  version = "2.7"
}

data "aws_ami" "os_windows" {

    filter {
       name ="name" #id = "ami-0399e1fa4369454f8"
       values = ["Windows_Server-2019-English-Full-SQL_2017_Express-2020.02.12"]   #ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-20190212.1
    }
    owners  = ["amazon"]
}

################################################
### Create our EC2 Instance. #
################################################
resource "aws_instance" "instance" {
    
  ami               = "${data.aws_ami.os_windows.id}"                    
  instance_type     = "t2.small"
  key_name          = "${aws_key_pair.kms.key_name}"

  get_password_data = true                                    ### Important to have this tag to force aws to generate the password for decryption
  security_groups   = [
    "${aws_security_group.sg_allow_ssh.name}",
    "${aws_security_group.sg_allow_outbound.name}"
  ]

resource "aws_eip" "instance_ip" {                  
  vpc      = true                                                      
  instance = "${aws_instance.instance.id}"
}


resource "aws_security_group" "sg_allow_ssh" {
  description = "Instance Inbound traffic"

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    from_port   = 3389
    to_port     = 3389
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

resource "aws_security_group" "sg_allow_outbound" {
  description = "outbound traffic"

  egress {
    from_port = 0
    to_port = 0
    protocol = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

resource "aws_key_pair" "kms" {
  //key_name   = "instance_kms_key"
  public_key = "${file("~/.ssh/_root_kp.pub")}"
}

data "aws_vpc" "default" {
  default = true
}

data "aws_subnet_ids" "all" {
  vpc_id = "${data.aws_vpc.default.id}"
}

##################################################################
# OUTPUTS
##################################################################

output "provider-version" {
  value = "${var.aws_provider_version}"
}

output "server-ip" {
  value = "${aws_eip.instance_ip.public_ip}"
}

output "password_data" {
  value="${aws_instance.instance.password_data}"
}

output "password_decrypted" {
  value=rsadecrypt(aws_instance.instance.password_data, file("~/.ssh/_root_kp.pem") ) 
}

I ran into this and filed an issue on our GitHub issue tracker to track this issue.

This should be fixed in 0.13.0 when https://github.com/hashicorp/terraform/pull/25112 is merged