まーぽんって誰がつけたの?

iOS→Scala→インフラなおじさん技術メモ

aws_security_groupのdescriptionはupdateできない

descriptionを気軽な名前で作ってしまって、あとでちょこっと変更したいなーと思って terraform planするとforce new resourceになってしまう。

ドキュメントにも書いてあった。

AWS: aws_security_group - Terraform by HashiCorp

description - (Optional, Forces new resource) The security group description. Defaults to "Managed by Terraform". Cannot be "". NOTE: This field maps to the AWS GroupDescription attribute, for which there is no Update API. If you'd like to classify your security groups in a way that can be updated, use tags.

aws_security_groupは気軽にdescriptionを設定しないようにしよう!識別したいだけなら、tags.Nameを使えばok

今日覚えたやつメモ 2017/1/27

rubyとかrailsとかRSpecのこと

fluentdのこと

dockerとmacでunix domain socketを共有する

ECSでの動的なネットワークポートマッピングとfluentd

固定ポートだとインスタンスの数以上にコンテナが増やせない

ECS上でfluentdを複数コンテナで動かして集約サーバーとして動かそうとしている。 最初だから試しにautoscaling groupで1つのインスタンスだけ立ち上げて、コンテナを2つ(desired count = 2)なサービスで立ち上げようとした。

でも、2台目のコンテナはportが埋まってますよというエラーで立ち上がってくれずにstoppedになってしまう。 そう言われてみればそうだなと。

ALBなら動的なネットワークポートマッピングが可能だが・・

Amazon ECSのELB構成パターンまとめ(ALB対応) | Developers.IOとか、Amazon ECS と AWS Application Load Balancer の組み合わせを試しているメモ - ようへいの日々精進XPとかを見ると動的にポートマッピングしてるからALBを使えばいけそう。しかし、healthcheckはHTTPかHTTPSでやらないといけない。

fluentdの集約サーバーはforwardプロトコルで24224で待ち受けていて、ELBならTCPでのhealthcheckでOKなので問題なかったが、ALBにするならばHTTPでhealthcheckできるようにしないといけない。 healthcheckに関してはfluentdはin httpも受け付けているのでそれでhealthcheckできるようにすればいける。

ただ、healthcheckはいけたとしても、結局forward Output Pluginはforward protocolでhttpじゃないのでダメだ。。

まとめ

集約サーバー側でforwardを使う限りALBは使えない。

fluent-plugin-s3でなかなかs3にアップロードされない

github.com

time_slice_formatの値をexampleに従って、%Y%m%d-%Hにしたんだけど、なかなかs3にアップされない。 buffered_pathには吐かれてるんだけどなかなかS3には上がってこない。

instanceのpoliciyかなーとかs3のbucketのpoliciyかなーとか色々迷っててうーんってハマってたらいつのまにかアップされてた。 どうやら1時間ぐらいたってた。

で、これはなぜかっていうと、time_slice_formatが時間ごとの値になってるからファイル名が変更になるまではs3にアップされない。s3にアップされて欲しいintervalを設定するのが、flush_intervalだった。 flush_intervalはplugin-s3のものではなく、そもそもbuffered-outputのもの。 flush_interval 60sと書けば1分ごとにs3にアップされた。

terraformのecs_registry.repository_urlにhttpsがついてるのを消す

バグだったようだ。mergeされたのでそのうち修正版がリリースされるはず。それまでは"${replace(aws_ecr_repository.test.repository_url, "https://", "")}"でしのぐ。

github.com

追記

terraform v0.8.5 で取り込まれた。

ECS(Amazon EC2 Container Service)がなんなのかやっと理解できてきた

いざ自分で一から作ってみると・・・

今まで人が作ったECS上でサービスの作成とか更新とか、タスクの更新とかやってきてなんとなく使えてたけど、 いざ自分で一から作ってみるとそれぞれの要素がどうなってるのか何も分かってないことに気づいた。 今まではECSでclusterとserviceを作っていって、clusterとかserviceに対して全体的なネットワークとかインスタンスの数とかの設定をしていくものだと思ってたけどそうじゃなかった。

ECSの役割

ECSがやってるのは主にスケジューラ(どのインスタンスにどのコンテナをいい感じに配置するか)がメインで、コンテナーインスタンスamazon-ecs-agentをおいてecsサービスのAPIを叩かせている。

じゃあ、全体的なネットワークの設定はどうするのかっていうと、ただのAuto Scalingという機能を使っていつも通りインスタンスを立ち上げてるだけ。なんならAuto Scalingを使わずに手動でAMIからインスタンスたちあげて、それをECSにコンテナーインスタンスとして登録したってよい。

GUIのウィザードでECSを作ろうとすると至れり尽せりでいい感じに色々なものができる。で、今やろうとしてるのはterraformで一から作ろうとしてるところだから、必要なものがなんなのか、どんな機能の組み合わせでできてるのかが分からないとterraformを書くことができない。進みは遅いし苦しいけど勉強にはなる。

ecs-agentの起動方法

会社の既存プロジェクトとかterraformのexampleを見てると、launch_configurationでuser_dataで結構がっつりシェルが書いてある。でも、AWS Consoleでウィザード経由で作ると、これだけ。

#!/bin/bash
echo ECS_CLUSTER=hoge >> /etc/ecs/ecs.config

