pandazx's blog

データ分析など雑多な技術ブログ

AWS SDKサンプルプログラム(Python2)

Get S3 bucket list

# coding:utf-8

from boto3.session import Session
import os

session = Session(
    aws_access_key_id = os.environ['access_key'],
    aws_secret_access_key = os.environ['secret_access_key'],
    region_name = 'ap-northeast-1',
)

s3 = session.resource('s3')
for bucket in s3.buckets.all():
    print(bucket.name)

Get kinesis shard IDs

# coding:utf-8

import boto3
import os

# Get stream info
client = boto3.client('kinesis')
shard = client.describe_stream(StreamName = os.environ['kinesis_stream_name'])
for x in shard['StreamDescription']['Shards']:
    print(x['ShardId'])

VPC内のLambdaから外部サービスにアクセスする方法

VPC内のEC2やRedshiftなどにアクセスするためにLambdaをVPC内に作成して実行すると、 今度は逆に外部のインターネットやS3, Kinesisなどにアクセス出来なくなる。

その場合の対応方法はAWSの公式ドキュメントに書いてある。

Configuring a Lambda Function to Access Resources in an Amazon VPC - AWS Lambda

日本語情報としては以下がある。

VPC Lambdaからs3へアクセスする - Qiita

以下では上記サイトの補足を述べる。

設定方法について

いずれのVPC内からもアクセス可能に出来るわけではなく、private subnet内にLambdaを設置することが条件である。

public subnet にNATサーバを構築し、private subnet はNATサーバ経由でインターネットにアクセスする構成とする。 private subnetが参照するルートテーブルにおいて、0.0.0.0/0 をpublic subnetのNATサーバにルーティングするよう設定すればよい。 設定イメージは下記ページの図が参考になる。

NAT ゲートウェイ - Amazon Virtual Private Cloud

NATサーバの構築については以下を参照

EC2にNATサーバ構築 - pandazx's blog

ネットワーク構成の補足

private subnet と public subnet についてだが、インターネットに直接つながっているsubnetをpublic subnet、 つながっていないsubnetをprivate subnet と呼ぶ。subnetのルートテーブルで0.0.0.0/0をインターネット・ゲートウェイにルーティングしているとpublic subnetとなる。

NATサーバのセキュリティグループ

当然、S3やKienesisなどへのアクセスをNATで受けるため、インバウンドの該当ポートは開けておく必要がある。

LambdaのIAM Role

LambdaからKinesisにアクセスしたい場合は、それ用のIAM Roleを作成しておく必要がある。 RoleにはAWSLambdaKinesisExecutionRoleとAmazonEC2FullAccessが必要。

参考:ステップ 2.2: 実行ロール (IAM ロール) を作成する - AWS Lambda

EC2への権限は本当はもっと細かく絞れるらしいが試していない。詳細は以下参照

https://forums.aws.amazon.com/message.jspa?messageID=756727

EC2にNATサーバ構築

本文

AmazonからはNAT Gatewayというマネージドサービスが提供されているが、お金が少しかかる。 そこで自前で用意する方法を説明する。

OS:Amazon Linux

NATサーバの設定

NATサーバを構築するEC2インスタンスはパブリックIPがあり、外につながっているとする。 以下を設定。IPアドレスに関する部分は適宜、読み替えて設定すること。

# NATのログを出力する場合。ログは /var/log/messages に出力される
sudo iptables -t nat -A POSTROUTING -j LOG

# 設定
sudo iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j MASQUERADE

# 設定の確認
sudo iptables -t nat -nL

# 設定の保存(保存しないと再起動で設定が初期化される)
sudo service iptables save

# forwardingの設定
vi /etc/sysctl.conf
#—————————————————-
#net.ipv4.ip_forward = 0
#↓
#net.ipv4.ip_forward = 1
#—————————————————-
# 設定の適用
sysctl -p

ブラウザでAWSのマネジメントコンソールにログインし、該当EC2インスタンスを右クリック→ネットワーキング→送信元/送信先の変更チェックを無効にする。

