[Ruby] [AWS SDK] Script for EC2 automatic construction

5 minute read

Target

Perform EC2 automatic construction using AWS SDK (AWS SDK for Ruby).

Introduction

After collecting the basic knowledge of AWS SDK, let’s try the actual operation with EC2 automatic construction using AWS SDK for Ruby.

AWS SDK

It is a type of API provided by AWS, and is used by importing it as a library into various programming languages supported by AWS. The following languages are currently supported, allowing AWS resources to be manipulated from various programs.

・C++ ・Go ・Java ・JavaScript .NET ・Node.js ・PHP ・Python

  • Ruby (Use this for this article) **

Authentication when using AWS CLI and SDK

Authentication information is required to use AWS CLI (used on OS command line, shell script, PowerShell) and AWS SDK (used on various programming languages). There are the following three methods for setting the authentication information, and the reference priority is different.

Item number Priority Setting location of authentication information
1 High OS environment variables
2 Medium Authentication information file
3 Low Instance Profile (IAM Role Authentication)

① OS environment variables You can use the environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables to set the authentication information. It has the highest priority among the authentication setting methods. For example, set as follows.


# For LINUX
export AWS_ACCESS_KEY_ID=your_access_key_id
export AWS_SECRET_ACCESS_KEY=your_secret_access_key

# For Windows
set AWS_ACCESS_KEY_ID=your_access_key_id
set AWS_SECRET_ACCESS_KEY=your_secret_access_key

② Authentication information file The file “credentials” in the “aws” directory in the OS user’s home directory is the credential file. Populate the aws_access_key_id and aws_secret_access_key in that file with your access key and secret access key.


# Authentication information file
~/.aws/credentials

[default]
aws_access_key_id = your_access_key_id
aws_secret_access_key = your_secret_access_key

③ Instance profile Instance profile is the execution environment used for authentication using IAM role. It is automatically created when creating an IAM role. It is a container for IAM rolls, and it seems to play the role of a connector required when attaching it to EC2. **This authentication method using IAM role is the best practice when using AWS SDK and AWS CLI, and is recommended because it reduces the risk of authentication information leakage compared to the above two methods using access key and secret access key. I am. ** By the way, as the authentication method has the lowest priority, you need to pay attention to the environment variables and the information in the authentication information file.

For details of the instance profile, the following site was helpful. Do you know the instance profile that passes the IAM Role information to EC2?

Workflow

| Item number | Title | |:—-:|:————-| | 1 | Setup of AWS SDK for Ruby | | 2 | Setup of script for EC2 automatic construction | | 3 | Operation verification |

procedure

1. Setting up AWS SDK for Ruby

** ① Install AWS SDK for Ruby ** It takes a lot of time, so be careful…


gem install aws-sdk

