最初に
本記事は Terraform Provider aws
でなく awscc
を利用している記事です。
Verified PermissionsはIaCと相性良いと思っているので、以下のIssueを日々ウォッチしながら待っていました。
そんな中、上記のissueで awscc
のプロバイダーに実装されたとコメントがあったので、そちらを使ってみた記事です。
awscc
は HashiCorp オフィシャル管理であるものの、v1.0に到達していないので、利用は自己責任でお願いします。
※例えば執筆時点でも以下のIssueのバグなどがあります
https://github.com/hashicorp/terraform-provider-awscc/issues/1284
参考にした記事
CDK管理でも問題無さそうなら、こちらの記事を参考にCDK管理した方が良いかもです。
VSCodeの設定
IaC管理するとしたら、開発端末でCedarやSchemaを書くことになりますが、何の補助もなしで書くのはtypoとかもありそうで、心許ないなと思っていました。
ただ、その点は以下のPlugin入れれば解決します。設定などは上記のCDKの記事を参考にしました。
実装
では実際の内容に入ります。
ディレクトリ構成
まずディレクトリ構成は以下のように整理しました。
├── cedar
│ ├── P001.cedar
│ ├── P002.cedar
│ ├── P003.cedar
│ └── xxx.cedar
├── schema
│ └── cedarschema.json
├── main.tf
スキーマ定義: schema/cedarschema.json
まずはサンプル用に以下のようなスキーマを定義してみました。
{
"MyApp": {
"entityTypes": {
"User": {
"memberOfTypes": [
"Group"
]
},
"Api": {
"memberOfTypes": [],
"shape": {
"attributes": {
"path": {
"required": true,
"type": "String"
}
},
"type": "Record"
}
},
"Group": {
"shape": {
"attributes": {},
"type": "Record"
},
"memberOfTypes": []
}
},
"actions": {
"HEAD": {
"appliesTo": {
"resourceTypes": [
"Api"
],
"context": {
"type": "Record",
"attributes": {}
},
"principalTypes": [
"Group",
"User"
]
}
},
"GET": {
"appliesTo": {
"context": {
"type": "Record",
"attributes": {}
},
"resourceTypes": [
"Api"
],
"principalTypes": [
"Group",
"User"
]
}
},
"PUT": {
"appliesTo": {
"resourceTypes": [
"Api"
],
"context": {
"type": "Record",
"attributes": {}
},
"principalTypes": [
"Group",
"User"
]
}
},
"OPTIONS": {
"appliesTo": {
"principalTypes": [
"Group",
"User"
],
"resourceTypes": [
"Api"
],
"context": {
"type": "Record",
"attributes": {}
}
}
},
"POST": {
"appliesTo": {
"context": {
"attributes": {},
"type": "Record"
},
"resourceTypes": [
"Api"
],
"principalTypes": [
"Group",
"User"
]
}
}
}
}
}
ポリシー定義: cedar/xxx.cedar
以下の二つのポリシー定義してみました。
permit (principal, action, resource)
when { principal in [MyApp::Group::"admin"] };
permit (
principal,
action in
[MyApp::Action::"GET", MyApp::Action::"OPTIONS", MyApp::Action::"HEAD"],
resource
);
Terraformの定義
main.tf
にまとめて書いてあります。バージョン等は適宜変更してほしいですが、実際に動かしたものを置いておきます。
ここまで見てきてわかる通り、Terraformとしては別ファイルで開発した定義をAWSに設定するだけの動きとなります。
terraform {
required_version = ">= v1.5.2"
required_providers {
awscc = {
version = "= 0.66.0"
source = "hashicorp/awscc"
}
}
backend "s3" {
}
}
variable "region" {
type = string
}
variable "profile" {
type = string
}
provider "awscc" {
profile = var.profile
region = var.region
}
locals {
cedar_dir = "${path.module}/cedar"
cedar_files = fileset(local.cedar_dir, "**/*.cedar")
}
resource "awscc_verifiedpermissions_policy_store" "this" {
validation_settings = {
mode = "STRICT"
}
schema = {
cedar_json = file("${path.module}/schema/cedarschema.json")
}
}
resource "awscc_verifiedpermissions_policy" "this" {
for_each = local.cedar_files
policy_store_id = awscc_verifiedpermissions_policy_store.this.id
definition = {
static = {
statement = file("${local.cedar_dir}/${each.value}")
description = "Policy File: ${each.value}"
}
}
}
terraform apply後確認
問題無く作成できています。