ほわいとぼーど

ぷろぐらまのメモ帳

peco+sshのためのEC2DescribeInstancesなツールをGolangで再車輪した

pecoでsshする際に組み合わせるためのEC2をリストアップするコマンドラインGolangで書いた。
前職でもec2-ls-hostsを使って同じことをしていたのだが、
現職で使うには機能が合っていなかったのでGolang手習い的な意味も込めて新たに書いてみた。
こういうのをサクッと書くのにGolang便利。

できたもの

ec2ls-cache

Why 再車輪

現職ではMFAを設定しているので毎回うたなくて済むようにキャッシュを入れたかった。

後は、aws-sdk-goでのcredentials設定周りがpythonほど簡単ではないと思いこんでいて、
実際は書いてみたら自分が望む環境設定は比較的容易に満たせてそうだった。
この辺はそのうち気が向いたら検証してみたいかも。

使い方

  • pecoを入れる
  • ec2ls-cacheをGithubのReleaseからダウンロードしてパスの通る所に配置
  • ローカルにキャッシュを作成更新
    • ec2ls-cache -u --filters "running" --columns "PrivateIpAddress,InstanceId,Tag:Name" --sortcolumn "Tag:Name" とか
    • 詳しいオプションはGithubReadme参照
    • これもalias登録しておくとよい
  • ssh $(ec2ls-cache| peco | cut -f 1) みたいなのをalias登録して使う

頑張ったところ?

filtersとかcolumnsとかは完全にaws-sdk-goに依存していて、
ec2ls-cache内部には定義を一切持っていない。
そのためにcache用のJSON出力をstruct使わない形で書くのに挑戦してみた。

filtersはaws-sdk-goに渡すfilters同様の記述をそのまま渡せる。

columnsはaws-sdk-goのec2.Instancesのfield名をそのまま渡せる。
これのためにreflectを初めて使ってみた。

今回は以前使ったmkideal/cliからurfave/cliに変えてみた。

キャッシュファイル分けれるので条件変えて作れば便利

課題とか

  • テストが無い。
  • validate手抜き
  • tabwriterの調整が難しくてPrivateIpAddressを先頭にしておかないとうまくcutできない

とりあえずIPを調べるという作業をなくしたかったので満足

parameter storeから取得して環境変数にセットする

AWSのパラメータストア (Amazon EC2 Systems Manager Parameter Store) を利用して、
取得した値を環境変数にセットするツールをgolangで書いてみました。

ki38sato/env-awsps

とりあえずlinux_386だけReleaseに置いてDLしてる。

使い方

使い方は、適当なinit.shとかで、

$(env-awsps --region ap-northeast-1 --prefix app.web. --rm-prefix)

とすると環境変数にパラメータストアのKEYを元にした変数名でセットされます。
上記のオプション例は、 app.web. をPrefixに持つKEYだけを選択し、
Prefixを除いた部分を環境変数名として使用するというものです。
オプション付けなければパラメータストアの全アイテムが展開されます。
変数名は大文字に変換します。./_に変換します。

example

(set parameter store)
app.web.user = XX1
app.web.password = YY1
app.db.user = XX2
app.db.password = YY2
$ env-awsps
export APP_WEB_USER=XX1
export APP_WEB_PASSWORD=YY1
export APP_DB_USER=XX2
export APP_DB_PASSWORD=YY2

$ env-awsps --prefix app.web.
export APP_WEB_USER=XX1
export APP_WEB_PASSWORD=YY1

$ env-awsps --prefix app.web. --rm-prefix
export USER=XX1
export PASSWORD=YY1

ツール自体はexport文を出力するだけなので$()で反映します。
os.Setenvとかだと親プロセスに設定できないので一時途方にくれましたが、
awscliのaws ecr get-loginを見てアリだなと気づきました。

経緯とか

元々はKMSを利用してS3においた設定ファイルをビルド時に入れたりしていましたが、
暗号化されたファイルを置くので変数入れ替えの管理が難しかったり、
環境依存のコンテナが出来てしまうのでイケてなく、
Credentialだけでもパラメータストアを使いたいと思っていました。

ふと同僚がパラメータストアからJAVA_OPTSにするのを書いてたので、
もうちょい汎用性あるようにしようと思って環境変数を利用しました。
(自分の要件に合わせて。でも後で同僚もオプション追加してたっぽい。)

作る前はentrykitやconfdにパラメータストアとつなぐ機能があればと思って探したけど無くて、
SocialCodeInc/dockerfyにそういうPRが出ている。
ただ、冷静に考えるとtemplate engineに外部依存があるのは微妙かもとは思いました。
plugin的にうまく連携できるならいいけど。
なので環境変数に設定できるのが手軽だなぁと。

