kasei_sanのブログ

かせいさんのIT系のおぼえがきです。胡乱の方はnoteとtwitterへ

Terraform Cloud にある state を mv する方法

流れ

  • state ファイルをローカルに持ってくる
  • backend をローカルに変更
  • terraform state mv を実行
  • terraform state push を実行
  • backend を Terraform Cloud に戻す(この時に、state を overwrite する)

state ファイルをローカルに持ってくる

terraform state pull > tmp.tfstate    

backend をローカルに変更

cat << EOF > override.tf
terraform {
  backend "local" {
  }
}
EOF
$ terraform init -reconfigure
Initializing modules...

Initializing the backend...

Successfully configured the backend "local"! Terraform will automatically
use this backend unless the backend configuration changes.

terraform state mv を実行

terraform state mv -state=tmp.tfstate ...

変更されたことを確認

terraform state list -state=tmp.tfstate | grep ...

terraform state push を実行

terraform state push tmp.tfstate

backend を Terraform Cloud に戻す(この時に、state を overwrite する)

rm override.tf
$ terraform init -reconfigure
Initializing modules...

Initializing the backend...
Acquiring state lock. This may take a few moments...
Do you want to copy existing state to the new backend?
  Pre-existing state was found while migrating the previous "local" backend to the
  newly configured "remote" backend. An existing non-empty state already exists in
  the new backend. The two states have been saved to temporary files that will be
  removed after responding to this query.

  Previous (type "local"): /var/folders/12/02rv601d4kv6gmbxrzg4hzzh0000gn/T/terraform229570062/1-local.tfstate
  New      (type "remote"): /var/folders/12/02rv601d4kv6gmbxrzg4hzzh0000gn/T/terraform229570062/2-remote.tfstate

  Do you want to overwrite the state in the new backend with the previous state?
  Enter "yes" to copy and "no" to start with the existing state in the newly
  configured "remote" backend.

既存の状態を新しいバックエンドにコピーするか? と聞かれるので「yes」と回答する

リモートのstateでも、変更が維持されていることを確認

terraform state list | grep ...

独自ドメインからRoute53でCloudFrontにAレコードを設定したときに、SSL関係のエラーが出た時の対処方法

現象

独自ドメインから、Route53でCloudFrontにAレコードを設定した その後に独自ドメインから、upした画像にアクセスするとSSL関係のエラーが発生する

curl -vv https://example.com/E4Tvj0mUUAEWnW8.jpeg
*   Trying ***.***.***.***...
* TCP_NODELAY set
* Connected to example.com (***.***.***.***) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/cert.pem
  CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* error:1400410B:SSL routines:CONNECT_CR_SRVR_HELLO:wrong version number
* Closing connection 0
curl: (35) error:1400410B:SSL routines:CONNECT_CR_SRVR_HELLO:wrong version number

CloudFrontのドメイン直接の場合はupした画像を見ることはできる

原因

CloudFront側で、CloudFrontのlternate Domain Names(CNAMEs)に、独自ドメインを設定していなかった

参考

blog.serverworks.co.jp

感想

SSLのハンドシェイクで失敗するので、なにか証明書関係のエラーと思って少しハマってしまった...

サーバメンテナンスのときには、503(Service Unavailable)を返して、さらに Retry-After ヘッダー をつけておくと安心かも

まとめ

  • メンテナンスページを出す時には、503(Service Unavailable) を返す
  • Retry-After ヘッダーに復旧日時を入れておくと、復旧後に見に来てくれるようになる
  • Retry-After ヘッダーが無いまま、長期間 503 を返すと、クローラーはサーバが復旧しないと思って index を外してしまう
  • また、200404 とかを返すとクローラーがメンテナンス中であることを理解してくれない

ソース

ちょっと古い

webmaster-ja.googleblog.com

RFCの Retry-After レスポンスヘッダの解説

HTTP/1.1: Header Field Definitions

EC2インスタンスの再起動と停止/起動のちがい

先に結論

ここに書いてあるとおり

docs.aws.amazon.com

  • 再起動: インスタンスは、同じホストコンピュータで保持される
  • 停止/開始: インスタンスは新しいホストコンピュータに移動されます

メンテナンスでEC2のハードウェア退役や再起動する場合は、停止/起動 の方がいいの?

イベントの告知でも、stopping and starting your instance と書かれているので、停止/起動のほうが良いと思う

そんなおぼえがき

複数バージョンのbundlerがインストールされている時の挙動おぼえがき

概要

複数バージョンのbundlerがインストールされているとき、どれが選択されるのか曖昧だったので実験

注意

公式ドキュメントの記述がみあたらなかったので、バージョンが変わると挙動が変わるかもしれないです

環境

ruby:3.0.1-alpine を使用。defaultで入っているbundlerは、2.2.15です

