kikukawa's diary

都内で活動するシステムエンジニアが書いてます。 興味を持った技術やハマったポイント、自分用メモをつけてます。 最近はweb中心

手動で作成したAWS環境をterraformで後追い

AWSコンソールから手動で作成した環境をterraformで後追いするために必要なこと、やることをメモします。 コマンドの詳しい説明や使い方は省略します。

terraform

  • terraform init : 作業ディレクトリを初期化します。
  • terraform plan : 差分確認ようです。
  • terraform import : 既存環境をtfstateにインポートします。
  • terraform state rm : インポートを取り消したいときに使います。

terraform import

terraformはtfstateと呼ばれるファイルにterraformの実行後の環境を保存しています。 既存の環境をtfstateに書き込むことで、terraform plan を実行したときに差分がでなくなります。 あくまでtfstateに現在の状態を書き込むだけなので、 xxx.tf などのコードを作成してくれるわけではありません。

terraform import はリソースひとつひとつに対して実行していく必要があります。

下記のような感じで指定します。

$ terraform import <terraformのmodule名>.<リソース名(変数名)> <リソースを特定するIDなど>

ex)

$ terraform import aws_cloudwatch_log_group.test_group yada

リソースを特定するIDなど は、moduleによって指定するものが違って、nameだったりidだったりします。 terraform のドキュメントの最後のところに参考例があります。 実際に指定する値はAWSコンソールから取ってきます。

terraform state rm

terraform import でインポートしたものをtfstateから削除します。 tfstateからの削除なので、AWS環境には影響ありません。

terraforming

terraforming は、 terraform のコードを書き出してくれるものです。 terrafrom とは別物なので、別途インストールする必要があります。

terraform import と違って、リソースの種類を指定してそのすべてのコードを出力します。 例えばセキュリティグループを指定したら、アカウントに紐づくすべてのセキュリティグループを取ってきます。 便利ですが、対応していないリソースも多いのですべてを terraforming 任せにするわけにもいきません。

また、 terraforming には、 tfstate を管理するオプションもあります。 terraform import とどっちを使うかは、 既存の環境のどれくらいを terraform 化したいかによると思います。

流れ

今回は、既存AWS環境のうち一部を terraform 化したいので、 terraform import を使った方法を想定します。

といった感じです。

terraform init でtfstateを作成

特に気をつけることもないので割愛

リバースエンジニアリング

terraforming に対応しているものいないものがあるのでそれぞれ対応します。

対応しているもの

流れ

  • terraforming でコードの書き出し
  • 作成したtfファイルの中身を確認・修正
  • terraform import
  • 差分確認

terraforming でコードの書き出し

リソースごとにコードを書き出していきます。

例)

$ terraforming sg > sg.tf

作成したtfファイルの中身を確認・修正

  • いらないものは削除
  • 必要ならリソース名(変数名)を変更
    • terraforming が勝手に命名するので分かりやすいとは言えない
    • 自分の考える命名規則とあってないなど
    • 下記の foo の部分のこと
resource "aws_cloudwatch_log_group" "foo" {
  name = "Bar"
}

terraform import

terraforming には、tfstateも一緒に更新してくれるオプションがありますが、 今回は一部だけをterraform化するため、個別にインポートする方法を取ります。

差分確認

terraform plan で差分の確認をします。 差分が出るようならでなくなるまで修正します。

対応していないもの

まず、リソース用のtfファイルを用意して 下記のように空でリソース名(変数名)を書いておきます。

resource "aws_cloudwatch_log_group" "foo" {
}

このリソース名(変数名)を使って terraform import します。 インポートが成功したら、差分を確認して、差分が出なくなるまで修正を繰り返します。

aws_iam_group_policy_attachmentで複数の管理ポリシーを追加する

メモ

terraform v0.12.6以降

resource "aws_iam_group_policy_attachment" "foo_attach" {
  for_each = toset([
    "arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess",
    "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryFullAccess",
    "arn:aws:iam::aws:policy/IAMFullAccess",
    "arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess",
  ])
  group      = aws_iam_group.foo.name
  policy_arn = each.value
}

terraformを0.11から0.12にアップグレード

v0.11.11からv0.12.24にアップグレードしたときのメモです。
classmethodさんの記事を参考にしました。

