こんにちは、 kotamat です。
Terraform 0.12がでてしばらく立ちますが、先日構築したCloudfrontの環境において、Terraform0.12のdynamicを使わないと実現できない事案が発生したため、この際にと思い、一気に0.12にバージョンアップしました。
マイグレーション方法とかは、terraform側が提供しているものを使えば80%くらいはやってくれるので(一部手動で修正が必要ですが、WARNING出してくれるのでポチポチやっていくだけです。)今回は主題のdynamicについて紹介します。
Dynamicとは
terraform 0.12で追加されたシンタックスのうちの一つです。
通常、トップレベルのリソースに関しては、一つ一つのリソースに名前をつけて記述したり、 count
とかを使って繰り返しを記述していきますが、security group
や cloudfront
のようなネストされたリソースを記述する際には一つ一つ重複して書く必要がありました。
特にcloudfrontは機能が多く、befaviorに各パスごとのoriginを書くことによってL7スイッチになることができるため、設定が繰り返し記述になりがちであり、かつネストが多い非常に複雑な構造になっているため、dynamicの恩恵を受けることができます。
記述方法
今回は Nuxt Generate Laravel Nova on AWSが綺麗にハマった話
で紹介した形を例に考えてみます。
各種スイッチの向き先の対照表は下記になっています。
ディレクトリ | オリジンの向き先 |
---|
/api/* | API |
/nova/* | nova |
/nova-assets/* | nova |
/nova-api/* | nova |
/vendor/nova/* | nova |
default | S3(Nuxt.js) |
今までであれば、/apiのブロックを一つ、novaのブロックを4つ、deafultのブロックを一つ書く必要がありましたが、dynamicを用いることによって、defaultとordered一つのブロックですべての表現をすることができます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
| resource "aws_cloudfront_distribution" "main" {
// api
ordered_cache_behavior {
allowed_methods = [
"GET",
"HEAD",
"OPTIONS",
"POST",
"PUT",
"PATCH",
"DELETE",
]
cached_methods = [
"GET",
"HEAD",
]
default_ttl = 0
forwarded_values {
cookies {
forward = "all"
}
headers = ["*"]
query_string = true
}
max_ttl = 0
min_ttl = 0
target_origin_id = local.api_origin_id
viewer_protocol_policy = "redirect-to-https"
path_pattern = "/api/*"
}
// nova
ordered_cache_behavior {
allowed_methods = [
"GET",
"HEAD",
]
cached_methods = [
"GET",
"HEAD",
]
default_ttl = 0
forwarded_values {
cookies {
forward = "all"
}
headers = ["*"]
query_string = true
}
max_ttl = 0
min_ttl = 0
target_origin_id = local.nova_origin_id
viewer_protocol_policy = "redirect-to-https"
path_pattern = "/nova/*"
}
// 以下 nova-assets/*とかも記述していく
|
↓
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
| locals {
path_patterns = [
"/api/*",
"/nova/*",
"/nova-assets/*",
]
}
resource "aws_cloudfront_distribution" "main" {
dynamic "ordered_cache_behavior" {
// 何を繰り返すのかをfor_eachで指定する
for_each = locals.path_patterns
content {
allowed_methods = [
"GET",
"HEAD",
"OPTIONS",
"POST",
"PUT",
"PATCH",
"DELETE",
]
cached_methods = [
"GET",
"HEAD",
]
default_ttl = 0
forwarded_values {
cookies {
forward = "all"
}
headers = ["*"]
query_string = true
}
max_ttl = 0
min_ttl = 0
target_origin_id = local.api_origin_id
viewer_protocol_policy = "redirect-to-https"
path_pattern = ordered_cache_behavior.value // dynamicで指定したリソース名 + .valueでpathの中身を取得
}
}
}
|
他の使いみち
上記はbehaviorの設定をまとめるために使ってみましたが、例えばステージング環境は特定のパスだけBasic認証いれたいという要件が来たときには、今までだとlambda_function_association
だけ違う別リソースを記述する必要がありましたが、map
と組み合わせる事によって、下記のように同一ソースで記述することができます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
| locals {
lambda_associations = {
"stg": {
// stg特有のもの(Basic認証とか)
{
event_type = "viewer-request"
lambda_arn = module.viewer_request.qualified_arn
},
// prodと共通のもの
{
event_type = "origin-request"
lambda_arn = module.origin_request.qualified_arn
},
},
"prod": {
{
event_type = "origin-request"
lambda_arn = module.origin_request.qualified_arn
}
}
}
}
resource "aws_cloudfront_distribution" "main" {
default_cache_behavior {
dynamic "lambda_function_association" {
for_each = local.lambda_associations[terraform.workspace] // workspaceの値を取得し、動的にassociationを切り替える
content {
event_type = lambda_function_association.value.event_type
lambda_arn = lambda_function_association.value.lambda_arn
}
}
}
}
|
まとめ
terraform 0.12 dyanmicの使い方を、Cluodfrontを用いて紹介させてもらいました。
特に後者の、lambda edgeとの組み合わせは非常に使い勝手がいいので、よかったら試してもらえればと思います。
Author
kotamat
LastMod
2019-11-25
(db4285c)