Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AWS: Implement resource to upload codecommit SSH keys for an IAM user #5744

Closed
keymon opened this issue Mar 21, 2016 · 5 comments
Closed

AWS: Implement resource to upload codecommit SSH keys for an IAM user #5744

keymon opened this issue Mar 21, 2016 · 5 comments

Comments

@keymon
Copy link
Contributor

keymon commented Mar 21, 2016

CodeCommit can be accessed via SSH. For that, you need a IAM user with the right policy and with some public SSH keys to access code commit uploaded. More info here.

The keys can be uploaded with awscli:

$ aws iam upload-ssh-public-key  --user-name keymon --ssh-public-key-body "$(< ~/.ssh/id_rsa.pub)"
{
    "SSHPublicKey": {
        "UserName": "keymon", 
        "Status": "Active", 
        "SSHPublicKeyBody": "ssh-rsa .... keymon@hostname", 
        "UploadDate": "2016-03-21T12:35:13.309Z", 
        "Fingerprint": "c9:e2:c9:e2:c9:e2:c9:e2:c9:e2:c9:e2:c9:e2:c9:e2:c9:e2:",
        "SSHPublicKeyId": "APKAABCABCABCABCABCABC"
    }
}

It would be great if terraform had a resource to upload, delete or update existing SSH keys on a IAM user. It might be called aws_iam_ssh_public_key, and it should work similar to the iam_access_key and the aws_key_pair resources:

More or less like this:

resource "aws_iam_ssh_public_key" "commiter" {
  user = "${aws_iam_user.commiter.name}"
  public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD3F6tyPEFEzV0LX3X8BsXdMsQz1x2cEikKDEY0aIj41qgxMCP/iteneqXSIFZBp5vizPvaoIR3Um9xK7PGoW8giupGn+EPuxIA4cDM4vzOqOkiMPhz5XK0whEjkVzTo4+S0puvDZuwIsdiW9mxhJc7tgBNL0cYlWSYVkz4G/fslNfRPW5mYAM49f4fhtxPb5ok4Q2Lg9dPKVHO/Bgeu5woMc7RY0p1ej6D4CKFE6lymSDJpW0YHX/wqE9+cfEauh7xZcG0q9t2ta6F6fmX0agvpFyZo8aFbXeUBr7osSCJNgvavWbM/06niWrOvYX2xwWdhXmXSrbX8ZbabVohBK41 email@example.com"
}

resource "aws_iam_user" "commiter" {
    name = "commiter"
    path = "/system/"
}

resource "aws_iam_user_policy" "codecommit_rw" {
    name = "codecommit_rw"
    user = "${aws_iam_user.commiter.name}"
    policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement" : [
    {
      "Effect" : "Allow",
      "Action" : [
        "codecommit:*"
      ],
      "Resource" : "*"
    }
  ]
}
EOF

@stack72
Copy link
Contributor

stack72 commented Mar 22, 2016

@keymon just a FYI, I have started a PR for this func

@stack72
Copy link
Contributor

stack72 commented Mar 22, 2016

Hi @keymon

this has been merged to master :)

Paul

@stack72 stack72 closed this as completed Mar 22, 2016
@keymon
Copy link
Contributor Author

keymon commented Mar 22, 2016

Wow, that was so quick!!! Thank you

keymon added a commit to alphagov/paas-cf that referenced this issue Mar 22, 2016
In order to access the codecommit repository via SSH, we must upload
a SSH key.

We add a required variable for the concourse terraform: `git_rsa_id_pub`,
which must have the public SSH key to add, and a new output 
`git_ssh_key_id` which is the key id of the ssh key and the user that 
must be used when connecting to the codecommit git repo.

But terraform does not currently support upload ssh keys, although
the PR is in master and will be released soon:

hashicorp/terraform#5744
hashicorp/terraform#5774

To workaround this, we implemented the following workaround:
 1. One template_file which contains the public key. 
      If it changes, it will run a script `aws-upload-aws-key.sh` to upload the 
      SSH key to the user. The script takes care of duplicates.
     
 2. A template_file resource will read from a `id_rsa_key_id`, and execute a
      script to query the ID if the file has changed since last execution. 
      This ensures that the file is updated.
       We must commit a empty file to avoid terraform fail the first run.
 
 3. Another template_file which reads the previous  populated 
     `id_rsa_key_id` file. This allows read the file content and expose it as 
      a terraform output.