一方でこれまでprogrium/entrykitを設定ファイルの入れ替えに使ってたのですが、
デバッグが難しくなったのでgliderlabs/sigilを直接使う形に変えました。
(ENTRYPOINT内での環境変数設定がうまくいってるかよくわからなかったため)
ただ、entrykitはファイルの権限とかもやってくれてたので面倒かも。
ENTRYPOINT以外でも使えるentrykitが望まれる・・・

要望とか

AWS ConsoleでパラメータストアのValueをマスクするモードが欲しいです。

あと、ECS定義内のEnvironmentから直接ssm:**parameter/**的なことができたら、、
と思ったけどローカルのdokcer-composeで困りそうではある。

既存のGitレポジトリから新しいレポジトリへ複数の要素を分割する (不完全)

既にあるレポジトリの一部をコミット履歴ごと別のレポジトリに移したいという例のアレです。

(repo_A)
 ├aaa/
 ├bbb/
 ├ccc
 └ddd

という構成の既存レポジトリがあって、これを元に次の新しいレポジトリ

(repo_B)
 ├aaa/
 └ccc

としたい。

まず複製する

mkdir repo_B
git clone repo_A repo_B

そして残したい物を列挙して次を実施

cd repo_B
git filter-branch -f --prune-empty --index-filter 'git rm --cached -r -q -- . ; git reset -q $GIT_COMMIT -- aaa ccc' -- --all

これで指定以外のファイルのコミットログが削除される。

後はリモートレポジトリ設定を書き換えてpushすればよい

git remote set-url origin git@github.com/ki38sato/repo_B.git
git push -u origin master

というのを試してみたのだが、移動しなかったファイルのコミットも新しい方に残るんだなコレ。不完全だったか。
(マージプルリクだから?)
ただ正直よくわからずコピペで試した段階なのでまだよくコマンド理解してない。
初めはsubdirectory-filterとか調べてるうちは理解できていたのだが、
複数要素選択どうするんだろうってなって
StackOverflow見て試したのがイマココ
普段sourcetree使ってる情弱だが後で気が向いたら調べたい (汗

ふるさと納税してみた話

ふるさと納税を使ってみたので思ったことをメモ。
ふるさと納税は本当にお得なのか?」みたいな話はクリア済みとします。

クリスマスイブにTwitterで「宮崎県都城市のお礼品の再入荷がされた」(意訳)を見て注文寄付してみた。
寄付にはふるさとチョイスというサイトを利用。
平成28年分の税控除対象にしたかったので、
クレジットカード可で12月31日まで受け付けの自治体から3自治体4品選択。

  • 平成28年の税控除対象になるのは大抵の自治体が12月31日最終期限だった。
  • 自治体によっては11月末の段階で受付終了するところも。
  • クレジットカードじゃない場合は引き落としの確認が期限内である必要がある。
  • ワンストップ特例制度を使う場合は5自治体以内である必要がある。

あと自分用に購入した肉を一緒に食べてもらうつもりの友人に内容量を言ったら
「1日じゃ食べきれないよね、それ」
って言われたのでご利用は計画的に。

更に「ワンストップ特例制度」を使うにはもう少し作業が必要です。

  • 平成28年から「寄付金税額控除に係る申告特例申請書」というのを各自治体に提出する必要がある。
  • 多分マイナンバー制度との兼ね合い
  • 提出期限が平成28年は1月10日までに各自治体必着。しかも紙。
  • 一緒にマイナンバーがわかるものと身分証明できるものの写しが必要。
  • マイナンバーカード両面とか、マイナンバー通知カード+免許証とか。

まだ届いたわけじゃないけど使ってみてお得だなーと思う反面、
でも面倒だよねーという感想も。

  • 申請書もいい感じに処理してほしい
  • 自治体によって送ってきた申請書に既に自分の情報記入済みと未記入があった
  • そもそもITで完結してほしいよね
  • マイナンバー連携いつされるのか
  • 税控除対象うんぬんももうチョイわかりやすく表示してほしい
  • そういう条件で検索できてもよさそう

とか他にもちょいちょい思ったことあった気がするが、
要するにこういうのもっと便利にならないかなーとか。
そういうこと考えるのITだよね(ちょっと違うけど
みたいなことを久々に思ったのでした。

Terraform 0.6.16 で格闘したことのメモ

Terraformの現バージョン(0.6.16)で相対した悩ましい問題のメモ。
暫定対処したが根本解決はしてない?。次のバージョンでは一部しそう。

aws_route_tableのrouteを削除しても適用されない

差分も出ないし実行もされない。
Issueが出ている -> Inline routes not removed from aws_route_table. #7632
routeをやめてaws_routeで全て書くようにしたら大丈夫になったような?。

aws_route_tableのrouteが変更してないのにplan上は差分が出る

planで差分が出るがapplyでは何も実行されない。
差分と言ってもA.1->A.2みたいな同じrouteを違う名前で付け直してるみたいな表示。
routeが複数(もしくはgateway使った時)の時しか起きないかも。
Issueが出てPR mergeされた? -> aws_route_table: Inconsistency when using gateway_id / nat_gateway_id #6551
routeをやめてaws_routeで全て書くようにしたら差分表示されなくなった。

複数のaws_security_groupで相互にingressできない

sg-Aのinboudにsg-B、sg-Bのinboundにsg-Aを設定したい。
Circle とか怒られる。
aws_security_group_ruleで全て書くようにしたら作成できた。

Accountをまたいだaws_security_group_ruleでplan上は差分が出る

Accountをまたいだ設定の時にAccount付とAccount無しを比較しているように見える。
Issue-> Terraform EC2 security group ingress rule flapping #6135
対策なし (-/+と出るのが救い)

aws_security_groupとaws_security_group_ruleを同時に使うとおかしくなる

これは問題というよりそういう仕様で注意書きがある -> NOTE
同じリソースにそれぞれアクセスして片方が上書くのでtfstateと合わなくなる。
aws_route_table/routeとaws_routeもそう。
ingressとegressは別のリソース判定っぽそう?

aws_iam_policy_attachmentで共通policyをattachmentする際には要注意

users/roles/groupsとリストになっているのを見れば気づくかもしれないが、
共通のpolicyを新しく作成したIAM Roleにattachしようとして、
rolesに単独で設定すると1回目は想定通り実行されるが、
tfstateを管理している場合に2回目に実行した時に他のIAM Roleがdettachされる。
この挙動はAWS Consoleやaws cli等で操作した時とは感覚的に異なるので注意が必要。

aws_iam_policy_attachmentのusers/roles/groupsには
紐付けられている全IAMが書かれている必要がある。
自分の意識では「IAM Role に IAM Role PolicyをAttach」する想定だったため、
その時作成したIAM Roleだけを書いて実行した。
(実際に実行したのは同僚でデバッグしたのも同僚・・・)
1回目の実行時は特に問題ないが、結果できるtfstateには全IAMが記載される。
この状態でもう一度(aws_iam_policy_attachmentにIAM Roleを1つだけ記載)
plan実行すると、記載した以外のIAMは前回との差分として抽出され、
apply実行すると、実際に他は外れて1個だけの状態になってしまう。

Terraform的にはIAMにpolicyをAttachするのではなく、policyにIAMをAttachするということ
なお、新しいリソースが追加される予定になっている模様
provider/aws: Add per user, role and group policy attachment (supersedes #5816) #6858

おしまい

Terraformは非常に開発速度の速いプロダクトなので、
これらは現バージョンのみの問題かもしれません。
なので説明はだいぶ雑になってますが、
自分の感覚的には非常に扱いづらい問題だったのでメモっておきました。
次のバージョンではもっとスッキリ書けると良いなぁ。

lambda-uploader (VirtualBox shared folder on Windows)で「Exception: virtualenv returned unsuccessfully」

Windows10上で、Docker Toolboxでlambda-uploader(virtualenv)を動かしたらエラーが出たので調べたメモ。

$lambda-uploader --no-upload -VV
中略

DEBUG:lambda_uploader.package:Virtualenv stderr: Traceback (most recent call last):
  File "/usr/local/bin/virtualenv", line 11, in <module>
    sys.exit(main())
  File "/usr/local/lib/python2.7/site-packages/virtualenv.py", line 708, in main
    symlink=options.symlink)
  File "/usr/local/lib/python2.7/site-packages/virtualenv.py", line 921, in create_environment
    site_packages=site_packages, clear=clear, symlink=symlink))
  File "/usr/local/lib/python2.7/site-packages/virtualenv.py", line 1353, in install_python
    os.symlink(py_executable_base, full_pth)
OSError: [Errno 71] Protocol error

 Unexpected error. Please report this traceback.
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/site-packages/lambda_uploader/shell.py", line 172, in main
    _execute(args)
  File "/usr/local/lib/python2.7/site-packages/lambda_uploader/shell.py", line 73, in _execute
    venv, cfg.ignore, extra_files)
  File "/usr/local/lib/python2.7/site-packages/lambda_uploader/package.py", line 47, in build_package
    pkg.build(ignore)
  File "/usr/local/lib/python2.7/site-packages/lambda_uploader/package.py", line 68, in build
    self.install_dependencies()
  File "/usr/local/lib/python2.7/site-packages/lambda_uploader/package.py", line 138, in install_dependencies
    self._build_new_virtualenv()
  File "/usr/local/lib/python2.7/site-packages/lambda_uploader/package.py", line 171, in _build_new_virtualenv
    raise Exception('virtualenv returned unsuccessfully')
Exception: virtualenv returned unsuccessfully

こんな感じのエラーが出るわけだが、ずばり以下の記事のとおりだった。
「vagrant環境でtoxしたらハマった件」

VirtualBoxのshared folderの問題で、
VagrantでもDocker Toolboxでも起きたし、
試しにshared folderではない別の場所にコピーして実行したら問題なく動いた。

Infrastructure as Code [2016/07/07 Thu.]を聴いてきた話

Recruit Technologies Open Lab #03 テーマ:Infrastructure as Codeに参加して来ました。
自分にとってのDevOpsInfrastructure as Codeは3年前くらいから始まっていて、
特に「はじめるDevOps」「JTF2013」への参加が印象に強いので、
Naoyaさん、ryuzeeさん、mizzyさんといったスピーカー陣・時期・内容からいっても
まさに振り返りのつもりで参加しました。
主催のmizzyさんも振り返りと言ってらした気がする。

資料

Naoya Itoさん 「Infrastructure as Code

ryuzeeさん 「Infrastructure as Codeと企業文化」

mizzyさん 「Infrastructure as Code のこれまでとこれから」

songmuさん 「運用・監視もコード化する。開発者が監視まで考える方法論」

katchangさん 「プロビジョニングツールはMakeで決まりだろ」

感想とか

NaoyaさんによるInfrastructure as Codeの歴史から。
初めは自動化から始まって徐々にコードのバージョン管理・ビルド再現性・テストと
アプリケーションと同じ流れで来てると。
それもサーバプロビジョニングだけでなくクラウドインフラ全体に対して。
Naoyaさん的にはこのままモデリングも・・・と思ったがイマイチ来てないとか。

自分もここ1年で書いたAnsibleが組織的には負債になってしまっているので
よい方法があったら知りたいが、ryuzeeさんの組織論にもヒントがありそうだった。
Dockerが来たことで違うStepに来てるのかなという気もする。
プロビジョニング層の複雑さを違う形で解決できそう。
この辺はkatchangさんの話にもつながる。

ryuzeeさんの組織論。
DevOps云々の前に組織文化大事ですよ。
バージョン管理やテストもしてないのでDevOpsどころじゃないよと。
大きく組織構造3パターン

  1. 開発部門とインフラ部門が独立、サービスに紐づかない
  2. 部門はそのままだがサービス毎にチームを組む
  3. サービスでワンチーム

基本的には1->2->3となるにつれ変化に強くなる半面、
サービス毎に品質のバラつき等の問題もおこりうる。
チャレンジする場合は小さく初めて必ず成功させようとのこと。

自分もインフラ担当1人なのに無理して1のパターンぽくなってボトルネックになってしまったので、
どういう感じに動くと3のパターンになれるのかというのは気になるところ。
組織文化・・・

mizzyさん
手法や分類を非常に丁寧に説明されていたので資料参照。
今後でいうとコンテナの影響によりプロビジョニング部分のツールの重要性は相対的に低下して
サーバ管理というよりはプロセス管理になっていくと。
マイクロサービス化によりテストやモニタリングが重要に。
自立制御のような仕組みが重要になっていくのでは。動的平衡

Serverspec以降の(テスト界隈の?)進展がないと仰ってて実際その辺は気になりました。
元々はリファクタのために作成されたはずですが、
インフラのモデリングが進まないのも一旦なのか、
それとToolもまだ少ない(Terraform一択)ですよね、という話をされてて割と同感。

さわのぼりさんのpodcast聴かなくちゃ。

songmuさん
監視やログは標準化した方が良いby「マイクロサービスアーキテクチャ
やっていくしかない
監視は継続的なテスト(先にやるか後にやるか)
欲しいapi生やしてモニタリングできる
アプリケーションエンジニアはコード書くの得意なので見たい項目を取ろう

見たい人が書いて改善してくの良いよなぁと思ってるけどどうやって推進すればいいのか難しい。
組織論の3のパターンだとこういうの進みそう。
Toolの説明してるように見えてチームの精神みたいなのも垣間見れる発表でした。

katchangさん
makeでプロビジョニングする。エラーも即中断して便利。
一般のプロビジョニングツールは宣言型アプローチ
実は冪等ではない(記述を削除しても反映されない)

ネタっぽい流れでありながらも考察は的確で
Dockerfileで実は一周回ってきた感あるし同感、みたいな話だった。
シンプルなのがいいよねっていう話なのかも。
そういえば誰かもイージーよりシンプルという話をしてた気がする・・・

まとめ

おっさん的振り返りとして参加したが学びも非常にあって良かった。