前提

  • アップグレード前はv0.11.11
  • stateファイルはS3で管理されている
  • macOS Catalina
  • tfenv導入済み

0.12checklistの実行

チェックリストコマンドを実行するために
tfenvで v0.11.14 に上げました。
v0.11.14 にしか存在しないコマンドです。

エラー

問題なければ、下記メッセージが出て終わるはずです。

Looks good! We did not detect any problems that ought to be
addressed before upgrading to Terraform v0.12

私の場合は、下記のようなメッセージが出ました。

$ terraform 0.12checklist
After analyzing this configuration and working directory, we have identified some necessary steps that we recommend you take before upgrading to Terraform v0.12:

- [ ] Terraform couldn't reach the Terraform Registry (at `registry.terraform.io`) to determine whether current provider plugins are v0.12-compatible.

  In general, we recommend upgrading to the latest version of each provider before upgrading to Terraform v0.12.

Taking these steps before upgrading to Terraform v0.12 will simplify the upgrade process by avoiding syntax errors and other compatibility problems.

このメッセージでググると、providerをupgradeしたほうがいいというような記事がありましたが、 解決しませんでした。

$ terraform init --upgrade=true

Initializing the backend...

Initializing provider plugins...
- Checking for available provider plugins on https://releases.hashicorp.com...

Error installing provider "aws": Get https://releases.hashicorp.com/terraform-provider-aws/: x509: certificate signed by unknown authority.

Terraform analyses the configuration and state and automatically downloads
plugins for the providers used. However, when attempting to download this
plugin an unexpected error occured.

This may be caused if for some reason Terraform is unable to reach the
plugin repository. The repository may be unreachable if access is blocked
by a firewall.

If automatic installation is not possible or desirable in your environment,
you may alternatively manually install plugins by downloading a suitable
distribution package and placing the plugin's executable file in the
following directory:
    terraform.d/plugins/darwin_amd64

そもそもローカルから registry.terraform.io , releases.hashicorp.comping を打っても返ってきません。

ワークアラウンド

ローカルの問題と判断し、dockerコンテナから 0.12checklist を実行しました。
今度は問題なく通りました。

0.12upgradeの実行

あとは参考記事通りに、 v0.12.24 にあげてから terraform init , terraform 0.12upgrade を実行するだけです。

versions.tf ファイルが作成された

backend.tf を作って、そこに required_version を書いてたのですが、 0.12upgrade 実行あとには versions.tf が作成されてました。 backend.tf から required_version は削除しました。

アップグレード後は force_destroy の差分がでなくなった

今回terraformの対象にしていたのはAWSコンソールから手動で作成されたリソースだったのですが、
import後に、planで差分確認だけしている(applyしてない)状態でした。
planでは aws_iam_user に下記差分が出てました。

force_destroy: "" => "false"

force_destroy は、terraform独自のプロパティで、 AWSコンソール上から手動で作ってから、
terraform import を使って後追いするとこの差分がでるようです。

しかし、v0.12にアップグレード後はこの差分がでなくなりました。

Puppeteerのメモ

ページ全てのスクリーンショットを取得する

await page.screenshot({ path: '/tmp/foo.jpg', fullPage: true });

ページのロードを待つ時間を指定する

timeoutで指定できます。

await page.goto('url'+tableCell04Val, {waitUntil: 'load', timeout: 0});

FargateとALBの設定メモ

ハマったのでメモしておきます。

最初はECSで assign_public_ip = "true" にしておく

しておかないと、sshで接続でのデバッグが難しいです。 不要になったらfalseにしましょう。

health_check_grace_period_seconds はきちんと設定する

FargateはEC2インスタンスよりも起動に時間がかかります。 なので、余裕をもった値にしておかないと、ヘルスチェックに失敗して、 設定によっては、

立ち上がる -> ヘルスチェック失敗 -> コンテナ終了 -> 立ち上がる -> ・・・

と数分ごとに起動と終了を繰り返すことになりデバッグが辛いです。

LBのターゲットの種類はipにする

デフォルトがinstanceなので注意が必要です。

ヘルスチェックのパスとmacherはよく確認する