This workaround can be removed and replaced as the resource
`aws_iam_user_ssh_key` is supported and released in the official
terraform release.
@keymon
Copy link
Contributor Author

keymon commented Mar 23, 2016

Just FYI, I paste here a workaround to implement the feature inside of terraform with awscli. But Ofc, better use the official provider that @stack72 quickly implemented as soon as it is ready.

# Workaround until this PR is released in terraform.
#
# https://github.com/hashicorp/terraform/pull/5774
# https://github.com/hashicorp/terraform/issues/5744
#
# We use a template to read a generated ssh public key. If it changed,
# we try to add it to the user using a local_exect provider
#
variable "git_rsa_id_pub" {
  description = "Public SSH key for the git user"
}

resource "template_file" "git_rsa_id_pub" {
  template = "${git_rsa_id_pub}"
  vars {
    git_rsa_id_pub = "${var.git_rsa_id_pub}"
  }
  # Upload the ssh key whenever this template changes
  provisioner "local-exec" {
    command = "${path.module}/aws-upload-aws-key.sh ${aws_iam_user.git.name} '${template_file.git_rsa_id_pub.rendered}'"
  }
}

# Query the key id of the just uploaded ssh public key, and
# write it to a file git_ssh_key_id which will be read by the next resource.
#
# This template will trigger the local_exec script everytime the file id_rsa_key_id
# is different than the state, and populate it with the right value.
resource "template_file" "git_ssh_key_id_query" {
  depends_on = ["template_file.git_rsa_id_pub"]
  template = "${git_ssh_key_id}"
  # Important, this must be used as variable to be evaluated in render time
  vars {
    git_ssh_key_id = "${trimspace(file("${path.module}/git_ssh_key_id"))}"
  }
  provisioner "local-exec" {
    command = "${path.module}/aws-get-aws-key-id.sh ${aws_iam_user.git.name} '${template_file.git_rsa_id_pub.rendered}' > ${path.module}/git_ssh_key_id"
  }
}

# We use a template so we can define a terraform output and it will be
# tracked in the terraform state.
resource "template_file" "git_ssh_key_id" {
  depends_on = ["template_file.git_ssh_key_id_query"]
  template = "${git_ssh_key_id}"
  # Important, this must be used as variable to be evaluated in render time
  vars {
    git_ssh_key_id = "${trimspace(file("${path.module}/git_ssh_key_id"))}"
  }
}

aws-get-aws-key-id.sh:

#!/bin/sh
set -e

username="$1"
id_rsa_pub=$(echo $2 | awk '{print $2}')

for key_id in $(aws iam list-ssh-public-keys --user-name "${username}" --query 'SSHPublicKeys[*].SSHPublicKeyId' | sed -n 's/.*\(AP.*\)".*/\1/p'); do
    key=$(aws iam get-ssh-public-key --encoding SSH --user-name "${username}" --ssh-public-key-id "${key_id}" --query 'SSHPublicKey.SSHPublicKeyBody')
    if echo "${key}" | grep -q "${id_rsa_pub}"; then
        echo $key_id
        exit 0
    fi
done
echo "Not found"
exit 1

aws-upload-aws-key.sh

#!/bin/sh
output=$(mktemp)
trap 'rm -f "${output}"' EXIT

aws iam upload-ssh-public-key --user-name $1 --ssh-public-key-body "$2" > "${output}" 2>&1
RET="$?"
cat "${output}"

if [ "${RET}" != "0" ]; then
    if grep -q "Duplicate SSH public key uploaded" "${output}"; then
        echo "Key is already uploaded."
        # Try to find out the key id
        exit 0
    else
        echo "Error uploading key"
        exit "${RET}"
    fi
fi

keymon added a commit to alphagov/paas-cf that referenced this issue Mar 23, 2016
In order to access the codecommit repository via SSH, we must upload
a SSH key.

We add a required variable for the concourse terraform: `git_rsa_id_pub`,
which must have the public SSH key to add, and a new output
`git_ssh_key_id` which is the key id of the ssh key and the user that
must be used when connecting to the codecommit git repo.

But terraform does not currently support upload ssh keys, although
the PR is in master and will be released soon:

hashicorp/terraform#5744
hashicorp/terraform#5774

