tfschemaの仕組み / How tfschema works

tfschemaの仕組み / How tfschema works

Terraformプロバイダから動的に型定義情報を取得する「tfschema」というツールを趣味で作ってます。

https://github.com/minamijoyo/tfschema

- Terraformのコアと同じgo-pluginプロトコルを使って、Terraformプロバイダから動的に型定義情報を取得できます。
- リソースタイプの一覧が取得できます。
- このリソースタイプの一覧を使ってbash/zshでコマンド引数の補完も可能。
- なので、このリソースタイプの一覧補完を使ってシュッと公式ドキュメントを開くこともできる。
- Terraform v0.11/v0.12 両方サポート

これがどういう仕組で動いてるのか、内部構造を簡単に解説します。

5ade34f8bdf1b55c4ff82c11cf23cf42?s=128

Masayuki Morita

August 01, 2019
Tweet

Transcript

  1. tfschemaͷ࢓૊Έ Terraform meetup tokyo #1 2019/08/01 @minamijoyo

  2. ࣗݾ঺հ • ৿ా ਅ೭ (Masayuki Morita) • Twitter/GitHub: @minamijoyo •

    SRE at CrowdWorks Inc. • झຯ: Terraform • ίʔυಡΜͩΓ • issueΛړͬͨΓ • ݟ͚ͭͨόάΛ࣏ͯ͠ΈͨΓ • αʔυύʔςΟͷπʔϧ࡞ͬͯ༡ΜͩΓ
  3. tfschemaͱ͸

  4. • https://github.com/minamijoyo/tfschema • TerraformͷϓϩόΠμ͔Βܕఆٛ৘ใΛऔಘ͢Δπʔϧ tfschemaͱ͸ $ echo 'provider "aws" {}'

    > main.tf $ terraform init Πϯετʔϧ(Macͷ৔߹) ϓϩόΠμͷμ΢ϯϩʔυ(ྫͱͯ͠aws) $ tfschema -install-autocomplete ิ׬ͷ༗ޮԽ(γΣϧͷϦϩʔυඞཁ) $ brew install minamijoyo/tfschema/tfschema
  5. $ tfschema resource show aws_iam_user +----------------------+-------------+----------+----------+----------+-----------+ | ATTRIBUTE | TYPE

    | REQUIRED | OPTIONAL | COMPUTED | SENSITIVE | +----------------------+-------------+----------+----------+----------+-----------+ | arn | string | false | false | true | false | | force_destroy | bool | false | true | false | false | | id | string | false | true | true | false | | name | string | true | false | false | false | | path | string | false | true | false | false | | permissions_boundary | string | false | true | false | false | | tags | map(string) | false | true | false | false | | unique_id | string | false | false | true | false | +----------------------+-------------+----------+----------+----------+-----------+ $ tfschema resource list aws | grep aws_iam_user aws_iam_user aws_iam_user_group_membership aws_iam_user_login_profile aws_iam_user_policy aws_iam_user_policy_attachment aws_iam_user_ssh_key ܕఆٛͷऔಘ ϦιʔελΠϓҰཡ ଐੑ஋ͷܕ΍ ඞਢ͔Ͳ͏͔ ͳͲ͕෼͔Δ
  6. tfschemaͷ࢓૊Έ

  7. tfschemaͷ࢓૊Έ • ௒ͬ͘͟Γ3ߦͰ·ͱΊΔͱ 1. providerͷόΠφϦΛ୳ࡧͯ͠ىಈ 2. GetSchemaؔ਺ͰϦιʔεͷܕఆٛΛऔಘ 3. ͍͍͔Μ͡ʹ੔ܗͯ͠දࣔ

  8. TerraformͱProvider • providerͱ͸aws/google/azurermͳͲͷϓϥάΠϯ • ී௨ʹTerraform࢖ͬͯΔͱɺ͋Μ·Γҙࣝ͠ͳ͍͔΋Ͱ͢ ͕ɺterraformίϚϯυͱ͸όΠφϦ͕෼͔ΕͯΔ • terraform initͰproviderͷόΠφϦΛμ΢ϯϩʔυ •

    terraform plan/applyͳͲͷλΠϛϯάͰprovider͕֤छΫ ϥ΢υͷAPIΛݺͼग़ͯ͠Δ
  9. providerͷόΠφϦͷ୳ࡧ • tfschema͸terraformίϚϯυ͕ಈ͘σΟϨΫτϦͰಈ͘Α͏ʹͳͬͯΔ • ී௨ʹterraform init͢Δͱ .terraformϑΥϧμ഑Լʹprovider͕μ΢ϯϩʔυ͞ΕΔɻ • tfschema͸terraformͱ͍͍ͩͨಉ͡ϧʔϧͰproviderΛ୳͢ʢݫີʹ͸2ͱ7͕ҧ͏ʣ •

    ۩ମతʹ͸ҎԼͷ৔ॴͰproviderͷόΠφϦΛ୳͢ 1. ΧϨϯτσΟϨΫτϦ 2. tfschemaͷόΠφϦ͕͋ΔσΟϨΫτϦ(terraformͷόΠφϦͷ৔ॴ͸γΣϧґଘ) 3. ϕϯμσΟϨΫτϦ terraform.d/plugins/<OS>_<ARCH> 4. ࣗಈΠϯετʔϧσΟϨΫτϦ .terraform/plugins/<OS>_<ARCH> 5. άϩʔόϧϓϥάΠϯσΟϨΫτϦ $HOME/.terraform.d/plugins 6. άϩʔόϧϓϥάΠϯσΟϨΫτϦ $HOME/.terraform.d/plugins/<OS>_<ARCH> 7. $GOPATH/bin (σόοά͢ΔͷʹศརͳͷͰೖͬͯΔ)
  10. go-pluginͱ͸ • terraformίϚϯυͱprovider͸go-pluginϓϩτίϧͰ௨৴ ͍ͯ͠Δ • https://github.com/hashicorp/go-plugin • Go੡ͷπʔϧʹϓϥάΠϯͷ࢓૊ΈΛఏڙ͢ΔϥΠϒϥϦ • HashiCorpͷ֤छπʔϧ(Packer/Terraform/Nomad/Vault)

    Ͱ࢖ΘΕͯΔ • RPCϕʔεͳͷͰɺϓϥάΠϯͷόΠφϦ͕෼͔Εͯͯ ΋ɺී௨ʹؔ਺Λݺͼग़͢Α͏ʹ࢖͑Δ
  11. ܕఆٛͷऔಘ • provider͕ຬͨ͢΂͖interface͸ҎԼͰఆٛ͞Ε͍ͯΔ(v0.12ͷ৔߹) • github.com/hashicorp/terraform/providers.Interface • plan/applyʹඞཁͳؔ਺ͷଞʹɺϦιʔεͷܕఆٛΛऔಘ͢Δ GetSchemaؔ਺͕͋Δ • GetSchemaؔ਺ͷ݁Ռ͸GetSchemaResponseܕ

    • HCLΛղऍ͢Δͷʹඞཁͳconfigschema.Blockؚ͕·ΕΔ • HCLͷσʔλߏ଄ʹ͍ͭͯ࿩࢝͠ΊΔͱ௕͘ͳΔͷͰׂѪ • tfschema͸Ұ୴಺෦දݱʹม׵ͯ͠ɺ͍͍͔Μ͡ʹ੔ܗͯ͠දࣔͯ͠Δ
  12. providerͷιʔείʔυݟͨ͜ͱ͋Δਓʹ͸ͳΜͱͳ͘఻ΘΔͱࢥ͏͚Ͳɺ Πϝʔδͱͯ͠͸ˣʹ૬౰͢Δ৘ใ͕ಘΒΕΔʢݫີʹ͸ͪΐͬͱҧ͏͚Ͳʣ ※஫: ͜Ε͸terraform-provider-awsͷιʔείʔυͷൈਮͰ͢ɻGetSchemaResponseͰ͸͋Γ·ͤΜɻ func resourceAwsIamUser() *schema.Resource { return &schema.Resource{

    Schema: map[string]*schema.Schema{ "arn": { Type: schema.TypeString, Computed: true, }, "name": { Type: schema.TypeString, Required: true, ValidateFunc: validateAwsIamUserName, }, func Provider() terraform.ResourceProvider { return &schema.Provider{ Schema: map[string]*schema.Schema{ … }, DataSourcesMap: map[string]*schema.Resource{ … }, ResourcesMap: map[string]*schema.Resource{ "aws_iam_user": resourceAwsIamUser(), “aws_iam_user_login_profile": resourceAwsIamUserLoginProfile(), ϦιʔελΠϓҰཡ ଐੑ஋ͷܕ΍ ඞਢ͔Ͳ͏͔ ͳͲ
  13. Ҿ਺ͷิ׬ • tfschemaʹ͸Ҿ਺ͷϦιʔελΠϓΛิ׬͢Δػೳ͕͋Δ • https://github.com/posener/complete • Go੡ͷCLIπʔϧͷิ׬ϥΠϒϥϦ • bash/zshͷิ׬ީิΛฦ͢ϩδοΫΛGoͰॻ͚Δ •

    TerrafromͰ΋࢖ͬͯΔmitchellh/cli ʹ૊Έࠐ·ΕͯΔ • ิ׬ީิΛऔಘ͢ΔͨΊʹɺtfschemaࣗ਎ͷόΠφϦΛݺͼग़ ͯ͠ɺཪͰGetSchemaؔ਺Λݺͼग़ͯ͠Δ • ಈతʹϦιʔελΠϓͷҰཡऔಘ͍ͯ͠ΔͷͰɺproviderͷ όʔδϣϯ্͕͕ͬͯ΋tfschemaଆ͸ϝϯςφϯεϑϦʔ
  14. ެࣜυΩϡϝϯτͷࢀর $ tfschema resource browse aws_iam_user ϒϥ΢β͕։͘

  15. ެࣜυΩϡϝϯτURLͷੜ੒ • HashiCorp͕ϝϯς͍ͯ͠ΔϝδϟʔͳproviderͷެࣜυΩϡϝϯ τͷURL͸Ұఆͷϧʔϧʹͳ͍ͬͯΔ • ϧʔϧΛܾΊଧͪͨ͠ΘΓͱࡶͳ࡞Γ͕ͩɺ͜ΕͰେମ։͚Δ • ͜ͷϧʔϧʹͳͬͯͳ͍ͷΛݟ͚ͭͨΒɺެࣜυΩϡϝϯτଆʹҰ ؏ੑ͕ͳ͍ͬͯissueΛཱͯΑ͏w •

    ϦιʔελΠϓΛิ׬ͭͭ͠ɺެࣜυΩϡϝϯτ͕γϡοͱ։͚Δ ͷͰ஍ຯʹ΂ΜΓ https://www.terraform.io/docs/providers/aws/r/iam_user.html $ tfschema resource browse aws_iam_user ҰఆͷϧʔϧʹͳͬͯΔ
  16. ॴײ • https://github.com/minamijoyo/tfschema • GetSchemaؔ਺Λ׬શʹཧղͨ͠ • αʔυύʔςΟͷπʔϧ࡞ΔͱTerraformͷ಺෦࣮૷ ʹৄ͘͠ͳͬͯͨͷ͍͠ ؾʹೖͬͨΒ˒ͯ͠Ͷ