一体この違いはなんなんだ・・ってはまったけどlinuxのdistributionが違ってた。見てたexampleとかはcoreOSとかubuntuとか。一方で、ウィザードだとamazon-linuxのecs-optimizedてやつ。だから色々書かずに済んでたんだ。 amazon-ecs-agentのREADMEにその辺のことが書いてあった。

まとめ

ちょっとすっきりした

terraformで作るときに参考にするもの

社内のプロジェクトのを参考にできる恵まれた環境なのでまずはそれを見る。

他にもterraform公式リポジトリにあるexampleも参考になった。 terraform/examples at master · hashicorp/terraform · GitHub

インフラエンジニアになっていきたいと思った理由

今の思い

ここでいうインフラエンジニアはハードディスクがとかケーブルがとかガチなやつじゃなくて、各種スタックを組み合わせて構築するぐらいのやつ。 プログラミング歴=ほぼ社会人歴で、iOS開発がメインで一番長かった。そのあとScalaでサーバーサイド。で、今はインフラできるようになりたいと思ってる。

iOSエンジニアとしてサーバーサイドへの引け目

iOSは動く画面を作るのが楽しかった。ただ、すぐに太ってしまうUIViewControllerやたくさんのManagerクラスなどクソコードもいっぱい生み出してきてしまった。なので、Clean Architectureとかもっといい設計はないかとかを考えるのが楽しかった。 でも、なんとなくサーバーサイドとかWebのことが分からないことに引け目をずっと感じていたが、プロジェクトの状況で幸か不幸かサーバーサイドが足りないとなり、がっつりサーバーサイドの開発に携わることもできた。 はじめはWebの基本的なこととか効率的なSQL、DB設計とかが分かってなかったりScalaの関数型的な書き方が分からず苦しかったけどそこそこできるようになった。

解決できる領域の広さ

でも、サービスを運営してると障害起きたりしてもインフラ周りだと手も足も出せないのが悔しく、あと、何かXXXという問題を解決したいっていう時に、アプリケーション側で色々苦労して解決できたとしてもインフラ側でそれを何十倍の効果で解決しちゃったりする場面があって、それも悔しかった。なので、出来るようになりたい。

あとアプリもサーバーサイドも保守しやすいとか変更しやすいとかの設計を考えるのは楽しいし、実力もまだまだなんだけど、普通ぐらいのレベルにはなったなという気がしてる。

新しいことを覚える楽しさ

インフラは0だからそれを普通にする方がワクワクする。ほんの1ヶ月前は分からなかったことが分かるようになる感覚がたまらない。 ドラクエ3で言えば転職をしてレベルが1に戻るのを繰り返してる。 最初は簡単なことも分からず進捗も悪くてかなり苦しいんだけど、だんだんできるようになっていくのが好き。マゾなのかもしれない。

terraformというかHCLでif文使いたい

基本的にはサポートされてない。 けど、こちらの方のやり方を参考にして、こんな風にすればできるっちゃできる。

If you set count to 1 on a resource, you get one copy of that resource and if you set count to 0, that resource is not created at all.

blog.gruntwork.io

trueが1、falseが0になることを利用して、countを0または1にするっていうちょっとdirtyな感じ。

resource "aws_eip" "example" {
  count = "${var.create_eip}"
  instance = "${aws_instance.example.id}"
}

module "frontend" {
  source = "/modules/microservice"
  service_name = "frontend"
  ami = "ami-abcd1234"
  instance_type = "t2.medium"
  create_eip = true
}
module "backend" {
  source = "/modules/microservice"
  service_name = "backend"
  ami = "ami-efgh5678"
  instance_type = "m4.large"
  
  create_eip = false
}

なるほどねー。でも、公式にのってないようなやり方はあんまりやりたくないタイプ。

追記

terraform 0.8から公式にsupportされました🎉

resource "aws_instance" "web" {
  subnet = "${var.env == "production" ? var.prod_subnet : var.dev_subnet}"
}

CONDITION ? TRUEVAL : FALSEVAL

sts:AssumeRoleとは

AWS STSが分からなかった

AWS Security Token Serviceのこと。

aws stsググる

このドキュメントが出てきてざーっと読んでなんかCLIしたいときに使うのか?みたいなぐらいでしっくりこなかった。

docs.aws.amazon.com

EC2サービスを信頼するという概念

この記事が分かりやすかった。

さて、ここで封印した記憶を呼び起こします。「EC2サービス」を信頼することにより、「EC2がAssumeRoleを行えるように」なります。

dev.classmethod.jp

なるほどねー。

残業をさせてるのは誰

ふるさと納税のワンストップのやつ、自治体によって印字してくれてたり返信用封筒入れてくれてたりしてみんなこうなればいいのにと思ったんだけど、いいサービスやおもてなしを期待することにより、自分が巡り巡って残業や日本の生産性の低下を生み出してる側なのではと思った。

実際、過度なサービスに慣れすぎてしまってるなー。サービス受ける側としては日本最高だなーって思ってしまう

remote-execでEC2インスタンスの起動時の処理書いたけどuser-dataがあった

前にこれを書いたんだけど、こんなことする必要なかった。

mpon.hatenablog.com

こっちでよかったじゃないか。AWSのこと何も分かってない証拠ですね。

docs.aws.amazon.com