To workaround this, we implemented the following workaround:
 1. One template_file which contains the public key.
      If it changes, it will run a script `aws-upload-aws-key.sh` to upload the
      SSH key to the user. The script takes care of duplicates.

 2. A template_file resource will read from a `id_rsa_key_id`, and execute a
      script to query the ID if the file has changed since last execution.
      This ensures that the file is updated.
       We must commit a empty file to avoid terraform fail the first run.

 3. Another template_file which reads the previous  populated
     `id_rsa_key_id` file. This allows read the file content and expose it as
      a terraform output.

This workaround can be removed and replaced as the resource
`aws_iam_user_ssh_key` is supported and released in the official
terraform release.
keymon added a commit to alphagov/paas-cf that referenced this issue Mar 23, 2016
In order to access the codecommit repository via SSH, we must upload
a SSH key.

We add a required variable for the concourse terraform: `git_rsa_id_pub`,
which must have the public SSH key to add, and a new output
`git_ssh_key_id` which is the key id of the ssh key and the user that
must be used when connecting to the codecommit git repo.

We use the resource `aws_iam_user_ssh_key` which has been added in this
issue and PR:

hashicorp/terraform#5744
hashicorp/terraform#5774
keymon added a commit to alphagov/paas-cf that referenced this issue Mar 23, 2016
In order to access the codecommit repository via SSH, we must upload
a SSH key.

We add a required variable for the concourse terraform: `git_rsa_id_pub`,
which must have the public SSH key to add, and a new output
`git_ssh_key_id` which is the key id of the ssh key and the user that
must be used when connecting to the codecommit git repo.

We use the resource `aws_iam_user_ssh_key` which has been added in this
issue and PR:

hashicorp/terraform#5744
hashicorp/terraform#5774
keymon added a commit to alphagov/paas-cf that referenced this issue Mar 23, 2016
In order to access the codecommit repository via SSH, we must upload
a SSH key.

We add a required variable for the concourse terraform: `git_rsa_id_pub`,
which must have the public SSH key to add, and a new output
`git_ssh_key_id` which is the key id of the ssh key and the user that
must be used when connecting to the codecommit git repo.

We use the resource `aws_iam_user_ssh_key` which has been added in this
issue and PR:

hashicorp/terraform#5744
hashicorp/terraform#5774
keymon added a commit to alphagov/paas-cf that referenced this issue Mar 23, 2016
In order to access the codecommit repository via SSH, we must upload
a SSH key.

We add a required variable for the concourse terraform: `git_rsa_id_pub`,
which must have the public SSH key to add, and a new output
`git_ssh_key_id` which is the key id of the ssh key and the user that
must be used when connecting to the codecommit git repo.

We use the resource `aws_iam_user_ssh_key` which has been added in this
issue and PR:

hashicorp/terraform#5744
hashicorp/terraform#5774
keymon added a commit to alphagov/paas-cf that referenced this issue Mar 23, 2016
In order to access the codecommit repository via SSH, we must upload
a SSH key.

We add a required variable for the concourse terraform: `git_rsa_id_pub`,
which must have the public SSH key to add, and a new output
`git_ssh_key_id` which is the key id of the ssh key and the user that
must be used when connecting to the codecommit git repo.

We use the resource `aws_iam_user_ssh_key` which has been added in this
issue and PR:

hashicorp/terraform#5744
hashicorp/terraform#5774
keymon added a commit to alphagov/paas-cf that referenced this issue Mar 23, 2016
We want to upload the generated SSH key to the created git user.

We use the resource `aws_iam_user_ssh_key` from terraform, implemented
in hashicorp/terraform#5744 so this requires
an updated version of terraform.

We retrieve the generated key as a s3 resource and pass it to terraform
as a TF_VAR_ variable.

After the key is uploaded, AWS assigns it a unique id which must be used
as user for SSH when connecting to the codecommit git repositories.

We render and output a full url with that ssh_key_id and the ssh url of the
repository, using scp like connect strings.
keymon added a commit to alphagov/paas-cf that referenced this issue Mar 23, 2016
We want to upload the generated SSH key to the created git user.

We use the resource `aws_iam_user_ssh_key` from terraform, implemented
in hashicorp/terraform#5744 so this requires
an updated version of terraform.

We retrieve the generated key as a s3 resource and pass it to terraform
as a TF_VAR_ variable.

