Terraform modulesで作成したリソースをecspresso/lambroll(tfstate-lookup)で参照してみる
2020-04-11

tl; dr


{{ tfstate `module.security_group.this_security_group_id` }}
  • こうする必要がある

{{ tfstate `module.security_group.aws_security_group.this_name_prefix[0].id` }}

ecspresso/lambroll(tfstate-lookup)でmoduleで作成されたresourceを参照してみる

ecspresso と lambroll で tfstate からの値参照に対応した

通常moduleで作成したリソースのoutputを参照するには module.resouce.output_key で参照することができます。


module security_group {
  source  = "terraform-aws-modules/security-group/aws"
  version = "3.4.0"

  name   = "test"
  vpc_id = "vpc-e5303b87"
}

output security_group_id {
  value = module.security_group.this_security_group_id
}

$ terraform apply -auto-approve
module.security_group.aws_security_group.this_name_prefix[0]: Creating...
module.security_group.aws_security_group.this_name_prefix[0]: Creation complete after 2s [id=sg-0fb94054e6c5eab45]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Outputs:

security_group_id = sg-0fb94054e6c5eab45

これを tfstate-lookup で同じように module.security_group.this_security_group_id で取得しようとしてもうまくいきません。


$ ./tfstate-lookup module.security_group.this_security_group_id
invalid address: module.security_group.this_security_group_id

これは terraform.tfstate ファイルでは module.security_group.this_security_group_id の形式で値を保持していないためです。module内部で使用されているresourceを含んだ形で保持しています。
terraform show を実行すると module.security_group.aws_security_group.this_name_prefix[0] で保持されていることがわかります。


$ terraform show

# module.security_group.aws_security_group.this_name_prefix[0]:
resource "aws_security_group" "this_name_prefix" {
    arn                    = "arn:aws:ec2:ap-northeast-1:963262494726:security-group/sg-0fb94054e6c5eab45"
    description            = "Security Group managed by Terraform"
    egress                 = []
    id                     = "sg-0fb94054e6c5eab45"
    ingress                = []
    name                   = "test-20200411103600516300000001"
    name_prefix            = "test-"
    owner_id               = "963262494726"
    revoke_rules_on_delete = false
    tags                   = {
        "Name" = "test"
    }
    vpc_id                 = "vpc-e5303b87"
}


Outputs:

security_group_id = "sg-0fb94054e6c5eab45"

tfstate-lookup でも同じようにこのリソース名を渡してあげると値を取得することができます。


$ ./tfstate-lookup 'module.security_group.aws_security_group.this_name_prefix[0]' | jq .
{
  "arn": "arn:aws:ec2:ap-northeast-1:960003262494726:security-group/sg-0fb94054e6c5eab45",
  "description": "Security Group managed by Terraform",
  "egress": [],
  "id": "sg-0fb94054e6c5eab45",
  "ingress": [],
  "name": "test-20200411103600516300000001",
  "name_prefix": "test-",
  "owner_id": "963262494726",
  "revoke_rules_on_delete": false,
  "tags": {
    "Name": "test"
  },
  "timeouts": null,
  "vpc_id": "vpc-e5303b87"
}

$ ./tfstate-lookup 'module.security_group.aws_security_group.this_name_prefix[0].id'
sg-0fb94054e6c5eab45

これでmoduleで作成したリソースをecspressoから参照させる際に渡すべきリソース名がわかったので無事参照させることができました。


{
  "launchType": "FARGATE",
  "networkConfiguration": {
    "awsvpcConfiguration": {
      "subnets": [
        "{{ tfstate `aws_subnet.az-a.id` }}",
        "{{ tfstate `aws_subnet.az-b.id` }}"
      ],
      "securityGroups": [
        "{{ tfstate `module.security_group.aws_security_group.this_name_prefix[0].id` }}"
      ]
    }
  },
  "loadBalancers": [
    {
      "containerName": "app",
      "containerPort": 80,
      "targetGroupArn": "{{ tfstate `aws_lb_target_group.app.arn` }}"
    }
  ]
}