I've been going through answers to similar questions on this StackExchange and on StackOverflow and reading through documentations all day ...

Here's the .tf file I'm executing:

    # defines the AWS provider
    provider "aws" {
      # credentials path: ~/.aws/credentials
      profile = var.aws_profile
    }
    resource "aws_key_pair" "key_pair" {
      # variable's default value: "id_rsa"
      key_name   = var.aws_key_pair_name
      # variable's default value: public key of "id_rsa"
      public_key = var.aws_key_pair_public
    }
    resource "aws_security_group" "security_group" {
      ingress {
        from_port = 22
        to_port = 22
        protocol = "tcp"
        cidr_blocks = ["0.0.0.0/0"]
      }
      egress {
        from_port = 0
        to_port = 0
        protocol = "-1"
        cidr_blocks = ["0.0.0.0/0"]
      }
      tags = {
        # variable's default value: "security-group-1"
        Name = var.aws_security_group_tags_name
      }
    }
    resource "aws_instance" "instance" {
      # variable's default value: ID of the Ubuntu AMI
      ami = var.aws_instance_ami
      # variable's default value: "t2.micro"
      instance_type = var.aws_instance_type
      associate_public_ip_address  = true
      key_name = aws_key_pair.key_pair.key_name
      vpc_security_group_ids = [aws_security_group.security_group.id]
      tags = {
        # variable's default value: "ec2-instance-1"
        Name = var.aws_instance_tags_name
      }
    }
    resource "null_resource" "instance" {
      provisioner "remote-exec" {
        connection  {
          type = "ssh"
          host = aws_instance.instance.public_ip
          # variable's default value: "ubuntu", Ubuntu AMI's default system user account
          user = var.aws_instance_user_name
          # variable's default value: "~/.ssh/id_rsa"
          # the path to the public key provided to aws_key_pair.key_pair
          private_key = file(var.aws_key_pair_private_path)
          timeout = "20s"
        }
        inline = ["echo 'remote-exec message'"]
      }
      provisioner "local-exec" {
        command = "echo 'local-exec message'"
      }
    }

It's returning the following error:

    aws_instance.instance (remote-exec): Connecting to remote host via SSH...
    aws_instance.instance (remote-exec):   Host: 54.82.23.158
    aws_instance.instance (remote-exec):   User: ubuntu
    aws_instance.instance (remote-exec):   Password: false
    aws_instance.instance (remote-exec):   Private key: true
    aws_instance.instance (remote-exec):   Certificate: false
    aws_instance.instance (remote-exec):   SSH Agent: true
    aws_instance.instance (remote-exec):   Checking Host Key: false
    aws_instance.instance (remote-exec):   Target Platform: unix
    aws_instance.instance: Still creating... [1m0s elapsed]
    ╷
    │ Error: remote-exec provisioner error
    │ 
    │   with aws_instance.instance,
    │   on main.tf line 63, in resource "aws_instance" "instance":
    │   63:   provisioner "remote-exec" {
    │ 
    │ timeout - last error: SSH authentication failed ([email protected]:22): ssh: handshake failed: ssh: unable to
    │ authenticate, attempted methods [none publickey], no supported methods remain

What am I missing? Are any parts of my code redundant?