Motivation

Adding ssh-keys of a developer,qas never been a fun work to do.

How we nailed it.

In gist, we automate the whole process in 3 breakdowns:

  1. collect ips from our rails apps repo from github src code #kudoscflibs #kudooctokit
  2. pulling public keys from github
  3. pushing to authorized keys list for deploy user

Ansible is awesome, so is github. —randomvoice

Since our ec2-machines are tagged with roles, we have them all in our config/deploy/environment.rb files. Remember the old legecy msg, Public Key *Permission denied (publickey).* when deploying with capistrano. Ho tehi. 😜

So in details: tl;dr Steps:

        - name: collet hostnames first
          uri:
            url: "http://{{SINATRA_URI|default('localhost:4567')}}/getroles?repo_name={{REPO_NAME|default('org/repo')}}&environment={{ENVIRONMENT|default('test')}}"
            register: registered_ips
            tags:
              - get_ips
- Fetch the ips from sinatra app as a json list

        # GET /getroles?repo_name=sprout/worker_paltform&environment=staging
        get '/getroles' do
          content_type :json
          repo_name = params[:repo_name] || "org/repo"
          environment = params[:environment] || "testing"
          config_path = params[:config_path] || "config/deploy/"+ environment +".rb"
          
          #get a login, please get netrc gem first
          client = Octokit::Client.new(:netrc => true)
          
          #pull contents of file
          file = client.content( repo_name, :path => config_path)
        
        
          #decode and process
          #thanks cmthakur, #theKing: https://github.com/cmthakur
          content_array = Base64.decode64(file.content).split("\n")
          ec2_roles = content_array.map do |content| 
            if content.scan('IFR').count > 0
              content.scan(/('(.*?)'|"(.*?)")/).flatten[1]
            end
          end.flatten.uniq.compact
          puts ec2_roles
          #{roles: ec2_roles}.to_json
        
        
          #get ips, awesome cflibs
          ec2_handle = CLOUDFACTORY::AWESOMELIBRARIES::AWSEC2.new
          ec2_ips = [ ]
          ec2_roles.each do |role|
            ec2_ips << ec2_handle.IFR(role).map(&:ipAddress)
          end
          puts ec2_ips.flatten
          {ips: ec2_ips.flatten}.to_json
        end
- Created dynamic inventory list with addhosts module

          - name: build strings
            add_host:
              hostname: "{{item}}"
              groups: hosts_to_add_keys
            with_items: registered_ips.json.ips
            tags:
              - get_ips
- Pushed public keys to those host with public key lookup withurl

    - hosts: hosts_to_add_keys
      tasks:
        - name: Set up authorized_keys for the deploy user
          authorized_key:
            user="deploy"
            key="{{item}}"
            state="{{STATE|default('present')}}"
          with_url:
            - "https://github.com/{{GITHUB_USERNAME|default('kajisaap')}}.keys"
          tags:
            - web_lookup
            

In gist:

It was a nice weekend fun work saving a lot of time for me and my hangry deploying friends, making everyones happy.

keys on kneez boss :p

So everyonez lived and deployed/debuged the codebase happily after. 😄