クライアントの設定

クライアントとなるEC2はパブリックIPがなく、プライベートIPのみとする。以下を設定。

# デフォルトゲートウェイをNATサーバに設定
sudo route del default gw 192.168.0.1
sudo route add default gw 192.168.0.8

sudo vim /etc/sysconfig/network
GATEWAY=192.168.0.8を追記設定

sudo service network restart
※少し時間がかかる

# 接続テスト
wget www.google.co.jp
index.htmlが作成されれば成功

ちなみに、各インスタンスの基本的なポートの開閉などはAWSのセキュリティグループでやればよい。

参考サイト(もっと詳しい説明があります):習うより慣れろ! iptablesテンプレート集(2):natテーブルを利用したLinuxルータの作成 (2/6) - @IT

以下の方法もあるらしい。

AWSでNAT構成を自前で用意する - のんびりSEの議事録

AMIイメージから作成したEC2にSSHで接続できない

それまでパスワード認証でsshでログインしていたEC2があったとする。

そのAMIイメージを作成して、別途、EC2を作成するが、sshでログインできず、「Permission Denied」となる。EC2作成時にはキーペアをなしに設定している。

解決方法

キーペアをありにして作成し、秘密鍵を使って、ec2-userでログイン。 /etc/ssh/sshd_config の PasswordAuthentication を yes にして、sudo service sshd restart すればよい。

そもそも、パスワード認証を使わない方がいいという話もあるが、それはまた別の話。

AWS SDK for Ruby V2でS3にアクセスするサンプルプログラム

AWS SDKをインストー

gem install aws-sdk

サンプルプログラム

# coding: utf-8
#
# AWS SDKを用いて、S3にアクセスするサンプルプログラム
#

require 'aws-sdk'

# Config
AWS_REGION = "ap-northeast-1"
AWS_ACCESS_KEY = "xxx"
AWS_SECRET_ACCESS_KEY = "xxx"
S3_BUECKT_NAME = "xxx"

client = Aws::S3::Client.new(
    :region => AWS_REGION,
    :access_key_id => AWS_ACCESS_KEY,
    :secret_access_key => AWS_SECRET_ACCESS_KEY,
    )

puts "Show S3's bucket list"
puts client.list_buckets.buckets.map(&:name)
puts ""

puts "Show object list"
client.list_objects(:bucket => S3_BUECKT_NAME).contents.each do |object|
  puts object.key
end
puts ""

puts "Upload object"
ret = client.put_object(
    :bucket => S3_BUECKT_NAME,
    :key    => '新しいテキスト ドキュメント.txt',
    :body   => File.open("新しいテキスト ドキュメント.txt")
    )
puts "Done"
puts ""

puts "Read object"
puts client.get_object(:bucket => S3_BUECKT_NAME, :key => '新しいテキスト ドキュメント.txt').body.read

参考サイト:AWS SDK for Ruby V2でS3をいろいろ使う - Qiita

OpenStreetMapサーバの構築 Ubuntu 14.04

OpenStreetMapサーバはKai Krueger氏がUbuntu14.04向けにパッケージングしてくれているので、 これを利用すると構築が簡単。以下の方法が参考になる。

OpenStreetMapサーバを自作する(Install OpenStreetMap on AWS EC2/Ubuntu14.04) | Developers.IO

以下のサイトにはUbuntu16.04 でも構築可能な手順が書いているようだが、未確認。

Installing an OpenStreetMap Tile Server on Ubuntu | OpenStreetMap Carto Tutorials

解説記事によってはインストール後に、sudo ldconfig コマンドが抜けていることがあるので、注意すること。 例えば、下記サイトには記載がない。下記サイトを参考に Ubuntu 16.04で構築を試みたが、/var/lib/mod_tile に何故か地図タイルが作成されず、断念した。

Ubuntu 16.04 で OpenStreetMap タイルサーバを構築 – 2 – – keizoh.com

Tips

すべての地図タイルレンダリング実行

render_list -a