** ② Issue access key and secret access key ** If you have not issued an access key and secret access key, you need to create a new one. Refer to the procedure below [[AWS CLI] Enable AWS CLI on Red Hat Enterprise Linux 8 (3. Issue access key ID and secret access key)](https://qiita.com/aWdfcfG2jLr73pe/items/688d183ae6e1d678ea84#3-%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%82%AD%E3%83%BCid%E3%81%A8%E3%82%B7%E3%83%BC%E3%82%AF%E3%83%AC%E3%83%83%E3%83%88%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%(B9%E3%82%AD%E3%83%BC%E3%81%AE%E7%99%BA%E8%A1%8C)

** ③ Edit authentication information file ** This time, save the AWS SDK authentication information by setting it in the authentication information file. Enter the access key and secret access key in the aws_access_key_id and aws_secret_access_key in the authentication information file ~/.aws/credentials.


# Edit authentication information file
vi ~/.aws/credentials

[default]
aws_access_key_id = your_access_key_id
aws_secret_access_key = your_secret_access_key

2. EC2 script setup for automatic construction

** ① Deploy EC2 automatic construction script to the environment where AWS SDK is set up ** Various environment-dependent variables in script (<ami_id>, <keypair_name>, <security_group_id>, <instance_type>, <az_name>, <subnet_id>, <userdata_pass> ) Rewrites according to the environment.

Also, write the user data processing you want to set in EC2 in the file specified in <userdata_pass>.


File name: ec2_create.rb

# ************************************************* *********************************
# Function overview: Automatic construction of EC2
# Script usage: ruby <script path> <instance name>
# ************************************************* *********************************

unless ARGV.size() == 1
  puts "The number of arguments is incorrect."
  exit
end

require'aws-sdk'
require'base64'

# EC2 component definition (Edit the following variables according to the environment)
image_id ='<ami_id>' # AMIID
key_name ='<keypair_name>' # key pair name
security_group_ids ='<security_group_id>' # security group ID
instance_type ='<instance_type>' # instance type
availability_zone ='<az_name>' # Availability AZ
subnet_id ='<subnet_id>' # used subnet ID
user_data ='<userdata_pass>' # user data file path

# User data setting
if File.exist?(user_data)
  file = File.open(user_data)
  script = file.read
  file.close
else
  script =''
end
encoded_script = Base64.encode64(script)

# Create instance for EC2 resource operation
ec2 = Aws::EC2::Resource.new

# Create EC2
instance = ec2.create_instances({
  image_id: image_id,
  min_count: 1,
  max_count: 1,
  key_name: key_name,
  security_group_ids: [security_group_ids],
  user_data: encoded_script,
  instance_type: instance_type,
  placement: {
    availability_zone: availability_zone
  },
  subnet_id: subnet_id
})

# Wait until instance is available
ec2.client.wait_until(:instance_running, {instance_ids: [instance[0].id]})

# Assign instance name (Name tag)
instance_name = ARGV[0]
instance.batch_create_tags({ tags: [{ key:'Name', value: instance_name }]})

puts "#{instance_name} (#{instance[0].id}) has been created!"

3. Operation verification

** ** Create EC2 with the following parameters.


# EC2 component definition (Edit the following variables according to the environment)
image_id ='ami-067152a7c26866dcb' # AMIID
key_name ='mykeypair' # key pair name
security_group_ids ='sg-64a59718' # security group ID
instance_type ='t2.medium' # instance type
availability_zone ='ap-northeast-1a' # Usage AZsubnet_id ='subnet-41d23b09' # Subnet ID used
user_data ='/tmp/userdata' # User data file path

Also, the user data scheduled to be set in EC2 is as follows.


$ cat /tmp/userdata
#!/bin/bash
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd

** ① Script execution ** Execute the script by specifying the instance name as the first argument.


$ ruby ec2_create.rb test_server
test_server (i-0a4fd9cfe1613a8d6) has been created!

** ② Result confirmation ** The instance name, instance type, subnet ID, key pair name, AZ name, and AMIID are set according to the settings in the script. tempsnip.png

The assigned security group is also OK tempsnip.png

The user data was also appropriate. image.png

Check the OS login and check if the user data is running normally.


# httpd is started by executing user data
$ systemctl status httpd
● httpd.service-The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
   Active: active (running) since Sat 2020-07-11 03:03:01 UTC; 12min ago
     Docs: man:httpd.service(8)
 Main PID: 21821 (httpd)
   Status: "Total requests: 0; Idle/Busy workers 100/0; Requests/sec: 0; Bytes served/sec: 0 B/sec"
   CGroup: /system.slice/httpd.service
           tq21821 /usr/sbin/httpd -DFOREGROUND
           tq21831 /usr/sbin/httpd -DFOREGROUND
           tq21832 /usr/sbin/httpd -DFOREGROUND
           tq21833 /usr/sbin/httpd -DFOREGROUND
           tq21834 /usr/sbin/httpd -DFOREGROUND
           mq21835 /usr/sbin/httpd -DFOREGROUND

Jul 11 03:03:01 ip-172-31-40-241.ap-northeast-1.compute.internal systemd[1]: Starting The Apache HTTP Server...
Jul 11 03:03:01 ip-172-31-40-241.ap-northeast-1.compute.internal systemd[1]: Started The Apache HTTP Server.

# Is also enabled
$ systemctl is-enabled httpd
enabled

All are created according to the set values, so it is OK!

Reference site

You can check the implementation examples using AWS SDK For Ruby in various services. AWS SDK for Ruby Code Example