前提
- TerraformのtfstateをS3で管理している
- S3のバージョニングを有効にしている
経緯
さきほどterraform state mv
をミスってtfstateからaws_vpc
の定義を消し飛ばしてしまい,すさまじいdiffを出してしまいました.
今後も起きる気がするのでいい感じにしておきたい...
やったこと
すくりぷとつくった
state-resurrection.sh
# !/bin/bash
export AWS_DEFAULT_REGION=ap-northeast-1
candidates=$(mktemp)
aws s3 ls s3://foo/tfstate --recursive | awk '{printf(" [%2d] %s\n", NR, $4)}' > $candidates
cat $candidates
read -p 'choose target tfstate number: ' num
num=$(printf "[%2d]" $num)
candidate=$(grep -F "$num" $candidates)
key=${candidate:5}
aws s3api list-object-versions \
--bucket foo \
--prefix $key \
--query 'Versions[].{VersionId:VersionId,LastModified:LastModified}|sort_by(@, &LastModified)' --output table
read -p 'choose target VersionId you want: ' v
aws s3api get-object --bucket foo --key $key --version-id $v tfstate.resurrected
実行結果
uraura@rosemary$ ~/bin/state-ressurection.sh
[ 1] tfstate/run/terraform.tfstate
[ 2] tfstate/gin/terraform.tfstate
[ 3] tfstate/vodka/terraform.tfstate
[ 4] tfstate/tequila/terraform.tfstate
choose target tfstate number: 3
------------------------------------------------------------------
| ListObjectVersions |
+---------------------------+------------------------------------+
| LastModified | VersionId |
+---------------------------+------------------------------------+
| 2016-08-29T23:24:25.000Z | Yo87dexAmPle1OGy4oBkSExAMp1eUGY. |
| 2016-08-29T23:26:54.000Z | HRvRFexaMP1efvLUg.8uMEXamPleDhWc |
| 2016-08-30T00:24:20.000Z | B8ExamplejLYcXnqqBFTexamPleknOPc |
| 2016-08-30T01:15:38.000Z | UEXamPLEQ5lTwZ4CK2ntJexAMP1e3VUK |
| 2016-09-02T07:50:28.000Z | q3kKnaauXP7nuExamPlecAWavExAMPle |
+---------------------------+------------------------------------+
choose target VersionId you want: B8ExamplejLYcXnqqBFTexamPleknOPc
{
"AcceptRanges": "bytes",
"ContentType": "application/json",
"LastModified": "Tue, 30 Aug 2016 00:24:20 GMT",
"ContentLength": 35960,
"VersionId": "B8ExamplejLYcXnqqBFTexamPleknOPc",
"ETag": "\"f24de000fdaf6479ba1923000c63600b\"",
"Metadata": {}
}
最初の選択肢は,いくつかの環境の構成を1つのバケットで管理しているので必要になっています.
1つのtfstateしかないのであれば固定でもいいでしょう.
指定された環境のtfstate(上の例ではウォッカ)のtfstateのバージョンを取得し,日付でソートしたものが表示されるので,欲しいバージョンIDをコピって次の選択肢で入力します.
そうすると指定したバージョンのtfstateが実行した場所にtfstate.resurrected
として帰ってきてくれます.
あとはstate操作をやりなおせば万事解決...
まとめ
state操作むずかしい