AWSで時刻同期サービスがリリースされました

これまでAWS上では時刻同期について、外部のサーバを利用する必要がありましたが、
AWS内で利用できるサービスがリリースされました。
これで外部へアクセスする必要がなくなりました。またうるう秒も自動で調整してくれるため是非利用するべきだと思います

設定方法(Amazon Linux

以下のいずれかの方法で設定

方法1

NTPのアクセス先を以下に変更する

server 169.254.169.123 prefer iburst
方法2

ntpを削除してchronyに入れ替える

sudo yum erase ntp*
sudo yum -y install chrony
sudo service chronyd start

これからAWSを利用する場合の時刻同期は全てこれで対応していいと思います。
Windowsでも設定可能なので、詳細は以下を参照してください。

S3マウントツールのObjectiveFSを試してみた

S3のマウントにみなさん何を使っていますか?
s3fs?goofys?使い勝手はいかがでしょう?
今回は、商用ですがObjectiveFS(https://objectivefs.com/)というS3のマウントツールの紹介をしたいと思います。

環境

OS:AmazonLinux

手順

ライセンス取得

14日間のトライアル版がありますので、以下のページの「Try It Free」からサインアップ(クレジットカード不要)してライセンスを取得してください。サインアップ後にメールが届きますのでそれに従ってログインしてください。
https://objectivefs.com/price?l=pricing
f:id:cloudfish:20170626144019p:plain

rpmダウンロード

ログイン後に以下のページからrpmをダウンロードします。
https://objectivefs.com/user/downloads

f:id:cloudfish:20170626144012p:plain

インストー

ダウンロードしたrpmのバージョンにあわせてください

# yum install objectivefs-5.1-1.x86_64.rpm

初期設定

IAM Userを作成しアクセスキー、シークレットキーを準備しておいてください。
IAM Userの権限にはS3FullAccessを付与しておいてください。

#sudo mount.objectivefs config
 Enter ObjectiveFS license: ←ライセンスを入力
 Enter Access Key Id: ←アクセスキーを入力
 Enter Secret Access Key: ←シークレットキーを入力
 Enter Default Region (optional): ←リージョンを入力

ファイルシステムを作成

以下のコマンドを実行するろS3にバケットが作成されますので注意して実行してください。
「s3-objectivefs」というバケットを作成するものとします

# sudo mount.objectivefs create s3-objectivefs
  Passphrase (for s3://<filesystem>): ←任意のパスワード
  Verify passphrase (for s3://<filesystem>): ←パスワード再入力

マウントする

# sudo mkdir /mnt/s3-objectivefs
# sudo mount.objectivefs s3-objectivefs /mnt/s3-objectivefs
Passphrase (for s3://<filesystem>): ←上記で設定したパスワードを入力

これでエラーが出なければ完了です
lsしてみたりファイルを作るなりして遊んでみてください。
既存バケットをマウントする方法はまたご紹介したいと思います。

AWS SDKでAuthFailure【cloudpack 大阪 BLOG】

発生した障害

boto(python)で定期的にS3にファイルをアップロードしているスクリプトが突然エラーとなり実行できなくなる問題に遭遇しました。
エラーログを確認すると「403 Forbidden」が発生していました。

調査したこと

何らかの原因で使用しているアクセスキーが有効でなくなった可能性をがあると想定しましたが問題なし。
ポリシーも確認しましたが権限は問題なし。
ざっと見たところ原因分からず。

問題の切り分け

同じ権限を持ったユーザーを再作成して試したところ上記と同様のエラーとなる
ここでS3にエラーが発生してないか気になりヘルスチェックを確認しましたがこちらも問題なし
一応、再作成したユーザーが本当に正しい権限が付与されているか確認するためにaws cliを手動で実行したところ下記エラーが発生しました。

An error occurred (AuthFailure) when calling the DescribeInstances operation: AWS was not able to validate the provided access credentials

認証失敗とありますが、あまり見慣れていないエラーが発生していたため即ググったところ、OSの時間がずれていることが原因らしいことが判明。OSの時刻を確認すると確かに20分ほどずれており、ntpで正常に同期できていませんでした。手動で時刻同期して再度aws cliを実行すると正常に実行できました。
その後定期スクリプトを再度実行したところ正常に終了しました。

参考ページ
awscliはOS内の時間が狂ってるとAuthFailureが出る | hacknote
これをやると http://qiita.com/sonots/private/4d5dbec2b12621ef27e9 こうなる · GitHub

上記のページを確認するとOSの時刻がずれているとAPIの認証が通らないようです。
AWSのドキュメントにも以下の記載がありました。

AWS CLI、または AWS SDK を使用してインスタンスからリクエストを行う場合、これらのツールによって
自動的にリクエストに署名されます。
インスタンスの日時が正しく設定されていない場合、署名の日付がリクエストの日付と一致しないことがあり、
その場合は AWS によってリクエストが却下されます。

Linux インスタンスの時刻の設定 - Amazon Elastic Compute Cloud

AWS CLISDKを使用する場合は気をつける必要がありますね。

AutoScalingでEC2のDetach/StandByができない場合の対処法【cloudpack 大阪 BLOG】

はじめに

AutoScalingを設定していて手動で設定を変更していると、たまに台数がずれるなどして最低台数の制限に引っかかりAutoScalingGroupからEC2をDetachやStandByにできない場合があります。スケーリングポリシーに基づいてインスタンスの増減が実施されていればほぼ発生しないと思いますが、メンテナンスやインスタンスの入れ替えなどを手動で実施すると発生する場合があります。今回はこうしたケースの対処法を紹介しようと思います。

Detachできない状態

AutoScalingGroupには3台紐付いていますが、DesiredとMinがそれぞれ2台となっています。
f:id:cloudfish:20170303154435p:plain

1台をDetachしてAutoScalingGroupを2台にしたいのですが、この状態でDetachを実施すると、
Desiredが2から1に変わりMinを下回ることからエラーとなります。
f:id:cloudfish:20170307100751p:plain

対応方法

Desiredを2から3に変更した後にDetachできればいいのですが、普通に変更するとインスタンスが新規に追加されてしまいます。
対応としては以下のように「Suspended Processes」でLaunchを設定します。こうすることでAutoScalignGroupの設定を変更しても新規にインスタンスの追加が実行されません。この状態にしてからDesiredを3に変更します。
f:id:cloudfish:20170307101316p:plain

正しく設定が完了すれば以下のようにAutoScalignGroupのインスタンス数が変わらずDesiredが3になります。
この状態で再度、対象インスタンスをDetachすると問題なく実行できるはずです。
f:id:cloudfish:20170307101420p:plain

Detach完了後です。正常にDetachが完了しました。
f:id:cloudfish:20170303154600p:plain

AutoScalingは便利な機能ですが、手動でインスタンスを制御しようとすると思わぬ動作をしてインスタンスの削除や追加が実行されます。追加はともかく削除は困ることが多いと思いますので手動で何かをする際は事前にしっかりと検証したほうがいいと思います。

起動後のEC2にIAM Roleを付与する【cloudpack 大阪 BLOG】

待望の機能追加があったので実際にやってみました。
これまで起動後のec2インスタンスにはiam-roleが付与できなくて不便な思いをしてきましたがやっと開放されそうです

現時点ではawscliからのみしかできません。
またawscliの更新が必要になりますので気をつけてください。

以下に手順を記載します。ec2にアタッチするroleについては作成されているものとします

①roleアタッチ

aws ec2 associate-iam-instance-profile --instance-id ${InstancdId} --iam-instance-profile Name=${profile_name}

②アタッチ確認

aws ec2 describe-iam-instance-profile-associations

③roleデタッチ

aws ec2 disassociate-iam-instance-profile  --association-id ${associationId} 

※${associationId}については②で確認できます

また、stop中のインスタンスについては、画面のEC2のrole項目は更新されませんでしたが、起動後に正しく表示されました。

rsyslogで中継サーバ経由してログ送信を行う【cloudpack 大阪 BLOG】

以下のような構成でrsyslogを使用してログをログ収集サーバへ集約させる要件がありました。
検証で動作確認を実施してみたので、備忘録としてやり方を残しておきたいと思います。

f:id:cloudfish:20170126190943p:plain,w400,h250

やりたいこと

webサーバの/var/log/messagesをログ中継サーバを経由させてログ収集サーバへ送信する
ユースケースとしてはログ収集サーバが別のVPCや外部DCにあるケースを想定しています。

構成

サーバ IP
webサーバ 172.31.0.1
中継サーバ 172.31.0.2
ログ収集サーバ 172.31.0.3

webサーバの設定

■/etc/rsyslog.config

*.info;mail.none;authpriv.none;cron.none                /var/log/messages
*.info;mail.none;authpriv.none;cron.none                @@172.31.02      ←追加

# 以下コメントを解除(73-78行目)
$WorkDirectory /var/lib/rsyslog # where to place spool files
$ActionQueueFileName fwdRule1 # unique name prefix for spool files
$ActionQueueMaxDiskSpace 1g   # 1gb space limit (use as much as possible)
$ActionQueueSaveOnShutdown on # save messages to disk on shutdown
$ActionQueueType LinkedList   # run asynchronously
$ActionResumeRetryCount -1    # infinite retries if host is down

中継サーバの設定

■/etc/rsyslog.config

# 以下コメントを解除
$ModLoad imtcp
$InputTCPServerRun 514

$AllowedSender TCP, 127.0.0.1, 172.31.0.0/24   ←送信元を指定

*.info;mail.none;authpriv.none;cron.none                /var/log/messages
*.info;mail.none;authpriv.none;cron.none                @@172.31.03       ←追加

#コメントを解除(73-78行目)
$WorkDirectory /var/lib/rsyslog # where to place spool files
$ActionQueueFileName fwdRule1 # unique name prefix for spool files
$ActionQueueMaxDiskSpace 1g   # 1gb space limit (use as much as possible)
$ActionQueueSaveOnShutdown on # save messages to disk on shutdown
$ActionQueueType LinkedList   # run asynchronously
$ActionResumeRetryCount -1    # infinite retries if host is down

ログ収集サーバの設定

■/etc/rsyslog.config

# 以下コメントを解除
$ModLoad imtcp
$InputTCPServerRun 514

$AllowedSender TCP, 127.0.0.1, 172.31.0.0/24   ←送信元を指定

#フォーマット指定
$template message_log,"/var/log/message.d/%fromhost%_%$year%%$month%%$day%.log"   ←追加
*.info;mail.none;authpriv.none;cron.none     -?message_log             ←追加

上記設定後にwebサーバでmessagesにログを出力し、ログ収集サーバに転送されていれば正常に設定されています。

logger logtest

Terraformで[Error reading config for xxxx : Invalid dot index found:]エラー【cloudpack 大阪 BLOG】

最近Terraformを触っていて少し躓いたので備忘録として残しておこうと思います。
現象としては、mapping定義にドットで参照しようとしてエラーが発生しました

variable "vpc_subnet_cidr" {
     default = {
       public-a  = "10.1.10.0/24"
       public-c  = "10.1.20.0/24"
       private-a = "10.1.100.0/24"
       private-c = "10.1.200.0/24"
     }
}

上記のようなmapping定義に対して以下のように変数を参照したとことタイトルのエラーが発生しました。

output "cidr" {
  value = "${var.vpc_subnet_cidr.public-a}"
}


発生したエラーの全文です。

Error loading config: Error loading terraform_test/main.tf: Error reading config for output cidr: Invalid dot index found: 'var.vpc_subnet_cidr.public-a'. Values in maps and lists can be referenced using square bracket indexing, like: 'var.mymap["key"]' or 'var.mylist[1]'. in:

エラーメッセージ内容から下記のように書き直せばいいのは分かるのですが、別案件で稼働実績のあるソースを持ってきたので何故動かないのか気になりました。

output "cidr" {
  value = "${var.vpc_subnet_cidr["public-a"]}"
}

調べてみるとCHANGELOGに記載がありました。
terraform/CHANGELOG.md at master · hashicorp/terraform · GitHub

原因はterraformのバージョン違いによるものでした。別案件で使用していたterraformは0.6系でしたが自分が利用している
terraformは0.7でした。後方互換のない変更がはいったようです。

f:id:cloudfish:20161222025343p:plain

基本的な参照方法を変更するとはなかなか思い切った変更ですね。
0.6系で作ったterraformソースを0.7以降で利用する場合は気をつける必要がありそうです。