Automating IAM Instance Profile with Ansible

My previous post talked about creating AWS IAM Instance Profiles so you don’t have to save keys on the instances. In this post, we’ll look at using Ansible to launch EC2 instances with IAM Instance Profiles attached to them (you don’t want to do this manually forever, do you?).

(You cannot attach IAM Instance Profiles to existing instances, unfortunately).

Assuming that you already have in place an IAM user that you’ve dedicated for use by Ansible, let’s head to the next step. In order for this IAM user to attach IAM Instance Profiles to EC2 instances, the user will have to be setup with “PassRole” privileges.

Head to the AWS Console and navigate to Identity and Access Management (IAM). Hit the “Users” tab and click on the user, as discussed above.

policy (1)

Then, hit the “Permissions” tab and scroll down to “Inline Policies”, and hit “click here”.

policy (2)

In the “Set Permissions” page, select “Policy Generator” and hit Select.

policy (3)

In the AWS Service drop down, select AWS IAM, and then select “PassRole” from the Actions drop down. Paste in the ARN of the role created from the previous blog post.

policy-333

Click “Add Statement” and head to the next screen for a Summary.

policy (4)

Hit Next to arrive at the final Review screen.policy (5)

Hit Apply Policy to finish.

Your Ansible playbooks can now create EC2 instances with IAM Instance Profiles attached to them. You’re done!

Posted in Amazon Web Services, Tech. | Tagged , , , , , , , , | Leave a comment

Simple Howto: AWS IAM Instance Profiles

For those of you looking to set up applications to run on EC2 instances without having to put credentials on the machines, there is an option. AWS has a great feature for exactly this purpose, and it’s called IAM Instance Profiles.

The IAM Instance Profile feature allows EC2 instances to call other AWS services on your behalf, with no need for setting up keys on the instance. AWS takes care of securing the keys within instance metadata, and also rotates keys regularly. More info here.

In my case, I was trying to setup Logstash to run on EC2 instances, talking to S3 buckets, without having to hard-code keys or upload them to the instance itself. This AWS feature saved the day.

Let’s get started with setting up an IAM Instance Profile. To begin with, login to the AWS Console and head to Identity and Access Management (IAM). Once there, click “Create Role”. Then, enter a name for the role:

role (1)

On the next page, select Role Type as “Amazon EC2”. This will create the necessary IAM Instance Profile in the background, with the same name as the role.

role (2)

Next, attach a policy to this role depending on your use case. In my case I wanted S3 access from my instances, so I selected AmazonS3FullAccess.

role (3)

Click Finish. On the review page, grab the Role ARN for later use. We’re done!

role (4)

Now, to launch instances using this IAM Instance Profile, simply select the IAM Role from the dropdown on the “Configure Instance Details” page.

role (5)png

You’re all set with IAM Instance Profiles!

Posted in Amazon Web Services, Tech. | Tagged , , , , , , , | Leave a comment

TravisCI: Export From Bash Scripts

Let’s say your TravisCI file is cluttering up due to having too many shell / bash commands in the “.travis.yml” file and you’ve decided to move the commands out to a separate shell script. Now, you’ll want to get export/return data out from this script but you don’t know how. There are two ways to approach this.

If your bash script is only expected to return one value, then you may want to call it from the TravisCI yaml file this way:

script:
- export ENDPOINT=$(bash discover_service.sh);

And you’ll want to add this to the bash script you’re calling (exit returns the variable to whatever’s calling it):

if [ $TRAVIS_BRANCH == 'master' ]; then  
  exit $ENDPOINT  
else  
  exit $ENDPOINT
fi

 

However, if your bash script sets multiple variables or is expected to generate a lot of data, you could “source” it from the TravisCI yaml file this way:

script:
   - . ./deploy.sh

I hope that was helpful!

Posted in DevOps, Tech. | Tagged , , , , , , , , | Leave a comment

Learn Scrum in Less Than An Hour

Well, if you’re part of an organization that does not do Agile (Scrum or not), OR an organization that’s in a transformation towards it, OR in an organization that already does Agile but you’re new and do not know what it is, then look no further than this book right here: http://amzn.to/1tiovv9

Scrum: a Breathtakingly Brief and Agile Introduction

This is an amazingly short, crisp, and distilled book that doesn’t waste any time in beating around the bush or thanking their family and friends for their help and patience in writing it. The book quickly gets to talking about the various features of Scrum form of Agile – including: Roles, Scrum Artifacts, Sprints (and what they mean), and, well, that’s almost it! At the end of the read you’d have come out with a very clear foundational idea of what Scrum is. You could choose to further explore each of the topics on your own (Google?) for further information or clarification.

This is also one of those books that you could give out to your team if you’re part of an organization about to embark on an Agile Scurm journey. It’s cheap, apt, concise and will get the team going in a very short time.

I’m a huge fan of short books that can be re-read regularly – I prefer this form over long books where you forget the context of the first chapter by the time you get to the last one. I chose the Kindle version of the book which is under a dollar and is cheaper than a can of soda.

Posted in Reviews, Tech. | Tagged , , , , | Leave a comment

