SSH connectivity from Jenkins to EC2 without permanent SSH keys!

Jenkins pipelines at times need SSH connectivity to apps on EC2. Yet, permanent storage of certificate chains in PEM files on Jenkins is not recommended. Why?

  1. PEM key proliferation problem: enterprise solutions have many keys
  2. Makes it impossible to automate Jenkins pipelines between environments.

AWS EC2 instance connect to the rescue!

Components of our reference implementation:

  1. IaaC for an app that installs ec2-instance-connect agent
    sudo yum install ec2-instance-connect
  2. A Jenkins container that installs EC2 instance connect CLI
    pip install ec2instanceconnectcli
  3. IAM policy granting appropriate permission for EC2 instance connect. Here are some AWS examples.
  4. Policy attached to IAM role used as instance profile for Jenkins.
  5. Policy attached to IAM user to enable localhost developer testing.

To achieve 3-5, here’s the code:

#!/usr/bin/env bash

aws iam create-policy --policy-name ec2-instance-connect --policy-document file://ec2-instance-connect-SendSSHPublicKey.json

policy_arn=$(aws iam list-policies --query 'Policies[?PolicyName==`ec2-instance-connect`].Arn' --output text)

#4
aws iam attach-role-policy --policy-arn ${policy_arn} --role-name JenkinsInstanceProfile

#5
aws iam attach-user-policy --policy-arn ${policy_arn} --user-name localhost-test-ec2-instance-connect