I could not find a way to specify the specific IP address my EC2 instance should use in a subnet. Is there perhaps a better way of doing this? The following snippet works perfectly and allocates an EC2 instance an IP address of 10.1.2.254, I'm just curious if anyone has a more elegant way.
"Subnet" is a parameter in format "10.1.2.0/24"
EC2Instance:
Properties
PrivateIpAddress: !Join
- "."
- - !Select [0, !Split [".", !Ref Subnet]]
- !Select [1, !Split [".", !Ref Subnet]]
- !Select [2, !Split [".", !Ref Subnet]]
- "254"
Related
Im trying to list the AWS S3 Buckets but in doing so I'm getting the following LocalStack error message:
Failed to open TCP connection to docs-localstack:4566 (getaddrinfo: Temporary failure in name resolution) (Seahorse::Client::NetworkingError)
Here's is the code I have for creating a bucket, which seems to be working fine:-
awsbucket.rb file:
require 'aws-sdk-s3'
class AwsS3
def aws_connect
#s3 = Aws::S3::Client.new(
access_key_id: 'test123',
secret_access_key: 'test456',
region: 'us-east-1',
endpoint: 'http://docs-localstack:4566'
)
end
def list_buckets
response = #s3.list_buckets
if response.buckets.count.zero?
puts 'No buckets'
else
response.buckets.each do |bucket|
puts "#{bucket.name}"
end
end
end
def create_bucket(name)
response = #s3.create_bucket(bucket: name)
if response.location == '/' + name
return true
else
return false
end
rescue StandardError => e
puts "Error creating bucket: #{e.message}"
return false
end
end#
I have an .rb file for the test step -
Given('I connect to AWS') do
#client= AwsS3.new
#client.aws_connect
end
Then('I create {string} bucket') do |name|
#client.create_bucket(name)
end
Then('the list of buckets is shown') do
#client.list_buckets
end
This is the code for the docker yml file -
version: "3.3"
services:
localstack:
container_name: "${LOCALSTACK_DOCKER_NAME-localstack_main}"
image: localstack/localstack
network_mode: bridge
ports:
- "127.0.0.1:53:53" # only required for Pro (DNS)
- "127.0.0.1:53:53/udp" # only required for Pro (DNS)
- "127.0.0.1:443:443" # only required for Pro (LocalStack HTTPS Edge Proxy)
- "127.0.0.1:4510-4559:4510-4559" # external service port range
- "127.0.0.1:4566:4566" # LocalStack Edge Proxy
environment:
- DEBUG=${DEBUG-}
- DATA_DIR=${DATA_DIR-}
- LAMBDA_EXECUTOR=${LAMBDA_EXECUTOR-}
- LOCALSTACK_API_KEY=${LOCALSTACK_API_KEY-}
- HOST_TMP_FOLDER=${TMPDIR:-/tmp/}localstack
- DOCKER_HOST=unix:///var/run/docker.sock
volumes:
- "${TMPDIR:-/tmp}/localstack:/tmp/localstack"
- "/var/run/docker.sock:/var/run/docker.sock"
So for creating a bucket it works fine, but when listing the buckets created I seem to get a TCP Connection issue.
This is the first time I'm using AWS S3 Buckets so apologies if the details are lacking, but not sure which area I'm messing up on.
Any ideas why I'm getting that error?
I'm new to working with YAML. I'd like to know if it is possible to 'nest' YAML anchors as I have attempted in the example below. Unfortunately, I get an error YAMLException: unidentified alias "foo" at line 13, column 19: category: *foo ^
namespace: &namespace-definition
name: "Hellow world"
value: "hw"
categories: &categories
- &foo:
name: "foo"
namespace: *namespace-definition
- &bar:
name: "bar"
namespace: *namespace-definition
keys:
- name: "element1"
category: *foo
- name: "element2"
category: *bar
Is there another way to achieve what I am trying to do, or is it impossible?
The anchors in your example are named foo: and bar:, not foo and bar.
Remove the colon after them and it will work:
namespace: &namespace-definition
name: "Hellow world"
value: "hw"
categories: &categories
- &foo
name: "foo"
namespace: *namespace-definition
- &bar
name: "bar"
namespace: *namespace-definition
keys:
- name: "element1"
category: *foo
- name: "element2"
category: *bar
I read some quick tutorials on Yaml or yml file format. I made a yaml document to represent my data. I saw some ruby tutorials which tell you how to extract yaml with ruby. Unfortunately, they just print the whole data or just keys and values. It does not meet my needs. Please help.
yaml file -
dev:
game1:
server1:
url: 'dev-game1-a-srv01.gamer.com'
log-path: '/srv/logs'
server2:
url: 'dev-game1-a-srv02.gamer.com'
log-path: '/srv/logs'
game2:
server1:
url: 'dev-game2-a-srv01.gamer.com'
log-path: '/srv/logs'
server2:
url: 'dev-game2-b-srv02.gamer.com'
log-path: '/srv/logs'
server3:
url: 'dev-game2-b-srv01.gamer.com'
log-path: '/srv/logs'
prod:
etc....
How do I select dev, game2, server 3, url using ruby code ?
Using the code below, I get an exception -
require 'yaml'
def server_info
path = 'C:\Code\demo-srv.yml'
yml = YAML::load(File.open(path))
game2 = yml['dev']['game2']
game2.each{|server|
if server['server3']
puts server['server3']['url']
end
}
end
server_info
error -
server.rb:8:in `[]': can't convert String into Integer (TypeError)
from server.rb:8:in `server_info'
from server.rb:7:in `each'
from server.rb:7:in `server_info'
from server.rb:14
Did you define the yaml-data or are you only the consumer of an existing yaml-file?
If you defined it, I would replace the array of servers with a Hash (see the missing - before the server names):
dev:
game1:
server1:
url: 'dev-game1-a-srv01.gamer.com'
log-path: '/srv/logs'
server2:
url: 'dev-game1-a-srv02.gamer.com'
log-path: '/srv/logs'
game2:
server1:
url: 'dev-game2-a-srv01.gamer.com'
log-path: '/srv/logs'
server2:
url: 'dev-game2-b-srv02.gamer.com'
log-path: '/srv/logs'
server3:
url: 'dev-game2-b-srv01.gamer.com'
log-path: '/srv/logs'
Then you can try yml['dev']['game2']['server3']['url'].
Attention: There are no checks for missing/wrong data. if the entry for game2 would miss, this code will raise an exception.
So, maybe you shoudl do something like
if yml['dev'] and yml['dev'].kind_of?(Hash)
if yml['dev']['game2'] and ....
...
else
puts "No dev-branch defined"
end
Else you can try something like:
def server_info
yml = YAML::load(DATA)
yml['dev']['game2'].each{|server|
if server['server3']
p server['server3']['url']
end
}
end
Attention (for both solutions):
There are no checks for missing/wrong data. The existence of server['server3'] is checked here. For real code, you should also check the existence of the dev and game2 data.
Answer continuation after edit:
The error convert String into Integer is often thrown if you have an array but expect a hash and you try to access an array element with a string.
You can try the following code. There are two changes:
line 8 contains the output of server - you will see it is an array, no hash.
line 9+10: The array is checked and used by its two elements (via #first and #last)
require 'yaml'
def server_info
path = 'C:\Code\demo-srv.yml'
#~ yml = YAML::load(File.open(path))
yml = YAML::load(DATA)
game2 = yml['dev']['game2']
game2.each{|server|
p server #-> you get an array
if server.first == 'server3'
puts server.last['url']
end
}
end
server_info
The file -
dev:
game1:
server1:
url: 'dev-game1-a-srv01.gamer.com'
log-path: '/srv/logs'
server2:
url: 'dev-game1-a-srv02.gamer.com'
log-path: '/srv/logs'
game2:
server1:
url: 'dev-game2-a-srv01.gamer.com'
log-path: '/srv/logs'
server2:
url: 'dev-game2-b-srv02.gamer.com'
log-path: '/srv/logs'
server3:
url: 'dev-game2-b-srv01.gamer.com'
log-path: '/srv/logs'
I don't know why but yml['dev']['game2']=>
[{"server1"=>{"url"=>"dev-game2-a-srv01.gamer.com", "log-path"=>"/srv/logs"}},
{"server2"=>{"url"=>"dev-game2-b-srv02.gamer.com", "log-path"=>"/srv/logs"}},
{"server3"=>{"url"=>"dev-game2-b-srv01.gamer.com", "log-path"=>"/srv/logs"}}]
So you have to use find on this Array to have the key.
require 'yaml'
# require 'pry'
def server3_url
yml = YAML::load(File.read('yaml.yml'))
# binding.pry
begin
yml['dev']['game2'].find{|x| x['server3']}['server3']['url']
rescue
end
end
puts server3_url
server3_url will return nil if it doesn't find a key
Changing your code the following should fix the issue.
# ...
game2.each{ |server, data|
if server == 'server3'
puts data['url']
end
}
# ...
You are encountering the type error because the yielded value server is an array, not a hash. This is happening because you are calling each on the game2 variable, which is a hash, and only yielding to a single variable.
Examples
hash = { one: 1, two: 2, three: 3 }
Yielding to a single variable
When Hash#each is called with only one variable, the current key and value are assigned to that variable as an array in the order [key, value]
hash.each do |number|
puts number.inspect
end
# Prints
# [:one, 1]
# [:two, 2]
# [:three, 3]
Yielding to multiple variables
When Hash#each is called with two variables, the current key will be assigned to the first variable, and the current value will be assigned to the second.
hash.each do |key, value|
puts "Key: #{key}; Value: #{value}"
end
# Prints:
# Key: one; Value: 1
# Key: two; Value: 2
# Key: three; Value: 3
I am new with ruby.
I want to use simple yml settings file
this is my code
LaunchEC2s.rb
#!/usr/bin/ruby
require 'rubygems'
require 'aws-sdk'
require 'yaml'
AWS_CON = Yaml.load_file("AWSsettings.yml") unless defined? AWS_CON
def launchEC2(count)
key_pair = ec2.key_pairs[AWS_CON['key_pair']]
image_id
ec2 = AWS::EC2.new.regions[AWS_CON['region']]
instances = ec2.instances.create(
:image_id => AWS_CON['image_id'],
:instance_type => AWS_CON['instance_type'],
:count => count,
:security_groups => AWS_CON['security_groups'],
:key_pair => key_pair)
end
launchEC2(2)
my yml file looks like
# AWS yml file
key_pair: xxx
region: us-west-2
image_id: ami-b5a7ea85
instance_type: t2.micro
security_groups: xxx
when I run it I get
./LaunchEC2s.rb:6:in `<main>': uninitialized constant Yaml (NameError)
I'm sorry is this question is dumb but I cant figure it up
What am I doing wrong ?
I'm pretty sure you want to do YAML.load_file("AWSsettings.yml") instead of Yaml.load_file("AWSsettings.yml") (the difference being all caps).
Try this:
Create a yml file in config/
say config/ec2_keys.yml
development:
region: us-west-2
image_id: ami-b5a7ea85
instance_type: t2.micro
security_groups: xxx
Now you want to initialize them once for all. For that create this one line file:
config/initializers/load_ec2.rb
EC2 = YAML.load(ERB.new(File.read("#{Rails.root.to_s}/config/ec2_keys.yml")).result)[Rails.env]
Now use the constants wherever required as:
EC2["region"]
#=> "us-west-2"
EC2["image_id"]
#=> "ami-b5a7ea85"
I applied YAML.load_file to my example file:
---
languages:
- name: "English"
iso_639: "en"
native_name: "English"
region:
- ''
- UK
- US
- name: "Klingon"
iso_639: "tlh"
native_name: "tlhIngan Hol"
region:
- notearth
I want to iterate though these languages and the region arrays. This doesn't work:
records.each do |record|
record.region.each do |region|
self.create!
end
end
record.region gives me an unknown method error for region. How can I iterate though the languages and and their regions? Or, how can I access the region array?
There are two errors in your code:
The object you get after loading the YAML file is not an array, it's a hash, say the file is called foo.yml:
YAML.load_file('foo.yml')
# => {"languages"=>[{"name"=>"English", "iso_639"=>"en", ...
Thus you have to modify your code like the following to make it work:
records['languages'].each do |record|
# ...
region is not a method of the hash record, it is a key, you have to access the related value using record['region'].
The correct code you have to use is:
records['languages'].each do |record|
record['region'].each do |region|
# My guess is you are going to use `region` inside this block
self.create!
end
end
Yaml is loaded into a hash, hence it will be in form:
languages: [
{
name: "English"
iso_639: "en"
native_name: "English"
region: ['', 'UK', 'US']
}
{
name: "Klingon"
iso_639: "tlh"
native_name: "tlhIngan Hol"
region: ['notearth']
}]
So you need to iterate like:
results = YAML.load_file(file)
results['languages'].flat_map{|l| l['region']}.each do |region|
self.create!
end
CONFIG = YAML.load_file("file.yml")
puts CONFIG # {"languages"=>[{"name"=>"English", "iso_639"=>"en", "native_name"=>"English", "region"=>["", "UK", "US"]}, {"name"=>"Klingon", "iso_639"=>"tlh", "native_name"=>"tlhIngan Hol", "region"=>["notearth"]}]}
CONFIG['languages'].map{|l| l['region']}