![Terraform Plan Analyzer を利用して Terraform Plan の内容を要約してみた](https://images.ctfassets.net/ct0aopd36mqt/wp-thumbnail-db64f1f2fda342fbdbdb6b2e336560e8/99e8f408bed87cdb4aa6bcadcaf57fc9/terraform-eyecatch.png)
Terraform Plan Analyzer を利用して Terraform Plan の内容を要約してみた
こんにちは! AWS 事業本部コンサルティング部のたかくに(@takakuni_)です。
かなり前ですが、 HashiCorp から terraform plan
を分析するモジュール(Terraform Plan Analyzer)が公開されました。
リリース内容から Amazon Bedrock、 Anthropic Claude など生成 AI を利用するようです。
内容
実態としては HCP Terraform で利用する Run Tasks 機能のモジュールで、以下の GitHub にて公開されています。
デプロイしたリソースのエンドポイントを利用し、 Run Task を作成することで、 Terraform Plan の結果を要約して分析可能になります。
やってみる
Run Task の作成
実際に Run Tasks 機能のモジュールを使ってみようと思います。 Usage に記載されている方法でデプロイします。
HCP Terraform のクレデンシャルと Organizations を聞かれるため、事前に準備しておきましょう。
make all
cd examples/basic
terraform init
terraform plan
terraform apply
作成するリソースの構成図は以下になります。 Lambda を CloudFront から OAC 経由で配信していてモダンなアーキテクチャに思えます。
Architecture より引用
また、作成されるリソースを見ていると、 Amazon Bedrock Guardrails も利用されており、不本意な生成 AI への入出力をガードするよう保たれています。
resource "aws_bedrock_guardrail" "runtask_fulfillment" {
name = "${local.solution_prefix}-guardrails"
blocked_input_messaging = "Unfortunately we are unable to provide response for this input"
blocked_outputs_messaging = "Unfortunately we are unable to provide response for this input"
description = "Basic Bedrock Guardrail for sensitive info exfiltration"
# detect and filter harmful user inputs and FM-generated outputs
content_policy_config {
filters_config {
input_strength = "HIGH"
output_strength = "HIGH"
type = "HATE"
}
filters_config {
input_strength = "HIGH"
output_strength = "HIGH"
type = "INSULTS"
}
filters_config {
input_strength = "HIGH"
output_strength = "HIGH"
type = "MISCONDUCT"
}
filters_config {
input_strength = "NONE"
output_strength = "NONE"
type = "PROMPT_ATTACK"
}
filters_config {
input_strength = "HIGH"
output_strength = "HIGH"
type = "SEXUAL"
}
filters_config {
input_strength = "HIGH"
output_strength = "HIGH"
type = "VIOLENCE"
}
}
# block / mask potential PII information
sensitive_information_policy_config {
pii_entities_config {
action = "BLOCK"
type = "DRIVER_ID"
}
pii_entities_config {
action = "BLOCK"
type = "PASSWORD"
}
pii_entities_config {
action = "ANONYMIZE"
type = "EMAIL"
}
pii_entities_config {
action = "ANONYMIZE"
type = "USERNAME"
}
pii_entities_config {
action = "BLOCK"
type = "AWS_ACCESS_KEY"
}
pii_entities_config {
action = "BLOCK"
type = "AWS_SECRET_KEY"
}
}
# block select word / profanity
word_policy_config {
managed_word_lists_config {
type = "PROFANITY"
}
}
tags = local.combined_tags
}
resource "aws_bedrock_guardrail_version" "runtask_fulfillment" {
guardrail_arn = aws_bedrock_guardrail.runtask_fulfillment.guardrail_arn
description = "Initial version"
}
リソース作成が完了すると Organizations の中に Run Task が作成されていました。
Run Task を使ってみる
CLI-Driven Driven な WorkSpace を作成し、実行モードは Remote を選択しました。
そのため、terraform plan
や terraform apply
に関しては HCP Terraform 側で実行するようにしています。
作成されたワークスペースに Run Task を紐づけます。Run Task は Pre-Plan, Post-Plan, Pre-Apply, Post-Apply と複数のステージに対応可能なのですが、今回は Post-Plan に設定してみます。
Terraform Plan の実施
今回は以下のコードに対して terraform plan
を実行してみました。EKS AutoMode を Kubernetes v1.32.0 で動かすシンプルなコードです。
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "5.85.0"
}
}
cloud {
organization = "hoge"
workspaces {
name = "ws-takakuni-plan-analyzer"
}
}
}
provider "aws" {
# Configuration options
region = "ap-northeast-1"
}
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
name = "eks-update-strategies"
cidr = "10.0.0.0/16"
azs = ["ap-northeast-1a", "ap-northeast-1c", "ap-northeast-1d"]
private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
public_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]
enable_nat_gateway = true
single_nat_gateway = true
enable_vpn_gateway = true
public_subnet_tags = {
"kubernetes.io/role/elb" = 1
}
}
module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "~> 20.0"
cluster_name = "eks-auto-mode"
cluster_version = "1.32"
cluster_endpoint_public_access = true
enable_cluster_creator_admin_permissions = true
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.private_subnets
control_plane_subnet_ids = module.vpc.private_subnets
cluster_compute_config = {
enabled = true
node_pools = ["general-purpose"]
}
}
Terraform Plan の結果はいつも通り、Terraform で作成するリソース一覧と期待される設定値が表示されます。(文字数の関係で空白省略しています)
Module を利用しているため、少ないコードで記述できてますが、実際は 54 リソースも作成します。 Plan の結果がかなり長いですね。terraform plan
のレビューコストを軽減するために、Terraform Plan Analyzer の出番です。
Terraform v1.10.5
on linux_amd64
Initializing plugins and modules...
module.eks.data.aws_caller_identity.current[0]: Reading...
module.eks.data.aws_partition.current[0]: Reading...
module.eks.data.aws_iam_policy_document.node_assume_role_policy[0]: Reading...
module.eks.module.kms.data.aws_caller_identity.current[0]: Reading...
module.vpc.aws_vpc.this[0]: Refreshing state... [id=vpc-055a47ed10fb16322]
module.eks.data.aws_iam_policy_document.assume_role_policy[0]: Reading...
module.eks.module.kms.data.aws_partition.current[0]: Reading...
module.eks.data.aws_iam_policy_document.node_assume_role_policy[0]: Read complete after 0s [id=3518401652]
module.eks.data.aws_partition.current[0]: Read complete after 0s [id=aws]
module.eks.data.aws_iam_policy_document.assume_role_policy[0]: Read complete after 0s [id=2830595799]
module.eks.module.kms.data.aws_partition.current[0]: Read complete after 0s [id=aws]
module.eks.data.aws_iam_policy_document.custom[0]: Reading...
module.eks.data.aws_iam_policy_document.custom[0]: Read complete after 0s [id=513122117]
module.eks.data.aws_caller_identity.current[0]: Read complete after 0s [id=123456789012]
module.eks.data.aws_iam_session_context.current[0]: Reading...
module.eks.data.aws_iam_session_context.current[0]: Read complete after 0s [id=arn:aws:sts::123456789012:assumed-role/tfc-role/terraform-run-LMknWcrtoAVAR16r]
module.eks.module.kms.data.aws_caller_identity.current[0]: Read complete after 0s [id=123456789012]
module.vpc.aws_subnet.private[2]: Refreshing state... [id=subnet-08ec616502d8e8e94]
module.vpc.aws_subnet.private[0]: Refreshing state... [id=subnet-042e0423e858cdd60]
module.vpc.aws_subnet.public[1]: Refreshing state... [id=subnet-0623d7ae04c067259]
Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
+ create
<= read (data resources)
Terraform will perform the following actions:
# module.eks.data.tls_certificate.this[0] will be read during apply
# (config refers to values not yet known)
<= data "tls_certificate" "this" {
+ certificates = (known after apply)
+ id = (known after apply)
+ url = (known after apply)
}
# module.eks.aws_cloudwatch_log_group.this[0] will be created
+ resource "aws_cloudwatch_log_group" "this" {
+ arn = (known after apply)
+ id = (known after apply)
+ log_group_class = (known after apply)
+ name = "/aws/eks/eks-auto-mode/cluster"
+ name_prefix = (known after apply)
+ retention_in_days = 90
+ skip_destroy = false
+ tags = {
+ "Name" = "/aws/eks/eks-auto-mode/cluster"
}
+ tags_all = {
+ "Name" = "/aws/eks/eks-auto-mode/cluster"
}
}
# module.eks.aws_eks_access_entry.this["cluster_creator"] will be created
+ resource "aws_eks_access_entry" "this" {
+ access_entry_arn = (known after apply)
+ cluster_name = (known after apply)
+ created_at = (known after apply)
+ id = (known after apply)
+ kubernetes_groups = (known after apply)
+ modified_at = (known after apply)
+ principal_arn = "arn:aws:iam::123456789012:role/tfc-role"
+ tags_all = (known after apply)
+ type = "STANDARD"
+ user_name = (known after apply)
}
# module.eks.aws_eks_access_policy_association.this["cluster_creator_admin"] will be created
+ resource "aws_eks_access_policy_association" "this" {
+ associated_at = (known after apply)
+ cluster_name = (known after apply)
+ id = (known after apply)
+ modified_at = (known after apply)
+ policy_arn = "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy"
+ principal_arn = "arn:aws:iam::123456789012:role/tfc-role"
+ access_scope {
+ type = "cluster"
}
}
# module.eks.aws_eks_cluster.this[0] will be created
+ resource "aws_eks_cluster" "this" {
+ arn = (known after apply)
+ bootstrap_self_managed_addons = false
+ certificate_authority = (known after apply)
+ cluster_id = (known after apply)
+ created_at = (known after apply)
+ enabled_cluster_log_types = [
+ "api",
+ "audit",
+ "authenticator",
]
+ endpoint = (known after apply)
+ id = (known after apply)
+ identity = (known after apply)
+ name = "eks-auto-mode"
+ platform_version = (known after apply)
+ role_arn = (known after apply)
+ status = (known after apply)
+ tags = {
+ "terraform-aws-modules" = "eks"
}
+ tags_all = {
+ "terraform-aws-modules" = "eks"
}
+ version = "1.32"
+ access_config {
+ authentication_mode = "API_AND_CONFIG_MAP"
+ bootstrap_cluster_creator_admin_permissions = false
}
+ compute_config {
+ enabled = true
+ node_pools = [
+ "general-purpose",
]
+ node_role_arn = (known after apply)
}
+ encryption_config {
+ resources = [
+ "secrets",
]
+ provider {
+ key_arn = (known after apply)
}
}
+ kubernetes_network_config {
+ ip_family = "ipv4"
+ service_ipv4_cidr = (known after apply)
+ service_ipv6_cidr = (known after apply)
+ elastic_load_balancing {
+ enabled = true
}
}
+ storage_config {
+ block_storage {
+ enabled = true
}
}
+ timeouts {}
+ upgrade_policy (known after apply)
+ vpc_config {
+ cluster_security_group_id = (known after apply)
+ endpoint_private_access = true
+ endpoint_public_access = true
+ public_access_cidrs = [
+ "0.0.0.0/0",
]
+ security_group_ids = (known after apply)
+ subnet_ids = (known after apply)
+ vpc_id = (known after apply)
}
}
# module.eks.aws_iam_openid_connect_provider.oidc_provider[0] will be created
+ resource "aws_iam_openid_connect_provider" "oidc_provider" {
+ arn = (known after apply)
+ client_id_list = [
+ "sts.amazonaws.com",
]
+ id = (known after apply)
+ tags = {
+ "Name" = "eks-auto-mode-eks-irsa"
}
+ tags_all = {
+ "Name" = "eks-auto-mode-eks-irsa"
}
+ thumbprint_list = (known after apply)
+ url = (known after apply)
}
# module.eks.aws_iam_policy.cluster_encryption[0] will be created
+ resource "aws_iam_policy" "cluster_encryption" {
+ arn = (known after apply)
+ attachment_count = (known after apply)
+ description = "Cluster encryption policy to allow cluster role to utilize CMK provided"
+ id = (known after apply)
+ name = (known after apply)
+ name_prefix = "eks-auto-mode-cluster-ClusterEncryption"
+ path = "/"
+ policy = (known after apply)
+ policy_id = (known after apply)
+ tags_all = (known after apply)
}
# module.eks.aws_iam_policy.custom[0] will be created
+ resource "aws_iam_policy" "custom" {
+ arn = (known after apply)
+ attachment_count = (known after apply)
+ id = (known after apply)
+ name = (known after apply)
+ name_prefix = "eks-auto-mode-cluster-"
+ path = "/"
+ policy = jsonencode(
{
+ Statement = [
+ {
+ Action = [
+ "ec2:RunInstances",
+ "ec2:CreateLaunchTemplate",
+ "ec2:CreateFleet",
]
+ Condition = {
+ StringEquals = {
+ "aws:RequestTag/eks:eks-cluster-name" = "${aws:PrincipalTag/eks:eks-cluster-name}"
}
+ StringLike = {
+ "aws:RequestTag/eks:kubernetes-node-class-name" = "*"
+ "aws:RequestTag/eks:kubernetes-node-pool-name" = "*"
}
}
+ Effect = "Allow"
+ Resource = "*"
+ Sid = "Compute"
},
+ {
+ Action = [
+ "ec2:CreateVolume",
+ "ec2:CreateSnapshot",
]
+ Condition = {
+ StringEquals = {
+ "aws:RequestTag/eks:eks-cluster-name" = "${aws:PrincipalTag/eks:eks-cluster-name}"
}
}
+ Effect = "Allow"
+ Resource = [
+ "arn:aws:ec2:*:*:volume/*",
+ "arn:aws:ec2:*:*:snapshot/*",
]
+ Sid = "Storage"
},
+ {
+ Action = "ec2:CreateNetworkInterface"
+ Condition = {
+ StringEquals = {
+ "aws:RequestTag/eks:eks-cluster-name" = "${aws:PrincipalTag/eks:eks-cluster-name}"
+ "aws:RequestTag/eks:kubernetes-cni-node-name" = "*"
}
}
+ Effect = "Allow"
+ Resource = "*"
+ Sid = "Networking"
},
+ {
+ Action = [
+ "elasticloadbalancing:CreateTargetGroup",
+ "elasticloadbalancing:CreateRule",
+ "elasticloadbalancing:CreateLoadBalancer",
+ "elasticloadbalancing:CreateListener",
+ "ec2:CreateSecurityGroup",
]
+ Condition = {
+ StringEquals = {
+ "aws:RequestTag/eks:eks-cluster-name" = "${aws:PrincipalTag/eks:eks-cluster-name}"
}
}
+ Effect = "Allow"
+ Resource = "*"
+ Sid = "LoadBalancer"
},
+ {
+ Action = "shield:CreateProtection"
+ Condition = {
+ StringEquals = {
+ "aws:RequestTag/eks:eks-cluster-name" = "${aws:PrincipalTag/eks:eks-cluster-name}"
}
}
+ Effect = "Allow"
+ Resource = "*"
+ Sid = "ShieldProtection"
},
+ {
+ Action = "shield:TagResource"
+ Condition = {
+ StringEquals = {
+ "aws:RequestTag/eks:eks-cluster-name" = "${aws:PrincipalTag/eks:eks-cluster-name}"
}
}
+ Effect = "Allow"
+ Resource = "arn:aws:shield::*:protection/*"
+ Sid = "ShieldTagResource"
},
]
+ Version = "2012-10-17"
}
)
+ policy_id = (known after apply)
+ tags_all = (known after apply)
}
# module.eks.aws_iam_role.eks_auto[0] will be created
+ resource "aws_iam_role" "eks_auto" {
+ arn = (known after apply)
+ assume_role_policy = jsonencode(
{
+ Statement = [
+ {
+ Action = [
+ "sts:TagSession",
+ "sts:AssumeRole",
]
+ Effect = "Allow"
+ Principal = {
+ Service = "ec2.amazonaws.com"
}
+ Sid = "EKSAutoNodeAssumeRole"
},
]
+ Version = "2012-10-17"
}
)
+ create_date = (known after apply)
+ force_detach_policies = true
+ id = (known after apply)
+ managed_policy_arns = (known after apply)
+ max_session_duration = 3600
+ name = (known after apply)
+ name_prefix = "eks-auto-mode-eks-auto-"
+ path = "/"
+ tags_all = (known after apply)
+ unique_id = (known after apply)
+ inline_policy (known after apply)
}
# module.eks.aws_iam_role.this[0] will be created
+ resource "aws_iam_role" "this" {
+ arn = (known after apply)
+ assume_role_policy = jsonencode(
{
+ Statement = [
+ {
+ Action = [
+ "sts:TagSession",
+ "sts:AssumeRole",
]
+ Effect = "Allow"
+ Principal = {
+ Service = "eks.amazonaws.com"
}
+ Sid = "EKSClusterAssumeRole"
},
]
+ Version = "2012-10-17"
}
)
+ create_date = (known after apply)
+ force_detach_policies = true
+ id = (known after apply)
+ managed_policy_arns = (known after apply)
+ max_session_duration = 3600
+ name = (known after apply)
+ name_prefix = "eks-auto-mode-cluster-"
+ path = "/"
+ tags_all = (known after apply)
+ unique_id = (known after apply)
+ inline_policy (known after apply)
}
# module.eks.aws_iam_role_policy_attachment.cluster_encryption[0] will be created
+ resource "aws_iam_role_policy_attachment" "cluster_encryption" {
+ id = (known after apply)
+ policy_arn = (known after apply)
+ role = (known after apply)
}
# module.eks.aws_iam_role_policy_attachment.custom[0] will be created
+ resource "aws_iam_role_policy_attachment" "custom" {
+ id = (known after apply)
+ policy_arn = (known after apply)
+ role = (known after apply)
}
# module.eks.aws_iam_role_policy_attachment.eks_auto["AmazonEC2ContainerRegistryPullOnly"] will be created
+ resource "aws_iam_role_policy_attachment" "eks_auto" {
+ id = (known after apply)
+ policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryPullOnly"
+ role = (known after apply)
}
# module.eks.aws_iam_role_policy_attachment.eks_auto["AmazonEKSWorkerNodeMinimalPolicy"] will be created
+ resource "aws_iam_role_policy_attachment" "eks_auto" {
+ id = (known after apply)
+ policy_arn = "arn:aws:iam::aws:policy/AmazonEKSWorkerNodeMinimalPolicy"
+ role = (known after apply)
}
# module.eks.aws_iam_role_policy_attachment.this["AmazonEKSBlockStoragePolicy"] will be created
+ resource "aws_iam_role_policy_attachment" "this" {
+ id = (known after apply)
+ policy_arn = "arn:aws:iam::aws:policy/AmazonEKSBlockStoragePolicy"
+ role = (known after apply)
}
# module.eks.aws_iam_role_policy_attachment.this["AmazonEKSClusterPolicy"] will be created
+ resource "aws_iam_role_policy_attachment" "this" {
+ id = (known after apply)
+ policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"
+ role = (known after apply)
}
# module.eks.aws_iam_role_policy_attachment.this["AmazonEKSComputePolicy"] will be created
+ resource "aws_iam_role_policy_attachment" "this" {
+ id = (known after apply)
+ policy_arn = "arn:aws:iam::aws:policy/AmazonEKSComputePolicy"
+ role = (known after apply)
}
# module.eks.aws_iam_role_policy_attachment.this["AmazonEKSLoadBalancingPolicy"] will be created
+ resource "aws_iam_role_policy_attachment" "this" {
+ id = (known after apply)
+ policy_arn = "arn:aws:iam::aws:policy/AmazonEKSLoadBalancingPolicy"
+ role = (known after apply)
}
# module.eks.aws_iam_role_policy_attachment.this["AmazonEKSNetworkingPolicy"] will be created
+ resource "aws_iam_role_policy_attachment" "this" {
+ id = (known after apply)
+ policy_arn = "arn:aws:iam::aws:policy/AmazonEKSNetworkingPolicy"
+ role = (known after apply)
}
# module.eks.aws_security_group.cluster[0] will be created
+ resource "aws_security_group" "cluster" {
+ arn = (known after apply)
+ description = "EKS cluster security group"
+ egress = (known after apply)
+ id = (known after apply)
+ ingress = (known after apply)
+ name = (known after apply)
+ name_prefix = "eks-auto-mode-cluster-"
+ owner_id = (known after apply)
+ revoke_rules_on_delete = false
+ tags = {
+ "Name" = "eks-auto-mode-cluster"
}
+ tags_all = {
+ "Name" = "eks-auto-mode-cluster"
}
+ vpc_id = "vpc-055a47ed10fb16322"
}
# module.eks.aws_security_group.node[0] will be created
+ resource "aws_security_group" "node" {
+ arn = (known after apply)
+ description = "EKS node shared security group"
+ egress = (known after apply)
+ id = (known after apply)
+ ingress = (known after apply)
+ name = (known after apply)
+ name_prefix = "eks-auto-mode-node-"
+ owner_id = (known after apply)
+ revoke_rules_on_delete = false
+ tags = {
+ "Name" = "eks-auto-mode-node"
+ "kubernetes.io/cluster/eks-auto-mode" = "owned"
}
+ tags_all = {
+ "Name" = "eks-auto-mode-node"
+ "kubernetes.io/cluster/eks-auto-mode" = "owned"
}
+ vpc_id = "vpc-055a47ed10fb16322"
}
# module.eks.aws_security_group_rule.cluster["ingress_nodes_443"] will be created
+ resource "aws_security_group_rule" "cluster" {
+ description = "Node groups to cluster API"
+ from_port = 443
+ id = (known after apply)
+ protocol = "tcp"
+ security_group_id = (known after apply)
+ security_group_rule_id = (known after apply)
+ self = false
+ source_security_group_id = (known after apply)
+ to_port = 443
+ type = "ingress"
}
# module.eks.aws_security_group_rule.node["egress_all"] will be created
+ resource "aws_security_group_rule" "node" {
+ cidr_blocks = [
+ "0.0.0.0/0",
]
+ description = "Allow all egress"
+ from_port = 0
+ id = (known after apply)
+ prefix_list_ids = []
+ protocol = "-1"
+ security_group_id = (known after apply)
+ security_group_rule_id = (known after apply)
+ self = false
+ source_security_group_id = (known after apply)
+ to_port = 0
+ type = "egress"
}
# module.eks.aws_security_group_rule.node["ingress_cluster_443"] will be created
+ resource "aws_security_group_rule" "node" {
+ description = "Cluster API to node groups"
+ from_port = 443
+ id = (known after apply)
+ prefix_list_ids = []
+ protocol = "tcp"
+ security_group_id = (known after apply)
+ security_group_rule_id = (known after apply)
+ self = false
+ source_security_group_id = (known after apply)
+ to_port = 443
+ type = "ingress"
}
# module.eks.aws_security_group_rule.node["ingress_cluster_4443_webhook"] will be created
+ resource "aws_security_group_rule" "node" {
+ description = "Cluster API to node 4443/tcp webhook"
+ from_port = 4443
+ id = (known after apply)
+ prefix_list_ids = []
+ protocol = "tcp"
+ security_group_id = (known after apply)
+ security_group_rule_id = (known after apply)
+ self = false
+ source_security_group_id = (known after apply)
+ to_port = 4443
+ type = "ingress"
}
# module.eks.aws_security_group_rule.node["ingress_cluster_6443_webhook"] will be created
+ resource "aws_security_group_rule" "node" {
+ description = "Cluster API to node 6443/tcp webhook"
+ from_port = 6443
+ id = (known after apply)
+ prefix_list_ids = []
+ protocol = "tcp"
+ security_group_id = (known after apply)
+ security_group_rule_id = (known after apply)
+ self = false
+ source_security_group_id = (known after apply)
+ to_port = 6443
+ type = "ingress"
}
# module.eks.aws_security_group_rule.node["ingress_cluster_8443_webhook"] will be created
+ resource "aws_security_group_rule" "node" {
+ description = "Cluster API to node 8443/tcp webhook"
+ from_port = 8443
+ id = (known after apply)
+ prefix_list_ids = []
+ protocol = "tcp"
+ security_group_id = (known after apply)
+ security_group_rule_id = (known after apply)
+ self = false
+ source_security_group_id = (known after apply)
+ to_port = 8443
+ type = "ingress"
}
# module.eks.aws_security_group_rule.node["ingress_cluster_9443_webhook"] will be created
+ resource "aws_security_group_rule" "node" {
+ description = "Cluster API to node 9443/tcp webhook"
+ from_port = 9443
+ id = (known after apply)
+ prefix_list_ids = []
+ protocol = "tcp"
+ security_group_id = (known after apply)
+ security_group_rule_id = (known after apply)
+ self = false
+ source_security_group_id = (known after apply)
+ to_port = 9443
+ type = "ingress"
}
# module.eks.aws_security_group_rule.node["ingress_cluster_kubelet"] will be created
+ resource "aws_security_group_rule" "node" {
+ description = "Cluster API to node kubelets"
+ from_port = 10250
+ id = (known after apply)
+ prefix_list_ids = []
+ protocol = "tcp"
+ security_group_id = (known after apply)
+ security_group_rule_id = (known after apply)
+ self = false
+ source_security_group_id = (known after apply)
+ to_port = 10250
+ type = "ingress"
}
# module.eks.aws_security_group_rule.node["ingress_nodes_ephemeral"] will be created
+ resource "aws_security_group_rule" "node" {
+ description = "Node to node ingress on ephemeral ports"
+ from_port = 1025
+ id = (known after apply)
+ prefix_list_ids = []
+ protocol = "tcp"
+ security_group_id = (known after apply)
+ security_group_rule_id = (known after apply)
+ self = true
+ source_security_group_id = (known after apply)
+ to_port = 65535
+ type = "ingress"
}
# module.eks.aws_security_group_rule.node["ingress_self_coredns_tcp"] will be created
+ resource "aws_security_group_rule" "node" {
+ description = "Node to node CoreDNS"
+ from_port = 53
+ id = (known after apply)
+ prefix_list_ids = []
+ protocol = "tcp"
+ security_group_id = (known after apply)
+ security_group_rule_id = (known after apply)
+ self = true
+ source_security_group_id = (known after apply)
+ to_port = 53
+ type = "ingress"
}
# module.eks.aws_security_group_rule.node["ingress_self_coredns_udp"] will be created
+ resource "aws_security_group_rule" "node" {
+ description = "Node to node CoreDNS UDP"
+ from_port = 53
+ id = (known after apply)
+ prefix_list_ids = []
+ protocol = "udp"
+ security_group_id = (known after apply)
+ security_group_rule_id = (known after apply)
+ self = true
+ source_security_group_id = (known after apply)
+ to_port = 53
+ type = "ingress"
}
# module.eks.time_sleep.this[0] will be created
+ resource "time_sleep" "this" {
+ create_duration = "30s"
+ id = (known after apply)
+ triggers = {
+ "cluster_certificate_authority_data" = (known after apply)
+ "cluster_endpoint" = (known after apply)
+ "cluster_name" = (known after apply)
+ "cluster_service_cidr" = (known after apply)
+ "cluster_version" = "1.32"
}
}
# module.vpc.aws_default_network_acl.this[0] will be created
+ resource "aws_default_network_acl" "this" {
+ arn = (known after apply)
+ default_network_acl_id = "acl-073faf59faa209e23"
+ id = (known after apply)
+ owner_id = (known after apply)
+ tags = {
+ "Name" = "eks-update-strategies-default"
}
+ tags_all = {
+ "Name" = "eks-update-strategies-default"
}
+ vpc_id = (known after apply)
+ egress {
+ action = "allow"
+ from_port = 0
+ ipv6_cidr_block = "::/0"
+ protocol = "-1"
+ rule_no = 101
+ to_port = 0
# (1 unchanged attribute hidden)
}
+ egress {
+ action = "allow"
+ cidr_block = "0.0.0.0/0"
+ from_port = 0
+ protocol = "-1"
+ rule_no = 100
+ to_port = 0
# (1 unchanged attribute hidden)
}
+ ingress {
+ action = "allow"
+ from_port = 0
+ ipv6_cidr_block = "::/0"
+ protocol = "-1"
+ rule_no = 101
+ to_port = 0
# (1 unchanged attribute hidden)
}
+ ingress {
+ action = "allow"
+ cidr_block = "0.0.0.0/0"
+ from_port = 0
+ protocol = "-1"
+ rule_no = 100
+ to_port = 0
# (1 unchanged attribute hidden)
}
}
# module.vpc.aws_default_route_table.default[0] will be created
+ resource "aws_default_route_table" "default" {
+ arn = (known after apply)
+ default_route_table_id = "rtb-0e1a79713163b95fd"
+ id = (known after apply)
+ owner_id = (known after apply)
+ route = (known after apply)
+ tags = {
+ "Name" = "eks-update-strategies-default"
}
+ tags_all = {
+ "Name" = "eks-update-strategies-default"
}
+ vpc_id = (known after apply)
+ timeouts {
+ create = "5m"
+ update = "5m"
}
}
# module.vpc.aws_default_security_group.this[0] will be created
+ resource "aws_default_security_group" "this" {
+ arn = (known after apply)
+ description = (known after apply)
+ egress = (known after apply)
+ id = (known after apply)
+ ingress = (known after apply)
+ name = (known after apply)
+ name_prefix = (known after apply)
+ owner_id = (known after apply)
+ revoke_rules_on_delete = false
+ tags = {
+ "Name" = "eks-update-strategies-default"
}
+ tags_all = {
+ "Name" = "eks-update-strategies-default"
}
+ vpc_id = "vpc-055a47ed10fb16322"
}
# module.vpc.aws_eip.nat[0] will be created
+ resource "aws_eip" "nat" {
+ allocation_id = (known after apply)
+ arn = (known after apply)
+ association_id = (known after apply)
+ carrier_ip = (known after apply)
+ customer_owned_ip = (known after apply)
+ domain = "vpc"
+ id = (known after apply)
+ instance = (known after apply)
+ ipam_pool_id = (known after apply)
+ network_border_group = (known after apply)
+ network_interface = (known after apply)
+ private_dns = (known after apply)
+ private_ip = (known after apply)
+ ptr_record = (known after apply)
+ public_dns = (known after apply)
+ public_ip = (known after apply)
+ public_ipv4_pool = (known after apply)
+ tags = {
+ "Name" = "eks-update-strategies-ap-northeast-1a"
}
+ tags_all = {
+ "Name" = "eks-update-strategies-ap-northeast-1a"
}
+ vpc = (known after apply)
}
# module.vpc.aws_internet_gateway.this[0] will be created
+ resource "aws_internet_gateway" "this" {
+ arn = (known after apply)
+ id = (known after apply)
+ owner_id = (known after apply)
+ tags = {
+ "Name" = "eks-update-strategies"
}
+ tags_all = {
+ "Name" = "eks-update-strategies"
}
+ vpc_id = "vpc-055a47ed10fb16322"
}
# module.vpc.aws_nat_gateway.this[0] will be created
+ resource "aws_nat_gateway" "this" {
+ allocation_id = (known after apply)
+ association_id = (known after apply)
+ connectivity_type = "public"
+ id = (known after apply)
+ network_interface_id = (known after apply)
+ private_ip = (known after apply)
+ public_ip = (known after apply)
+ secondary_private_ip_address_count = (known after apply)
+ secondary_private_ip_addresses = (known after apply)
+ subnet_id = (known after apply)
+ tags = {
+ "Name" = "eks-update-strategies-ap-northeast-1a"
}
+ tags_all = {
+ "Name" = "eks-update-strategies-ap-northeast-1a"
}
}
# module.vpc.aws_route.private_nat_gateway[0] will be created
+ resource "aws_route" "private_nat_gateway" {
+ destination_cidr_block = "0.0.0.0/0"
+ id = (known after apply)
+ instance_id = (known after apply)
+ instance_owner_id = (known after apply)
+ nat_gateway_id = (known after apply)
+ network_interface_id = (known after apply)
+ origin = (known after apply)
+ route_table_id = (known after apply)
+ state = (known after apply)
+ timeouts {
+ create = "5m"
}
}
# module.vpc.aws_route.public_internet_gateway[0] will be created
+ resource "aws_route" "public_internet_gateway" {
+ destination_cidr_block = "0.0.0.0/0"
+ gateway_id = (known after apply)
+ id = (known after apply)
+ instance_id = (known after apply)
+ instance_owner_id = (known after apply)
+ network_interface_id = (known after apply)
+ origin = (known after apply)
+ route_table_id = (known after apply)
+ state = (known after apply)
+ timeouts {
+ create = "5m"
}
}
# module.vpc.aws_route_table.private[0] will be created
+ resource "aws_route_table" "private" {
+ arn = (known after apply)
+ id = (known after apply)
+ owner_id = (known after apply)
+ propagating_vgws = (known after apply)
+ route = (known after apply)
+ tags = {
+ "Name" = "eks-update-strategies-private"
}
+ tags_all = {
+ "Name" = "eks-update-strategies-private"
}
+ vpc_id = "vpc-055a47ed10fb16322"
}
# module.vpc.aws_route_table.public[0] will be created
+ resource "aws_route_table" "public" {
+ arn = (known after apply)
+ id = (known after apply)
+ owner_id = (known after apply)
+ propagating_vgws = (known after apply)
+ route = (known after apply)
+ tags = {
+ "Name" = "eks-update-strategies-public"
}
+ tags_all = {
+ "Name" = "eks-update-strategies-public"
}
+ vpc_id = "vpc-055a47ed10fb16322"
}
# module.vpc.aws_route_table_association.private[0] will be created
+ resource "aws_route_table_association" "private" {
+ id = (known after apply)
+ route_table_id = (known after apply)
+ subnet_id = "subnet-042e0423e858cdd60"
}
# module.vpc.aws_route_table_association.private[1] will be created
+ resource "aws_route_table_association" "private" {
+ id = (known after apply)
+ route_table_id = (known after apply)
+ subnet_id = (known after apply)
}
# module.vpc.aws_route_table_association.private[2] will be created
+ resource "aws_route_table_association" "private" {
+ id = (known after apply)
+ route_table_id = (known after apply)
+ subnet_id = "subnet-08ec616502d8e8e94"
}
# module.vpc.aws_route_table_association.public[0] will be created
+ resource "aws_route_table_association" "public" {
+ id = (known after apply)
+ route_table_id = (known after apply)
+ subnet_id = (known after apply)
}
# module.vpc.aws_route_table_association.public[1] will be created
+ resource "aws_route_table_association" "public" {
+ id = (known after apply)
+ route_table_id = (known after apply)
+ subnet_id = "subnet-0623d7ae04c067259"
}
# module.vpc.aws_route_table_association.public[2] will be created
+ resource "aws_route_table_association" "public" {
+ id = (known after apply)
+ route_table_id = (known after apply)
+ subnet_id = (known after apply)
}
# module.vpc.aws_subnet.private[1] will be created
+ resource "aws_subnet" "private" {
+ arn = (known after apply)
+ assign_ipv6_address_on_creation = false
+ availability_zone = "ap-northeast-1c"
+ availability_zone_id = (known after apply)
+ cidr_block = "10.0.2.0/24"
+ enable_dns64 = false
+ enable_resource_name_dns_a_record_on_launch = false
+ enable_resource_name_dns_aaaa_record_on_launch = false
+ id = (known after apply)
+ ipv6_cidr_block_association_id = (known after apply)
+ ipv6_native = false
+ map_public_ip_on_launch = false
+ owner_id = (known after apply)
+ private_dns_hostname_type_on_launch = (known after apply)
+ tags = {
+ "Name" = "eks-update-strategies-private-ap-northeast-1c"
}
+ tags_all = {
+ "Name" = "eks-update-strategies-private-ap-northeast-1c"
}
+ vpc_id = "vpc-055a47ed10fb16322"
}
# module.vpc.aws_subnet.public[0] will be created
+ resource "aws_subnet" "public" {
+ arn = (known after apply)
+ assign_ipv6_address_on_creation = false
+ availability_zone = "ap-northeast-1a"
+ availability_zone_id = (known after apply)
+ cidr_block = "10.0.101.0/24"
+ enable_dns64 = false
+ enable_resource_name_dns_a_record_on_launch = false
+ enable_resource_name_dns_aaaa_record_on_launch = false
+ id = (known after apply)
+ ipv6_cidr_block_association_id = (known after apply)
+ ipv6_native = false
+ map_public_ip_on_launch = false
+ owner_id = (known after apply)
+ private_dns_hostname_type_on_launch = (known after apply)
+ tags = {
+ "Name" = "eks-update-strategies-public-ap-northeast-1a"
+ "kubernetes.io/role/elb" = "1"
}
+ tags_all = {
+ "Name" = "eks-update-strategies-public-ap-northeast-1a"
+ "kubernetes.io/role/elb" = "1"
}
+ vpc_id = "vpc-055a47ed10fb16322"
}
# module.vpc.aws_subnet.public[2] will be created
+ resource "aws_subnet" "public" {
+ arn = (known after apply)
+ assign_ipv6_address_on_creation = false
+ availability_zone = "ap-northeast-1d"
+ availability_zone_id = (known after apply)
+ cidr_block = "10.0.103.0/24"
+ enable_dns64 = false
+ enable_resource_name_dns_a_record_on_launch = false
+ enable_resource_name_dns_aaaa_record_on_launch = false
+ id = (known after apply)
+ ipv6_cidr_block_association_id = (known after apply)
+ ipv6_native = false
+ map_public_ip_on_launch = false
+ owner_id = (known after apply)
+ private_dns_hostname_type_on_launch = (known after apply)
+ tags = {
+ "Name" = "eks-update-strategies-public-ap-northeast-1d"
+ "kubernetes.io/role/elb" = "1"
}
+ tags_all = {
+ "Name" = "eks-update-strategies-public-ap-northeast-1d"
+ "kubernetes.io/role/elb" = "1"
}
+ vpc_id = "vpc-055a47ed10fb16322"
}
# module.vpc.aws_vpn_gateway.this[0] will be created
+ resource "aws_vpn_gateway" "this" {
+ amazon_side_asn = "64512"
+ arn = (known after apply)
+ id = (known after apply)
+ tags = {
+ "Name" = "eks-update-strategies"
}
+ tags_all = {
+ "Name" = "eks-update-strategies"
}
+ vpc_id = "vpc-055a47ed10fb16322"
}
# module.eks.module.kms.data.aws_iam_policy_document.this[0] will be read during apply
# (config refers to values not yet known)
<= data "aws_iam_policy_document" "this" {
+ id = (known after apply)
+ json = (known after apply)
+ minified_json = (known after apply)
+ override_policy_documents = []
+ source_policy_documents = []
+ statement {
+ actions = [
+ "kms:*",
]
+ resources = [
+ "*",
]
+ sid = "Default"
+ principals {
+ identifiers = [
+ "arn:aws:iam::123456789012:root",
]
+ type = "AWS"
}
}
+ statement {
+ actions = [
+ "kms:CancelKeyDeletion",
+ "kms:Create*",
+ "kms:Delete*",
+ "kms:Describe*",
+ "kms:Disable*",
+ "kms:Enable*",
+ "kms:Get*",
+ "kms:ImportKeyMaterial",
+ "kms:List*",
+ "kms:Put*",
+ "kms:ReplicateKey",
+ "kms:Revoke*",
+ "kms:ScheduleKeyDeletion",
+ "kms:TagResource",
+ "kms:UntagResource",
+ "kms:Update*",
]
+ resources = [
+ "*",
]
+ sid = "KeyAdministration"
+ principals {
+ identifiers = [
+ "arn:aws:iam::123456789012:role/tfc-role",
]
+ type = "AWS"
}
}
+ statement {
+ actions = [
+ "kms:Decrypt",
+ "kms:DescribeKey",
+ "kms:Encrypt",
+ "kms:GenerateDataKey*",
+ "kms:ReEncrypt*",
]
+ resources = [
+ "*",
]
+ sid = "KeyUsage"
+ principals {
+ identifiers = [
+ (known after apply),
]
+ type = "AWS"
}
}
}
# module.eks.module.kms.aws_kms_alias.this["cluster"] will be created
+ resource "aws_kms_alias" "this" {
+ arn = (known after apply)
+ id = (known after apply)
+ name = "alias/eks/eks-auto-mode"
+ name_prefix = (known after apply)
+ target_key_arn = (known after apply)
+ target_key_id = (known after apply)
}
# module.eks.module.kms.aws_kms_key.this[0] will be created
+ resource "aws_kms_key" "this" {
+ arn = (known after apply)
+ bypass_policy_lockout_safety_check = false
+ customer_master_key_spec = "SYMMETRIC_DEFAULT"
+ description = "eks-auto-mode cluster encryption key"
+ enable_key_rotation = true
+ id = (known after apply)
+ is_enabled = true
+ key_id = (known after apply)
+ key_usage = "ENCRYPT_DECRYPT"
+ multi_region = false
+ policy = (known after apply)
+ rotation_period_in_days = (known after apply)
+ tags = {
+ "terraform-aws-modules" = "eks"
}
+ tags_all = {
+ "terraform-aws-modules" = "eks"
}
}
Plan: 54 to add, 0 to change, 0 to destroy.
続いて Terraform Plan Analyzer の RunTask が起動します。Plan-Summary と AMI-Summary の 2 種類があり、今回は Plan-Summary が起動していました。
出力結果は以下になります。かなり長くなっていた Terraform Plan の結果が端的に要約されているように思えます。
Based on the provided Terraform plan, the following infrastructure changes will occur:
Summary:
- The plan will create a new Amazon Elastic Kubernetes Service (EKS) cluster named "eks-auto-mode" with version 1.32.
- It will also provision the necessary networking resources (VPC, subnets, internet gateway, NAT gateway, etc.) for the EKS cluster.
Additionally, it will create an AWS Key Management Service (KMS) key for encrypting the EKS cluster resources.
Major Components:
- The primary Terraform module being executed is the "eks" module from the "terraform-aws-modules/eks/aws" source.
- The "vpc" module from the "terraform-aws-modules/vpc/aws" source is also being used to create the necessary networking resources.
- The "kms" submodule within the "eks" module is responsible for creating the KMS key and its related resources.
Terraform Module Details:
- The "eks" module is responsible for creating the EKS cluster, worker node groups, security groups, IAM roles, and other related resources.
- The "vpc" module creates a new VPC, subnets (public and private), internet gateway, NAT gateway, route tables, and other networking components.
- The "kms" submodule creates a KMS key for encrypting the EKS cluster resources and an alias for the key.
Resources Being Replaced or Deleted:
- No resources are being replaced or deleted in this plan.
Outputs:
- The plan does not include any outputs.
It's important to note that this plan is creating a new EKS cluster and the necessary supporting infrastructure from scratch. No existing resources are being modified or deleted.
まとめ
以上、「Terraform Plan Analyzer を利用して Terraform Plan の内容を要約してみた」でした。Run Task の API サーバーは非常にサーバレスな構成となっており、API の実行回数レベルでの課金であるため、 HCP Terraform を利用されている方であれば、非常に導入障壁が少ない Run Task なのではないかと感じました。
このブログがどなたかの参考になれば幸いです。クラウド事業本部コンサルティング部のたかくに(@takakuni_)でした!