March 25, 2016

Azure & Terraform Tips (ARM対応 2016春版)

俺の屍を越えていけ 今週リリースされたTerraform v0.6.14で、Azure Resource Manager ProviderのリソースにVMとテンプレートデプロイが追加されました。この週末お楽しみ、という人も多いかもしれません。 小生、v0.6.14以前から触っていたこともあり、土地勘があります。そこで現時点でのTipsをいくつかご紹介します。 この3つは触る前から意識しよう ARMテンプレートリソースは分離して使う リソース競合したら依存関係を定義する 公開鍵認証SSH指定でエラーが出ても驚かない 1. ARMテンプレートリソースは分離して使う v0.6.14で、リソース“azurerm_template_deployment”が追加されました。なんとARMテンプレートを、Terraformの定義ファイル内にインラインで書けます。 でも、現時点の実装では、おすすめしません。 ARMテンプレートのデプロイ機能とTerraformで作ったリソースが不整合を起こす 避けるべきなのは”Complete(完全)“モードでのARMテンプレートデプロイです。なぜなら完全モードでは、ARM リソースマネージャーは次の動きをするからです。 リソース グループに存在するが、テンプレートに指定されていないリソースを削除します つまり、ARMテンプレートで作ったリソース以外、Terraform担当部分を消しにいきます。恐怖! デプロイ vs デプロイ!!。リソースグループを分ければ回避できますが、リスク高めです。 タイムアウトしがち それでもTerraformの外でARMテンプレートデプロイは継続します。成功すれば結果オーライですが…Terraform上はエラーが残ります。「ああそれ無視していいよ」ではあるのですが、割れ窓理論的によろしくないです。 せっかくのリソースグラフを活用できない Terraformはグラフ構造で賢くリソース間の依存関係を管理し、整合性を維持しています。サクサク apply & destroyできるのもそれのおかげです。ARMテンプレートでデプロイしたリソースはそれに入れられないので、もったいないです。 読みづらい Terraform DSLにJSONが混ざって読みにくいです。Terraform DSLを使わない手もありますが、それでいいのかという話です。 それでも”terraformコマンドに操作を統一したい”など、どうしても使いたい人は、ARMテンプレート実行部は管理も実行も分離した方がいいと思います。 2. リソース競合したら依存関係を定義する Terraformはリソース間の依存関係を明示する必要がありません。ですが、行き届かないこともあります。その場合は“depends_on”で明示してあげましょう。 例えば、以前のエントリで紹介した下記の問題。 Error applying plan: 1 error(s) occurred: azurerm_virtual_network.vnet1: autorest:DoErrorUnlessStatusCode 429 PUT https://management.azure.com/subscriptions/my_subscription_id/resourceGroups/mygroup/providers/Microsoft.Network/virtualnetworks/vnet1?api-version=2015-06-15 failed with 429 Cannot proceed with operation since resource /subscriptions/GUID/resourceGroups/xxxx/providers/Microsoft.Network/networkSecurityGroups/yyy allocated to resource /subscriptions/GUID/resourceGroups/***/providers/Microsoft.Network/virtualNetworks/yyy is not in Succeeded state. Read more

March 23, 2016

Azure & Terraform エラーコード429の対処法

Terraformer増加に備えて 2016/3/21にリリースされたTerraform v0.6.14で、Azure Resource Manager ProviderのリソースにVMとテンプレートデプロイが追加されました。待っていた人も多いのではないでしょうか。 追ってHashicorp認定パートナーのクリエーションラインさんから導入・サポートサービスがアナウンスされましたし、今後AzureをTerraformでコントロールしようという需要は増えそうです。 エラーコード429 さて、TerraformでAzureをいじっていると、下記のようなエラーに出くわすことがあります。 Error applying plan: 1 error(s) occurred: azurerm_virtual_network.vnet1: autorest:DoErrorUnlessStatusCode 429 PUT https://management.azure.com/subscriptions/my_subscription_id/resourceGroups/mygroup/providers/Microsoft.Network/virtualnetworks/vnet1?api-version=2015-06-15 failed with 429 autorestがステータスコード429をキャッチしました。RFC上で429は“Too many requests”です。何かが多すぎたようです。 対処法 もう一度applyしてください 冪等性最高。冪等性なんていらない、という人もいますが、こういうときはありがたい。Terraformが作成に失敗したリソースのみ再作成します。 背景 エラーになった背景ですが、2つの可能性があります。 APIリクエスト数上限に達した リソースの作成や更新に時間がかかっており、Azure側で処理を中断した 1. APIリクエスト数上限に達した Azure Resource Manager APIには時間当たりのリクエスト数制限があります。読み取り 15,000/時、書き込み1,200/時です。 Azure サブスクリプションとサービスの制限、クォータ、制約 Terraformは扱うリソースごとにAPIをコールするので、数が多い環境で作って壊してをやると、この上限にひっかかる可能性があります。 長期的な対処として、Terraformにリトライ/Exponential Backoffロジックなどを実装してもらうのがいいのか、このままユーザ側でシンプルにリトライすべきか、悩ましいところです。 ひとまずプロダクトの方針は確認したいので、Issueに質問をあげておきました。 2. リソースの作成や更新に時間がかかっており、Azure側で処理を中断した Terraform側ではエラーコードで判断するしかありませんが、Azureの監査ログで詳細が確認できます。 わたしが経験したエラーの中に、こんなものがありました。 Cannot proceed with operation since resource /subscriptions/GUID/resourceGroups/xxxx/providers/Microsoft.Network/networkSecurityGroups/yyy allocated to resource /subscriptions/GUID/resourceGroups/***/providers/Microsoft.Network/virtualNetworks/yyy is not in Succeeded state. Resource is in Updating state and the last operation that updated/is updating the resource is PutSecurityRuleOperation. Read more

