IAM Roles for Service Accounts を Terraformで手軽に体験してみる

2019年 9月 4日、EKSにIAM Roles for Service Accountsの機能が追加されました!

このアップデートにより、Kubernetesのサービスアカウントと、AWSのIAMを紐付けて運用することができるようになりました。

これまでと現在

今までは Pod に対して AWS リソースに対するアクセス権限を割り当てたい場合、 Node に IAM ロールを割り当てるしかありませんでした。 この方法を使うと、Node で動く Pod に対してすべての権限が振ってくるのでセキュリティ上問題がありました。

しかし今回のアップデートで Pod に対して IAM ロールを割り当てることが可能になりました。

IAM Role for Podsを用いることで、必要なPodに必要なだけの権限を付与することができるため、最小権限の原則を守ることができます。

手軽に体験する

この記事は、Introducing Fine-Grained IAM Roles for Service Accounts に基づいています。

元記事ではeksctlを用いてクラスタやIAMの作成を行っているのですが今回はTerraformを用いて環境を構築します。

Terraformを用いて構築することでGitHubなどにインフラの構成を残しておくことができます。

今回使用するコードはGitHubにあるため、適宜参照してください。

IAM Roles for Service Accounts をやるための準備

今回は、以下のバージョンで行いました。 - Terraform v0.12.9

以下の流れに沿って解説をします。

  1. EKSのクラスタを作成する

  2. EKS の OpenID Connect Provider URL を用いて OIDC プロバイダーを作成する

  3. OIDC プロバイダーを利用する IAM ロールをつくる

  4. Kubernetes サービスアカウントを作成する

  5. S3のbucketをつくる

EKSのクラスタを作成する

今回、terraform-aws-modules/eks/aws というmoduleを使用しています。

module "next-cluster" {
  source  = "terraform-aws-modules/eks/aws" #https://registry.terraform.io/modules/terraform-aws-modules/eks/aws/6.0.0
  version = "6.0.0"

  cluster_name                    = "${local.cluster_name}"
  cluster_version                 = "${local.cluster_version}"
  cluster_endpoint_private_access = true
  manage_aws_auth                 = false
  subnets                         = "${module.vpc.public_subnets}"
  vpc_id                          = "${module.vpc.vpc_id}"

  worker_groups = []

  write_aws_auth_config = false
  write_kubeconfig      = false
  tags                  = "${local.tags}"
}

EKS の OpenID Connect Provider URL を用いて OIDC プロバイダーを作成する

resource "aws_iam_openid_connect_provider" "oidc_provider" {
  client_id_list  = ["sts.amazonaws.com"]
  thumbprint_list = ["9e99a48a9960b14926bb7f3b02e22da2b0ab7280"] # CA thumbprint
  url             = "${module.next-cluster.cluster_oidc_issuer_url}"
}

先ほど作成したEKSのoidc_issuer_urlを用いて、 ODIC プロバイダーを作成します。

OIDC プロバイダーを利用する IAM ロールをつくる

1. KMS にアクセスできる IAM policy をつくる

resource "aws_iam_policy" "s3" {
  name   = "s3_read_only"
  policy = "${data.aws_iam_policy_document.s3.json}"
}

data "aws_iam_policy_document" "s3" {
  statement {
    effect    = "Allow"
    resources = ["*"]

    actions = [
      "s3:*",
    ]
  }
}

2. IAM Role for Service Accounts に利用する IAM Roleをつくる

resource "aws_iam_role" "s3_service_account" {
  assume_role_policy = "${data.aws_iam_policy_document.s3_service_account.json}"
}

data "aws_iam_policy_document" "s3_service_account" {
  statement {
    effect = "Allow"
    actions = [
      "sts:AssumeRoleWithWebIdentity"
    ]
    principals {
      type        = "Federated"
      identifiers = ["${aws_iam_openid_connect_provider.oidc_provider.arn}"]
    }
    condition {
      test     = "StringEquals"
      variable = "${replace(aws_iam_openid_connect_provider.oidc_provider.url, "https://", "")}:sub"
      values = [
        "system:serviceaccount:default:vault-unseal"
      ]
    }
  }
}

3. IAM Role と IAM Policyを紐付ける

resource "aws_iam_role_policy" "s3_service_account" {
  policy = "${data.aws_iam_policy_document.s3.json}"
  role   = "${aws_iam_role.s3_service_account.name}"
}

Kubernetes サービスアカウントをつくる

terraform applyすると、3つファイルが出てきます。

  • aws-auth

  • kubeconfig

  • s3_serviceaccount

kubeconfigを用いて、aws-auths3_serviceaccountをapplyしてください。

S3のbucketをつくる

resource "aws_s3_bucket" "bucket" {
  bucket = "terraform-bucket-test-hello-hello"
  acl    = "private"

  tags = {
    Name        = "My bucket"
    Environment = "Dev"
  }
}

bucketの名前は世界でユニークなので変更しておいてください。

これで準備は完了です。

s3へファイルを保存してみる

https://github.com/mhausenblas/s3-echoer をもちいて、IAM Roles for Service Accounts ができているかテストします。

git clone https://github.com/mhausenblas/s3-echoer.git && cd s3-echoer

s3-echoer-job.yaml.template をコピーして、s3-echoer-job.yamlとし、 serviceAccountName, TARGET_BUDGET, DEFAULT_AWS_REGION, をそれぞれ変更します。

変更したあと、kubectl apply -f s3-echoer-job.yaml でS3に保存するJobが走ります。

ここで、S3を確認してファイルが保存されていることを確認しましょう。

おわりに

今回、 IAM Roles for Service Accounts をeksctlではなくTerraformを用いて実現する方法について紹介しました。 この記事は、HERPでインターンをしているときの成果です。

株式会社HERPは、先日資金調達をしたり、京都と筑波に開発拠点が増えたりと今ノリに乗っている会社だと思います。 また、プロダクトの方もTypeScript + Haskell と面白い技術スタックなので興味ある方はぜひ!

www.wantedly.com

www.wantedly.com

参考

Introducing Fine-Grained IAM Roles for Service Accounts [アップデート] EKSでIAMロールを使ったPod単位のアクセス制御が可能になりました!

株式会社HERPでインターンをしました

もともとリモートで働いていたのですが、東京に呼んでいただいて二週間東京勤務をしました。 インターンをに全部落ちて辛かった時期なので呼んでいただけてとても嬉しかったです:bow:

herp.co.jp

やったこと

やったことは後でまとめて記事として投稿します!

ArgoCDの導入

CI/CDをすすめるため、ArgoCDの導入を行いました。 これまではアプリケーションを毎回人がkubectl apply -f していました。 しかし、これからはGitHubのPRがmergeされたタイミングでproduction, stagingにデプロイされるようになるため、エンジニアの負担軽減につながるかと思います。

一旦一部のアプリケーションにCDを導入し、ゆくゆくはすべてのアプリケーションがCDされると嬉しいです。

IAM Role for Service Accountの検証

9/4 に IAM Role for Service Account の機能がEKSに追加されました。 eksctlを使えば簡単に導入できるのですが、それをterraformで行うにはどうするかを検証しました。

今まではできなかったPod別のロール管理が簡単にできるようになり、それをTerraformでコードとして残しておけるようになったのが成果かと思います。

おわりに

先日会社として資金調達をしたり、京都と筑波に開発拠点が増えたりと今ノリに乗っている会社だと思います。また、プロダクトの方もTypeScript + Haskell と面白い技術スタックなので興味ある方はぜひ!

www.wantedly.com

www.wantedly.com

SREも絶賛募集中!!

CNDT2019 に参加してきました

Cloud Native Days Tokyo 2019に参加してきました。

きっかけ

もともとCloud Nativeに興味があり、Kubernetesなどちょこちょこ遊んでいたところに、この募集が流れてきました。

僕自身愛知の学生で、なかなか東京に来ることは出来ないためこういった支援制度があるのはとてもありがたいです。 採択していただきありがとうございます!

参加してみて

今回参加してみて、学生のうちに実際に働いてる人の話を聞いたり、セッションの聴講ができるというのは恵まれているなと思いました。

実際にセッションを聞いていて、手元で動かしているだけでは見つからないプロダクションならではの課題が聞けたり、チームでやっていくときに嵌りそうなポイントなど役に立つお話が聞けました。

面白かったセッション

いくつか抜粋して感想とメモを残します。

講中に残していたメモはDay1Day2です。

Opening

CNCF Cloud Native Definition v1.0

Cloud Native Trail Map

今回の来場者の46%が本番環境でKubernetesを運用しているという話を聞いて正直驚きました。

また、Stackanalyticsの紹介をされていました。 主に2016年に1社だった中国企業でが今では4社に増えているといった話や、CNCFのプロジェクトでは個人のコントリビュートが30%くらい占めている(!)という話をされていました。

Day 1ではOpenStack Upstream TrainingKubernetes Upstream Trainingがセッションと並行して行われており、そちらでは実際のプロジェクトにコントリビュートするためのトレーニングが行われていたようです。 そちらの資料は公開されるとのことで、公開が待ち遠しいです。

Performing Infrastructure Migrations at Scale

Airbnbの方による、どうやって新システムに移行するかという話でした。

技術的負債(Tech debt)が溜まっていくとつらいので新システムに移行するのですが、一気に移行はできないので新旧並行するタイミングは必ず存在します。そのタイミングはまた技術的負債になるのでつらいって感じでした。

*Migrations are the solver to systematically reduce tech debt** のワードが印象的で、結構胸に残ってます。

CircleCI 2.0を支える2つのコンテナクラスターとSRE

speakerdeck.com

技術編・組織編共にとても面白かったです。

中でも後半のSREチームの話はすごいなぁと聞いていました。

世界中に分散したSREチームが共同して障害対応を行うというのは想像もつかない苦労が裏にはあるのだろうと思いました。

メモ

技術編: 2つのクラスタ

  • Kubernetes
    • マイクロサービス用のコンテナ
      • 60くらい
        • フロントエンド
        • 課金
        • ユーザー管理
        • WebHook管理
  • Nomad
    • ビルド用のコンテナ
      • Docker imageのpull
      • コードのcheckout
      • ビルドコマンドの実行
      • Artifactsの保存 二つを分けることでセキュリティの担保
  • ユーザのコードをビルドする == ユーザのコードを実行できる

組織編: SRE

  • 分散したエンジニアリングチーム
    • アメリカ、ヨーロッパ、アジア
      • サンフランシスコのエンジニア単価がめちゃ高い
    • 今後は分散したエンジニアリングチームが主流になっていく?
  • ボーイング方式
    • Working together
    • 時差の有効活用
    • 継続的なペアリング
    • 無理のないアラート対応
    • 障害時対応
障害対応チーム構成
  • Incident Commander
    • Communication Commander
    • Incident Responce Team
    • Note Taker
  • ボランティアでできそうな人がやる
SRE Clinic
  • 週ごとにローテーションでToilを潰す
    • アカウントの削除、DNSレコードの追加 etc
  • Toil以外に集中できるようにする
  • Clinic
    • 駆け込み寺的なニュアンス
      pros, cons
  • Pros.
    • 他のエンジニアがタスクに集中できるようになった
    • 何がToilかの分類ができるようになった
  • Cons.
    • なにがClinicの仕事かの分類が曖昧
    • タスクからClinicへ映るときのタイミングが難しい
      • 自分のタスクを人に渡さないといけないので
    • Toil自体が減るわけではない

k3sで作る! 軽量k8sエッジコンピューティング環境

speakerdeck.com

Rancher Labsが開発した軽量なディストリビューションで、ARMアーキテクチャをサポートしていることからRaspberryPiで動くのが特徴らしいです。

実際にRaspberryPi3の上で動作させ、showKsならぬshow3sのデモを行っていました。

メモ

どうやってk8sから軽量化したのか

コードの削減

5つ機能を削った 1. レガシーまたは非デフォルトの機能 2. アルファ版の機能 3. クラウドプロバイダ向けのコード 4. Storageドライバ関連のコード 5. Docker(optional)

プロセスの削減

Kubernetesを構成する主要コンポーネントを単一プロセスにまとめた