After the key is uploaded, AWS assigns it a unique id which must be used
as user for SSH when connecting to the codecommit git repositories.

We render and output a full url with that ssh_key_id and the ssh url of the
repository. Note that the url must be in the ssh:// format, or
codecommit will drop the git connections.
keymon added a commit to alphagov/paas-cf that referenced this issue Mar 24, 2016
We want to upload the generated SSH key to the created git user.

We use the resource `aws_iam_user_ssh_key` from terraform, implemented
in _hashicorp/terraform#5744 so this requires
an updated version of terraform.

We retrieve the generated key as a s3 resource and pass it to terraform
as a TF_VAR_ variable.

After the key is uploaded, AWS assigns it a unique id which must be used
as user for SSH when connecting to the codecommit git repositories.

We render and output a full url with that ssh_key_id and the ssh url of the
repository. Note that the url must be in the ssh:// format, or
codecommit will drop the git connections.
keymon added a commit to alphagov/paas-cf that referenced this issue Mar 29, 2016
We want to upload the generated SSH key to the created git user.

We use the resource `aws_iam_user_ssh_key` from terraform, implemented
in _hashicorp/terraform#5744 so this requires
an updated version of terraform.

We retrieve the generated key as a s3 resource and pass it to terraform
as a TF_VAR_ variable.

After the key is uploaded, AWS assigns it a unique id which must be used
as user for SSH when connecting to the codecommit git repositories.

We render and output a full url with that ssh_key_id and the ssh url of the
repository. Note that the url must be in the ssh:// format, or
codecommit will drop the git connections.
keymon added a commit to alphagov/paas-cf that referenced this issue Mar 29, 2016
We want to upload the generated SSH key to the created git user.

We use the resource `aws_iam_user_ssh_key` from terraform, implemented
in _hashicorp/terraform#5744 so this requires
an updated version of terraform.

We retrieve the generated key as a s3 resource and pass it to terraform
as a TF_VAR_ variable.

After the key is uploaded, AWS assigns it a unique id which must be used
as user for SSH when connecting to the codecommit git repositories.

We render and output a full url with that ssh_key_id and the ssh url of the
repository. Note that the url must be in the ssh:// format, or
codecommit will drop the git connections.
keymon added a commit to alphagov/paas-cf that referenced this issue Mar 29, 2016
We want to upload the generated SSH key to the created git user.

We use the resource `aws_iam_user_ssh_key` from terraform, implemented
in _hashicorp/terraform#5744 so this requires
an updated version of terraform.

We retrieve the generated key as a s3 resource and pass it to terraform
as a TF_VAR_ variable.

After the key is uploaded, AWS assigns it a unique id which must be used
as user for SSH when connecting to the codecommit git repositories.

We render and output a full url with that ssh_key_id and the ssh url of the
repository. Note that the url must be in the ssh:// format, or
codecommit will drop the git connections.
keymon added a commit to alphagov/paas-cf that referenced this issue Mar 29, 2016
We want to upload the generated SSH key to the created git user.

We use the resource `aws_iam_user_ssh_key` from terraform, implemented
in _hashicorp/terraform#5744 so this requires
an updated version of terraform.

We retrieve the generated key as a s3 resource and pass it to terraform
as a TF_VAR_ variable.

After the key is uploaded, AWS assigns it a unique id which must be used
as user for SSH when connecting to the codecommit git repositories.

We render and output a full url with that ssh_key_id and the ssh url of the
repository. Note that the url must be in the ssh:// format, or
codecommit will drop the git connections.
keymon added a commit to alphagov/paas-cf that referenced this issue Mar 29, 2016
We want to upload the generated SSH key to the created git user.

We use the resource `aws_iam_user_ssh_key` from terraform, implemented
in _hashicorp/terraform#5744 so this requires
an updated version of terraform.

We retrieve the generated key as a s3 resource and pass it to terraform
as a TF_VAR_ variable.

After the key is uploaded, AWS assigns it a unique id which must be used
as user for SSH when connecting to the codecommit git repositories.

We render and output a full url with that ssh_key_id and the ssh url of the
repository. Note that the url must be in the ssh:// format, or
codecommit will drop the git connections.
@ghost
Copy link

ghost commented Apr 27, 2020

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@ghost ghost locked and limited conversation to collaborators Apr 27, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants