Creating and using an SSH key pair to use on AWS

Now we have our AWS provider configured in Terraform, let's add a SSH key pair to use on a default account of the virtual machines we intend to launch soon.

Getting ready

To step through this recipe, you will need the following:

  • A working Terraform installation
  • An AWS provider configured in Terraform
  • Generate a pair of SSH keys somewhere you remember, for example, in the keys folder at the root of your repo:
    $ mkdir keys
    $ ssh-keygen -q -f keys/aws_terraform -C aws_terraform_ssh_key -N ''
    
  • An Internet connection

How to do it…

The resource we want for this is named aws_key_pair. Let's use it inside a keys.tf file, and paste the public key content:

resource "aws_key_pair" "admin_key" {
  key_name   = "admin_key"
  public_key = "ssh-rsa AAAAB3[…]"
}

This will simply upload your public key to your AWS account under the name admin_key:

$ terraform apply
aws_key_pair.admin_key: Creating...
  fingerprint: "" => "<computed>"
  key_name:    "" => "admin_key"
  public_key:  "" => "ssh-rsa AAAAB3[…]"
aws_key_pair.admin_key: Creation complete

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

If you manually navigate to your AWS account, in EC2 | Network & Security | Key Pairs, you'll now find your key:

How to do it…

Another way to use our key with Terraform and AWS would be to read it directly from the file, and that would show us how to use file interpolation with Terraform.

To do this, let's declare a new empty variable to store our public key in variables.tf:

variable "aws_ssh_admin_key_file" { }

Initialize the variable to the path of the key in terraform.tfvars:

aws_ssh_admin_key_file = "keys/aws_terraform"

Now let's use it in place of our previous keys.tf code, using the file() interpolation:

resource "aws_key_pair" "admin_key" {
  key_name   = "admin_key"
  public_key = "${file("${var.aws_ssh_admin_key_file}.pub")}"
}

This is a much clearer and more concise way of accessing the content of the public key from the Terraform resource. It's also easier to maintain, as changing the key will only require to replace the file and nothing more.

How it works…

Our first resource, aws_key_pair takes two arguments (a key name and the public key content). That's how all resources in Terraform work.

We used our first file interpolation, using a variable, to show how to use a more dynamic code for our infrastructure.

There's more…

Using Ansible, we can create a role to do the same job. Here's how we can manage our EC2 key pair using a variable, with the name admin_key. For simplification, we're using the three usual environment variables—AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_DEFAULT_REGION:

Here's a typical Ansible file hierarchy:

├── keys
│   ├── aws_terraform
│   └── aws_terraform.pub
├── main.yml
└── roles
    └── ec2_keys
        └── tasks
            └── main.yml

In the main file (main.yml), let's declare that our host (localhost) will apply the role dedicated to manage our keys:

---
- hosts: localhost
  roles:
  - ec2_keys

In the ec2_keys main task file, create the EC2 key (roles/ec2_keys/tasks/main.yml):

---
  - name: ec2 admin key
    ec2_key:
      name: admin_key
      key_material: "{{ item }}"
    with_file: './keys/aws_terraform.pub'

Execute the code with the following command:

$ ansible-playbook -i localhost main.yml
TASK [ec2_keys : ec2 admin key] ************************************************
ok: [localhost] => (item=ssh-rsa AAAA[…] aws_terraform_ssh)

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.37.196