showk3s

  • showKsの小プロジェクト
    • showKsと連携したk3sを用いたアプリケーション
  • k3sのエッジコンピューティングコンセプトをデモとして実装する

エッジコンピューティングで考えなければならないこと

  • 上流のネットワークは不安定
  • エッジ端末は壊れる
  • エッジは一般的に数が多い

Goldwing Smart Energy

Goldwing

  • スマート風力発電のために3万台を超える風車を運用

  • 各種データを数千箇所にあるエッジk8sクラスタに集約してアップロード

show3s

  • エッジコンピューティングについてきちんとした実装を素人がするのは大変
  • デモやPoC程度にはRPiとk3sの力で実現できる
  • お小遣い程度で公開できる
  • 興味あれば動かしてみて

おわりに

今回はスカラシップ枠での参加ということで、貴重な体験をさせていただくことが出来ました。

運営の皆様、本当にありがとうございます!

参加記録としてちょっと薄いものになってしまったのでこれから手を動かした記録などどんどんブログに残していこうと思います。

ありがとうございました!

Bitbucket Pipelinesを使ってみる

Bitbucket使ってますか?

Githubでもprivate repositoryが無限に作れるようになったので最近は使わなくなってしまったのですが、それでもまだ使ってる方は多いかと思います。

今回はBitbucketの便利機能の紹介をします。

Bitbucket Pipelines

Bitbucket Pipelinesとは、Bitbucketに統合されているCI/CDツールです。

便利なところ

  • 無課金でも使える
  • bitbucket-pipelines.ymlを書くだけで使える
  • CI/CD入門にちょうどよい
  • Slack通知ができる

つらいところ

  • bitbucket-pipelines.ymlを変更しないと動かない
    • 導入時に虚無のコミットが生まれやすい

動かしてみる

今回使うリポジトリこちら

Go言語で書かれたコードを想定しています。

Go modulesが有効になっているプロジェクトで、go testするまでです。

コード

bitbucket-pipelines.yml

各言語用にテンプレートが存在しているため、好きな言語で始めることができます。

# This is a sample build configuration for Go.
# Check our guides at https://confluence.atlassian.com/x/5Q4SMw for more examples.
# Only use spaces to indent your .yml configuration.
# -----
# You can specify a custom docker image from Docker Hub as your build environment.
image: golang:1.11

pipelines:
  default:
    - step:
        script: # Modify the commands below to build your repository.
          - PACKAGE_PATH="\${GOPATH}/src/bitbucket.org/\${BITBUCKET_REPO_OWNER}/\${BITBUCKET_REPO_SLUG}"
          - mkdir -pv "\${PACKAGE_PATH}"
          - tar -cO --exclude-vcs --exclude=bitbucket-pipelines.yml . | tar -xv -C "\${PACKAGE_PATH}"
          - cd "\${PACKAGE_PATH}"
          - go test -v

やっていることは簡単で、リポジトリからコードを落としてきて、go test -vするだけ

LT.go

package LT

func greeting() string {
        return "Hello."
}
LT_test.go
package LT

import "testing"

func TestGreeting(t *testing.T) {
        result := greeting()
        expected := "Hello, World."
        if result != expected {
                t.Errorf("greeting() failed. expect:%v, actual: %v", expected, result)
        }
        t.Logf("result is %v", result)
}

go.mod

Modulesで使用するファイルです。

今回ライブラリを使用していないため一行のみになっています。

module LT

注意

Settings/Pipelines settingsからBitbucket Pipelinesonにします。

また、Settings/Repository VariablesからGOMODULE111onにしましょう。

動かしてみる

先程のファイルをbitbucketにpushするとPipelinesが動き出します。

greeting()がHello, World.でなく、Hello.を返しているためテスト失敗しています。

以下のように変更しましょう。

package LT

func greeting() string {
        return "Hello, World."
}

commitしてpushするとまたPipelinesが動き出します。

Yay! :tada:

PS

この話は以前のLTをベースにしています!

Cloud Native Nagoya #01 に参加してきました

6月14日に行われたCloud Native Nagoya #01に参加してきました!

cnjp.connpass.com

晩ごはん

connpassを見ていたらお友達が参加することがわかり急遽晩御飯に誘いました

会場だった大名古屋ビルヂングB1にある名古屋コーチンのお店へ

とても美味しかったのでおすすめです。

名古屋コーチン親子丼 酉しみず | 大名古屋ビルヂング

Cloud Native Nagoya #01

発表が3本、LTが2本でした。

オープニング「世界における急速なCloud Native化の流れと日本の現状」

新藤洋介 (@shindoy) さんのオープニングトークで始まりました。 タイトル通り、 + 世界では急激にCloudNative化が進んでいる + 日本はCloudNative後進国 + 今から頑張ればまだ間に合うからがんばろう! というお話でした。

実際に世界ではどうなっているかという視点はなく、危機感もそんなになかったのでこのお話を聞けてよかったです。 実際に手を動かして追いつけるよう頑張ろうと思いました。

「遊びながら感じた Kubernetes の魅力」

二本目はエイチーム大西勉 (@tsutorm)さんの発表でした。 実際にKubernetesで遊んでみた感想がベースのお話で、最近やっていることと重なる部分もありとてもおもしろかったです。 実際にデモをされており、PodをdeleteしてもKubernetesが勝手に新しいPodを立てる様子が よくわかりました! よく知らない人でもわかりやすいデモだと思うので、僕も布教するときは同じようにやりたいと思います

「コンテナビルド高速化への道(仮)」

三本目はだびっつ(@dabits)さんの発表でした。

以前行われたヤフー名古屋TechMeetupでLTされていたものの完全版といった様子でした。

yahoo-nagoya.connpass.com

Dockerfileのビルドを高速化するためにやったことのまとめのお話でした。 結局全部BestPracticesに書いてあったとはいえ 手を動かしてたどり着いたという姿勢を見習いたいと思いました。

以下がおすすめされていたBest Practiceのスライドです。

www.slideshare.net DCSF19 Dockerfile Best Practices

LT:「Cloud Immigrant: オンプレウェブアプリをコンテナ化して Amazon ECS にデプロイするまで」

LT一本目は@手羽先さんのLTでした。 オンプレのプロダクトをAWSに移行させる話だったのですが、こういった話を聞くのは初めてでとてもおもしろかったです。 EC2からマネージドサービスに移していってEC2の役割をどんどん減らしていくことでクラウドネイティブっぽい構成にするというアプローチでした。

「Dockerインストール後の設定をしよう」

LT二本目は@DaichiYamaguchiさんのLTでした。 Dockerはインストールしただけじゃなくて、しっかり設定してあげることでもっと良くなるというLTでした。 僕自身インストールして設定は全く触らず使っていたのでちゃんと設定してあげようと思うきっかけになりました。

名古屋ではまだまだ勉強会も少なく、貴重な機会に参加できてよかったです。 今後またこういった勉強会があれば参加して、自分のアウトプットの質を高めていきたいです!

ElephantSQLを使ってみる

ElephantSQLとは

ElephantSQL 無料でも使えるPostgresqlのマネージドサービスです。

料金プラン

共有インスタンスのプランの場合、以下のとおりです。

プラン 最大データサイズ 同時接続数 月額料金
TINY TURTLE 20MB 5 無料
SIMPLE SPIDER 500MB 10 $5
CRAZY CAT 1GB 15 $10
PRETTY PANDA 2GB 20 $19

ハードウェア専有インスタンスのプランもあります。

そちらの説明は公式サイトを御覧ください。

いいところ

  • 環境構築や運用管理が不要
  • 東京リージョンが選べる

悪いところ

  • 無料プランは20MB
  • スケールが大変らしい(参考URL)

クラウドに簡単なWebアプリをデプロイしたいときなどにとりあえず使ってみるって場合に良いと思います。

使い方

ログイン

今回はTINY TURTLEを使ってみます。

ページ右上のLoginを押します。

ここで、GoogleGithubでのログインも選ぶことができます。 今回はGithubでのログインをしました。

インスタンスの作成

ログインできると、以下のような画面になります。 インスタンスの作成のために、右上のCreate New Instanceを押します。 ここで、インスタンスの名前とプランを選択します。 今回は

Name: testDB
Plan: Tiny Turtle

としました。 タグは今回使わないので空白です。

このNameインスタンスの名前であり、DBには関係ないので好きな名前をつけて大丈夫です。

入力が終わったら右下のSelect Regionを押します。

DBのリージョンを選択することができます。今回は一番近そうなAP-NorthEast-1(Tokyo)を選択しました。

選択が終わったら右下のReviewを押します。

選択したName,Regionが表示されています。 確認したら、右下のCreate Instanceを押します。

インスタンスの確認

トップページに戻ると、先ほど作成したインスタンスができています。 クリックして詳細を確認しましょう。 URLを用いて接続することができます。

psql "URL"
psql (9.3.25, サーバー 11.2 (Ubuntu 11.2-2.pgdg18.04+1))
WARNING: psql major version 9.3, server major version 11.
         Some psql features might not work.
SSL 接続 (暗号化方式: ECDHE-RSA-AES128-GCM-SHA256, ビット長: 128)
"help" でヘルプを表示します.
username=>

プロンプトが出てきたら成功です!

平成最後のハッカソンに参加してきた

平成最後のハッカソンに参加してきました

サイバーエージェント主催の平成最後のハッカソンに参加してきました!

きっかけ

www.cyberagent.co.jp

いつも一人でハッカソンに出ていたので、せっかくならと思い高専プロコンの前哨戦として友達を連れて参加しました。

いつもはインフラ・バックエンド担当なのですが今回はReactをガリガリ書いてました😇

作ったもの

平成生まれの私たちが、平成を楽しく振り返ることができるサービス/モノということで、平成に関するクイズを作ればいいんじゃないかという話になりました。

安直なアイディアで、絶対かぶると思ってたんですがそうでもなくてびっくりしました。

ただ一人でクイズに答えるだけだとつまんないので、複数人参加型のクイズにしました!

また、平成の各時代の通信速度を考慮して、最近のことならすぐ画像が表示され、昔のことなら上からすこしずつ画像が表示されるような工夫をしました!

こだわり

複数人参加型かつリアルタイムなクイズなので、前に表示した画面で正解不正解のグラフ・先着3名のアイコンと名前がでてくるってのをこだわって作りました:smile:

技術的な話

@onsd_

僕は普段バックエンドをGoでよく書いているんですが、今回はReactをガリガリ書いてました:fearful:

Travis.ciを用いてfirebaseへの自動デプロイなどを構築したり、Git-Flowで開発を進めたりモダンにできたんじゃないかな〜と思っています。

Travis.ciの話

Github Educationに登録しているとprivateリポジトリのビルドが無料になります!

ですが、Github Educationに登録しているOrganisationアカウントではだめです!

無料お試しの100回ビルドすると後は何もしてくれなくなります!気をつけよう!!

git checkout master && git pull && npm run build && firebase deployを手動で毎回やる羽目になります:cry:

@asasigure_ice

CSS,ロゴ作成全部やってくれました!

まじでありがたいです:bow:

さっさん

Reactの部分半分くらい書いてくれました!

一緒に開発できて楽しかったです。プロコンでもよろしく!

@gucchi1187

クイズ30問つくって!って言ったらやってくれました!

プレゼンもありがとう:bow:

発表

1チーム2分と短くてびっくりしました。

チーム数が多かったので仕方ないのですが、5分使ってこだわりとかいろいろ聞きたかったです!

5分あったら僕らは全員でクイズしようとしていました:smile:

作品は全部完成度高かっただけにそこがちょっと残念です

結果

入選はできなかったのですが、ハンズオンで遊んでくれた人からは好評だったのでよかったです!

フィードバックがあるのかはわかんないですが、あったら嬉しいです!

最後に

1週間のハッカソンだったのである程度規模のあるプロダクトをつくれてよかった。

また締切があることで集中(やらないと死ぬので)できてよい

個人プロダクトではこんなにできないので...

当日出会った方、人事の方などありがとうございました!

またどこで会ったらよろしくおねがいします!!