当たり前と言えば当たり前ですが忘れやすいのでメモします。 例えばRedashなどログインが必要なものは、 / にアクセスすると /login にリダイレクトします。 このとき、 200 ではなく 302 が帰ってきます。

パスを / に設定したなら、 macherは '200,302' に macherを 200 に設定するならパスは /login にする必要があります。

braviaの録画用HDDを引っ越しする

もともと使っていた録画用HDDの調子が物理的におかしかったので、引っ越しをしました。 HDDらくらく交換ソフト というソフトがsonyから提供はされているのですが、TVが対応していない機種 & Windowsを持っていないので自前であれこれやった覚書です。

  1. 元のHDDより大きいHDDを用意する
  2. 新しいHDDを一応、braviaでフォーマットする(多分いらない工程)
  3. 新旧HDDをubuntuなどに接続する
  4. ddコマンドでクローンHDDを作成する
    • sudo dd if=/dev/sd* of=/dev/sd* bs=16M conv=sync,noerror
      • パスの sd* の部分は各自の環境に置き換え
    • sudo sh -c 'while true; do killall -USR1 dd; sleep 2; done'
  5. 新しいHDDの未使用の領域を使えるようにする
    • GPartedを使う
    • 先頭以外すべてのパーティションの前後を後ろにずらす形で変更する

続・マクアケはこんなところ

この記事はMakuake Development Team Advent Calendar 2019 20日目の記事です。

ここに書かれていることはすべて私見です。

昨年マクアケはこんなところと題してアドベントカレンダーに投稿しました。 今回は続編として、もし自分がマクアケで働きたいと思っているエンジニアならこんなことを知りたいという視点でもう少し具体的に書いてみようかと思います。 昨年の記事に書いたことは全くと言っていいほど変わってないので合わせて読んでもらえるといいかもしれません。 今回の記事に書かれていることが永続的に続くというわけでもないと思うので現状を知るための参考程度にしてもらえればと思います。

いくつかのチームと横断的な動き

マクアケの開発メンバーはいくつかのチームに分かれています。 それぞれが特定のミッションを背負っていて、それを達成するために日々開発しています。 細かいことは書けませんが、技術的に注力するチームとビジネス的に注力するチームがあります。 技術的に注力するチームはプロダクトの安定性やセキュリティ、開発の効率化などを目指してます。 ビジネス的に注力するチームは、目標数字の達成や(いろいろな意味でのユーザーの)プロダクトの使い勝手を改善などを目指しています。

また、チームを横断的に動くメンバーやチームの垣根を超えて協力することも多々あり、チームが分かれているからと動きにくいということもない気がします。 実際私は越境してきたメンバーに助けてもらったことが多々あります。

定期的なLT大会

マクアケでは定期的なLT大会が開催されています。 発表者それぞれが深堀りしたテーマを5-15分程度で発表していきます。 昨年今のオフィスに引っ越してきてから始まり、すでに22回やってます。 毎回軽食と飲み物が用意され、密かに楽しみにしているメンバーもいるようです。

上記定期的なLTとは別に 他社との合同LT大会やメンバーが海外のカンファレンスに参加したときのフィードバック発表なども不定期に開催され勉強会好きの方には合っているんじゃないかと思います。

オフィス

オフィスのレイアウト自体は こちら のときからあまり変わっていません。今の雰囲気だと、こちらの本田さんと中山社長の対談でちらっと社内の様子が見られるのでそちらが参考になるかもしれません。

レイアウトは変わっていないのですが、社内のIT関連を改善するチームが非常に頑張ってくれてていろいろなところの使い勝手が良くなりました。会議室のモニターなんかはワンクリックで出力できたりします。

リモートワーク

一部のメンバーはリモートワークで働いています。 ミーティングがあれば出社しますし、大きめなリリースをした後はしばらく出社している必要があったりなど、完全に自由というわけでもありませんが、リモートワークで働くという選択肢はあります。 ミーティングはすべてがオフラインというわけではなく、Slackの音声やZoomを使ったミーティングもありリモートからの参加が可能な場合があります。

リモートワークだからというわけではなく、相談することで柔軟な働き方ができる可能性は高いです。

まとめ

あくまで業務委託としての私見になりますが、働きやすいし働きがいのある現場だなと思います。