docker run --rm --name ruby -it ruby:3.0.1-alpine /bin/sh
/ # gem list --local | grep bundler
bundler (default: 2.2.15)
/ # bundler -v
Bundler version 2.2.15

先に結論

以下の優先順でバージョンが選ばれるようです。default は関係ない様子

  1. $BUNDLER_VERSION
  2. Gemfile.lock の BUNDLED WITH
  3. 一番新しいバージョン

複数バージョンを入れた場合、default や、インストール順は左右されず、最新のバージョンが参照される

/ # gem install bundler:2.2.20
Fetching bundler-2.2.20.gem
Successfully installed bundler-2.2.20
1 gem installed

/ # gem install bundler:2.2.19
Fetching bundler-2.2.19.gem
Successfully installed bundler-2.2.19
1 gem installed

/ # gem list --local | grep bundle
bundler (2.2.20, 2.2.19, default: 2.2.15)

/ # bundle -v
Bundler version 2.2.20

ディレクトリに Gemfile.lock がある場合、そこの BUNDLED WITH にかかれているバージョンが参照される

/ # cat <<EOS > Gemfile.lock
> GEM
>   remote: https://rubygems.org/
>   specs:
>     rack (2.0.6)
> 
> PLATFORMS
>   ruby
> 
> DEPENDENCIES
>   rack
> 
> BUNDLED WITH
>   2.2.19
> EOS
/ # bundle -v
Bundler version 2.2.20

環境変数 BUNDLER_VERSION があると、それが最優先される

/ # export BUNDLER_VERSION=2.2.15

/ # bundle -v
Bundler version 2.2.15

環境変数 BUNDLER_VERSION や、Gemfile.lock に書かれたバージョンがインストールされていな場合、最新のバージョンが参照される

bundle install しない限り、特に警告は出ませんでした

/ # export BUNDLER_VERSION=2.2.13

/ # cat <<EOS > Gemfile.lock
> GEM
>   remote: https://rubygems.org/
>   specs:
>     rack (2.0.6)
>
> PLATFORMS
>   ruby
>
> DEPENDENCIES
>   rack
>
> BUNDLED WITH
>   2.2.16
> EOS

/ # bundle -v
Bundler version 2.2.20

おまけ: bundle _version_ でバージョンを明示的に指定すると、そのバージョンが参照される

/ # bundle _2.2.15_ -v
Bundler version 2.2.15

存在しないバージョンを指定すると怒られます

/ # bundle _2.2.00_ -v
/usr/local/lib/ruby/3.0.0/rubygems.rb:281:in `find_spec_for_exe': can't find gem bundler (= 2.2.00) with executable bundle (Gem::GemNotFoundException)
        from /usr/local/lib/ruby/3.0.0/rubygems.rb:300:in `activate_bin_path'
        from /usr/local/bundle/bin/bundle:23:in `<main>'

古い ruby image だと、挙動が変わります

docker run --rm --name ruby -it ruby:2.5.1-alpine /bin/sh
/ # gem list --local | grep bundler
bundler (1.16.6, default: 1.16.2)
/ # bundler -v
Bundler version 1.16.6

2.2.20 をインストールしても、1.16.6 が参照されたまま

/ # gem install bundler:2.2.20
/ # gem list --local | grep bundler
bundler (2.2.20, 1.16.6, default: 1.16.2)
/ # bundler -v
Bundler version 1.16.6

これは、古い ruby の Dockerfile の中で BUNDLER_VERSION が設定されているため そのため、BUNDLER_VERSION を unset しないと想定通りの挙動してくれない

こちらのissueで議題になって、新しいバージョンでは BUNDLER_VERSION がセットされないようになっています

github.com

elasticbeanstalkのプラットフォーム(ruby puma)のバージョンを上げると、nio4r の依存関係でエラーが発生する件

elasticbeanstalkのプラットフォーム(ruby puma)のバージョンを上げると、こんなエラーが出るようになる

/opt/rubies/ruby-2.7.3/lib/ruby/site_ruby/2.7.0/bundler/runtime.rb:302:in `check_for_activated_spec!': You have already activated nio4r 2.5.7, but your Gemfile requires nio4r 2.5.5. Prepending `bundle exec` to your command may solve this. (Gem::LoadError)

原因

プラットフォームに入っている puma に依存している Gem と、自分が入れた Gem がコンフリクトしているために発生している模様

解決方法

アプリの puma のバージョンをプラットフォームの puma のバージョンと合わせれば解決

参考

おんなじ問題にハマった人

各環境ごとのpumaのバージョン

Nginxのデバッグログを取る方法

Nginxの内部転送の設定がうまく行かない時とかにデバッグログは便利なのですが、その設定方法をよく忘れるのでメモ

エラーログのログレベルを debug にする

error_log /dev/stdout debug;

内部転送を出力するように設定

rewrite_log on;

Nginxをデバッグモードで起動

nginx-debug -g "daemon off;"

いじょうです