March 17, 2016

PackerとAnsibleでAzureのGolden Imageを作る(ARM対応)

いつの間に ナイスな感じにイメージを作ってくれるPackerですが、いつの間にかAzure ARM対応のBuilderが出ておりました。0.10からかな。早く言ってください。 ansible_localと組み合わせたサンプル さっそく試してそつなく動くことを確認しました。サンプルをGithubにあげておきます。 手の込んだ設定もできるように、Provisonerにansible_localを使うサンプルで。 前準備 リソースグループとストレージアカウントを作っておいてください。そこにイメージが格納されます。 認証情報の類は外だしします。builder/variables.sample.jsonを参考にしてください。 Packerの構成ファイルはOSに合わせて書きます。サンプルのbuilder/ubuntu.jsonはubuntuの例です。 Azure ARM BuilderはまだWindowsに対応していません。開発中とのこと。 ansibleはapache2をインストール、サービスEnableするサンプルにしました。 サンプル ubuntu.jsonはこんな感じです。 { "variables": { "client_id": "", "client_secret": "", "resource_group": "", "storage_account": "", "subscription_id": "", "tenant_id": "" }, "builders": [{ "type": "azure-arm", "client_id": "{{user `client_id`}}", "client_secret": "{{user `client_secret`}}", "resource_group_name": "{{user `resource_group`}}", "storage_account": "{{user `storage_account`}}", "subscription_id": "{{user `subscription_id`}}", "tenant_id": "{{user `tenant_id`}}", "capture_container_name": "images", "capture_name_prefix": "packer", "image_publisher": "Canonical", "image_offer": "UbuntuServer", "image_sku": "14.04.3-LTS", "location": "Japan West", "vm_size": "Standard_D1" }], "provisioners": [{ "type": "shell", "scripts": [ ". Read more

March 9, 2016

Terraform & Azure デプロイ設計4原則

注: 2018/1/8にサンプルを更新しました。更新エントリはこちら。 情報がありそうでない 以前のエントリで書いたとおり、TerraformでAzureへデプロイする方式をClassicからResource Managerへ移行しているところです。 今後も継続して試行錯誤するとは思うのですが、ふらふらしないように原則を作りました。この手の情報はありそうでないので、参考になればと思いこのエントリを書いています。 なお、考え方は他のクラウドやデプロイツールでも応用できるかと。 4原則 セキュリティファースト 手順書をなくそう 分割境界にこだわりすぎない 早すぎる最適化は悪 なお、サンプルのTerraformファイル群を、Githubに置いておきました。 今後ガラガラポンする可能性は大いにありますが、現時点ではこんな構造です。 . ├── .gitignore ├── main.tf ├── availability_set │ ├── avset_web.tf │ ├── avset_db.tf │ └── variables.tf ├── network │ ├── sg_backend.tf │ ├── sg_frontend.tf │ ├── variables.tf │ └── vnets.tf ├── storage │ ├── storage_backend.tf │ ├── storage_frontend.tf │ └── variables.tf └── terraform.tfvars Availability Setに対するVMのデプロイはTerraformの外でやっています。まだTerraformのAzure RM Providerにない、ということもありますが、VMの増減はアドホックだったり、別ツールを使いたいケースが多いので。 1. セキュリティファースト セキュリティはデザイン時に考慮すべき時代です。機密情報が漏れないように、また、身内がうっかりリソースを壊して泣かないようにしましょう。 認証情報は変数指定し、設定ファイルから読み込む Read more

February 27, 2016

TerraformをAzure ARMで使う時の認証

高まってまいりました 全国10,000人のTerraformファンのみなさま、こんにちは。applyしてますか。 Terraformのマイナーバージョンアップのたびに、Azure Resource Manager Providerのリソースが追加されているので、ぼちぼちClassic(Service Management)からの移行を考えよう、という人もいるのでは。VMリソースが追加されたら、いよいよ、ですかね。 そこで、Classicとは認証方式が変わっているので、ご注意を、という話です。 client_id/client_secret って何よ 以下がARM向けのProvider設定です。 # Configure the Azure Resource Manager Provider provider "azurerm" { subscription_id = "..." client_id = "..." client_secret = "..." tenant_id = "..." } subscription_idは、いつものあれ。tenant_idは普段使わないけどどこかで見た気がする。でも、client_id/client_secret って何よ。ためしにポータルログインで使うID/パスワード指定したら、盛大にコケた。 "The provider needs to be configured with the credentials needed to generate OAuth tokens for the ARM API." おっとそういうことか。OAuth。 サービスプリンシパルを使おう Terraformをアプリケーションとして登録し、そのサービスプリンシパルを作成し権限を付与すると、使えるようになります。 “アプリケーション オブジェクトおよびサービス プリンシパル オブジェクト” “Azure リソース マネージャーでのサービス プリンシパルの認証” 以下、Azure CLIでの実行結果をのせておきます。WindowsでもMacでもLinuxでも手順は同じです。 Read more

© Copyright 2019 Toru Makabe

Powered by Hugo & Kiss.