[AWS SDK] EC2 automatic construction script

Target

EC2 automatic construction is performed using AWS SDK (AWS SDK for Ruby).

Introduction

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

AWS SDK A type of API provided by AWS that is imported and used as a library in various programming languages supported by AWS. Currently, the following languages are supported, enabling AWS resource operations from various programs.

・ C ++ ・ 5 ・ Java ・ JavaScript ・.NET ・ Because. js ・ PHP ・ Python ・ ** Ruby (this is used in this article) **

Authentication when using AWS CLI and SDK

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

Item number priority Authentication information setting location
1 High OS environment variables
2 During ~ Credential file
3 Low Instance profile (IAM role authentication)

① OS environment variables Authentication information can be set using the environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY. 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" that exists in the "aws" directory in the OS user's home directory is the credentials file. Enter the access key and secret access key for aws_access_key_id and aws_secret_access_key in that file.


#Credential file
~/.aws/credentials

[default]
aws_access_key_id = your_access_key_id
aws_secret_access_key = your_secret_access_key

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

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

Workflow

Item number title
1 AWS SDK for Ruby setup
2 Set up script for EC2 automatic construction
3 Operation verification

procedure

1. AWS SDK for Ruby setup

** ① AWS SDK for Ruby installation ** Note that it will take a long time ...


gem install aws-sdk

** ② Issuance of access key and secret access key ** If the access key and secret access key have not been issued, you need to create a new one. Refer to the following for the procedure [[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 credentials in the credentials file. Enter the access key and secret access key in ʻaws_access_key_id and ʻaws_secret_access_key in the credentials file ~ / .aws / credentials.


#Credential file editing
vi ~/.aws/credentials

[default]
aws_access_key_id = your_access_key_id
aws_secret_access_key = your_secret_access_key

2. Setup of script for EC2 automatic construction

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

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


File name: ec2_create.rb

# **********************************************************************************
#Functional overview: EC2 automatic construction
#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>'               #Use AZ
subnet_id = '<subnet_id>'                     #Subnet ID used
user_data = '<userdata_pass>'                 #User data file path

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

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

#EC2 creation implementation
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 for an instance to become available
ec2.client.wait_until(:instance_running, {instance_ids: [instance[0].id]})

#Give an 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'     #Use AZ
subnet_id = 'subnet-41d23b09'             #Subnet ID used
user_data = '/tmp/userdata'               #User data file path

In addition, the user data to be set in EC2 has the following contents


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

** ① Script execution ** Execute the script with the instance name specified 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 AMI ID are set according to the settings in the script. tempsnip.png

The assigned security group is also OK tempsnip.png

The content of the user data was also appropriate. image.png

For the time being, check the OS login and check if the user data is executed 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.

#It is also enabled
$ systemctl is-enabled httpd
enabled

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

Reference site

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

Recommended Posts

[AWS SDK] EC2 automatic construction script
[Rails] AWS EC2 instance environment construction
I tried automatic deployment with CircleCI + Capistrano + AWS (EC2) + Rails
Install docker on AWS EC2
How to publish an application using AWS (3) EC2 instance environment construction