Public IP Address of Private AWS Instances?

Do you want to find out the public IP address of your private instances (those in a private VPC subnet) but don’t know how? An easy way to do this would be to just do a “whatsmyip” equivalent on the private instance such as this:

wget http://ipecho.net/plain -O - -q ; echo

However, there’s an even easier way to figure this out, especially if AWS is your bread and butter. Every private instance communicates to the outside world via a NAT instance or a NAT gateway (yes, this is your ‘duh’ moment). So, all that you need is your NAT gateway’s or NAT instance’s Elastic IP address and you’re done.

In my case, I was trying to allow an ELB on one AWS account to see traffic from private instances on another AWS account. So, I just added an entry to the ELB’s security group to listen from the NAT gateway’s Elastic IP of the other AWS account and I was done.

Posted in Amazon Web Services, Linux, Tech. | Tagged , , , , , , , , , | Leave a comment

TravisCI and Ansible on AWS

If you’re trying to use Travis CI and Ansible playbooks to spin up and configure instances on AWS, you’ll want to do things at some point:

  1. Configure instances on private subnets with Ansible via bastion host
  2. Secure the said Bastion host’s security group to talk to TravisCI

The problem is that Travis CI is a hosted service on the Internet, whereas your instances are sitting in a private subnet inside AWS. How can you make TravisCI use Ansible to talk to these instances? How do you find out TravisCI’s IP address, given that TravisCI launches your build in a new container each time?

The answer lies in Ansible 2.0’s new SSH Jump Host setting. The following lines should be set as variables for the group or host vars. I set it in group_vars/all because that fits my use case currently:

ansible_ssh_common_args: '-o StrictHostKeyChecking=no -o ProxyCommand="ssh -i <private-key-for-bastion-host.pem> -W %h:%p -q ubuntu@X.X.X.X"'
ansible_ssh_private_key_file: '<private-key-for-private-subnet-instances.pem>'

The first variable is appended to SSH commands automatically by Ansible. The problem with Ansible’s documentation is that it doesn’t mention the need to specify the key file for the bastion host, and I spent hours with errors such as these:

debug1: key_load_public: No such file or directory
debug1: identity file /<private-key-file.pub-cert> type -1

It is probably immediately apparent to someone that works with SSH / Ansible day-in and day-out, though.

Next, you should encrypt these private keys with Travis encrypt files command and paste the output of the command into your .travis.yml file, like so:

before_install:
- openssl aes-256-cbc -K $encrypted_23423423_key -iv $encrypted_23423423_iv -in <private-key>.enc -out <private-key>.pem -d

which dynamically decrypts the file during a build into the container’s current directory (which is the directory where it clones your Git repo, for example). If you want to encrypt multiple files, you should encrypt an archive of the files like so: https://docs.travis-ci.com/user/encrypting-files/#Encrypting-multiple-files

Next, let’s talk about securing the security group for the bastion host. Now, you don’t want to open SSH up for the world, do you? But given that TravisCI launches a new container with a different IP each time, how do you open the security group to this container?

The answer is dynamic modification of the security group. This is how I did it in .travis.yml:

- PUBLIC_IP=`wget http://ipecho.net/plain -O - -q ; echo`
- "echo travis_ip: $PUBLIC_IP >> group_vars/all"


script:
- ansible-playbook 01_create.yml

This effectively puts a variable called “travis_ip” into the group_vars/all file that is then picked up by Ansible when it runs the 01_create.yml playbook.

- name: create/maintaing EC2 security group for Bastion host
    local_action:
      module: ec2_group
      name: "{{ bastion_sg }}"
      description: Security Group for Bastion Server
      region: "{{ region }}"
      vpc_id: "{{ vpc_id }}"
      rules:
        - proto: tcp
           from_port: 22
           to_port: 22
           cidr_ip: "{{ travis_ip }}/32"

That’s it! You’re now all set to use Travis CI and Ansible.

Posted in Linux, Tech. | Leave a comment

Defrost Timer – A Look Inside

If the defrost timer on your fridge is a mechanical timer (works like a wall clock, and ticks annoyingly), then sometime or the other you’ll have this thing fail on you. Ours did, but I wanted to be sure it couldn’t be saved, so I decided to pry it open. It isn’t easy to open the timer up. You’ll inadvertently break a tab or two (I broke one), and you’ll have to be careful opening it up, because as soon as you pop it open all the parts fly into the air. One, you’ll have to search all over the room for parts. Two, because you’ve no idea what the parts are, you’ll never know if you should stop searching for more parts. Third, when you do gather all parts and try to put it back in, you’ll have no idea which part goes where.

I scourged the Internet for a close-up picture of any defrost timer to help me put all the gears and parts back in, but I found nothing.

So, to help some people who might be in a similar situation, I post these pictures of my defrost timer and I hope it helps you put things back in the way they were. When I put all the parts back in, my timer started ticking again. I’ve no idea what fixed it, but the ritual of opening and putting everything back in seems to have worked. Click on the pictures for a full view.

 

IMG_2696IMG_2697

Posted in Tech. | Tagged , , , , , , , , , , , , , , | 1 Comment