こんにちは、末廣です。
前回のブログでは CodeBuild のコンピューティングで Lambda を使用して実行したものを紹介しました。
本ブログでは同様に Lambda コンピューティングを使用して、アップデートにて追加されたカスタムイメージを使用したビルドの実行を検証したのでまとめていきます。
前置き
上記ブログでは実行環境には AWS CodeBuild によって管理されたイメージを使用(ランタイムに Java、イメージに Coretto21) していました。
ランタイムの選択は以下図の中からのみ可能であり、Lambda コンピューティングには yum
や docker build
が使えないなど制約があったため、コンピューティングが EC2 や Docker のときよりも自由度が低い状態でした。
Lambda コンピューティングの利点、制約やそれぞれ言語ごとの速度比較等は弊社山本のブログで紹介されております。
このような制約があった中、2024年3月のアップデートにて Lambda コンピューティング用のカスタムイメージをサポートするようになりました。
Amazon ECR リポジトリに保存されているコンテナイメージを使うことで、 Java、Python、Node.js 以外の言語や AWS CLI、AWS SAM CLI などのランタイムが実行可能となっています。
検証
コンテナイメージがあれば実行できるため、今回検証として Terraform をビルドしてみました。
構成
検証した構成は
- ソース:CodeCommit(main.tf)
- ビルド:CodeBuild(terraform apply)
- アーティファクト:S3(tfstate)
となっています。
実際の Terraform の使い方としては CI/CD パイプラインの作成等を行うと思いますのでドキュメントをご参考ください。
CodeBuild プロジェクトの作成
では実際にカスタムイメージを選択したプロジェクトを作っていきます。
環境イメージにカスタムイメージ、コンピューティングに Lambda、環境タイプに Linux Lambda を選択しています。
ECR イメージは、自身のアカウント内、または別のアカウントにあるものを使用できます。
ECR イメージの URI には ECR Public Gallery から選ぶこともできましたので、Terraform の公式イメージを入力しました。
アタッチするロールには terraform apply
で作成するリソースの権限を付与します。
CodeCommit ソース
Terraform ソースコード
HashiCorp 社公式のソースを利用して簡単な VPC とサブネットを作成します。
※6・14行目にてtags
の記載方法に =
が抜けているので追記しています。
main.tf
provider "aws" { region = "${var.region}" } resource "aws_vpc" "demo_vpc" { cidr_block = "${var.vpc_cidr_block}" tags = { Name = "fp_demo_vpc" } } resource "aws_subnet" "demo_subnet" { vpc_id = "${aws_vpc.demo_vpc.id}" cidr_block = "${var.subnet_cidr_block}" availability_zone = "${var.subnet_availability_zone}" tags = { Name = "fp_demo_subnet" } }
ビルド仕様ファイル
ビルドの流れとしては以下のようになります。
- ビルド前セクション:Terraform のバージョン確認、ワークディレクトリの初期化
- ビルドセクション:デプロイを実施
- ビルドアーティファクト:tfstate ファイルを S3 へ保存
terraform apply
はオプションを付けないと yes
を入力する必要があるため、-auto-approve
を付与します。
buildspec.yml
version: 0.2 phases: pre_build: on-failure: ABORT commands: - terraform --version - cd ./getting-started/terraform-aws - terraform init build: commands: - terraform plan - terraform apply -auto-approve artifacts: files: - getting-started/terraform-aws/terraform.tfstate
ビルド実行
マネジメントコンソールからビルドを実行し、ログを見てみます。 少々長いので以下クリックで展開ください。
[Container] 2024/04/08 01:45:31.644248 YAML location is /tmp/codebuild/output/src135/src/git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/terraform-trial/buildspec.yml [Container] 2024/04/08 01:45:31.644540 Processing environment variables [Container] 2024/04/08 01:45:31.651087 Moving to directory /tmp/codebuild/output/src135/src/git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/terraform-trial [Container] 2024/04/08 01:45:31.801840 Running command terraform --version Terraform v1.7.5 on linux_amd64 [Container] 2024/04/08 01:45:31.838213 Running command cd ./getting-started/terraform-aws [Container] 2024/04/08 01:45:31.841618 Running command terraform init Initializing the backend... Initializing provider plugins... - Finding latest version of hashicorp/aws... - Installing hashicorp/aws v5.44.0... - Installed hashicorp/aws v5.44.0 (signed by HashiCorp) Terraform has created a lock file .terraform.lock.hcl to record the provider selections it made above. Include this file in your version control repository so that Terraform can guarantee to make the same selections by default when you run "terraform init" in the future. Terraform has been successfully initialized! You may now begin working with Terraform. Try running "terraform plan" to see any changes that are required for your infrastructure. All Terraform commands should now work. If you ever set or change modules or backend configuration for Terraform, rerun this command to reinitialize your working directory. If you forget, other commands will detect it and remind you to do so if necessary. [Container] 2024/04/08 01:45:36.511600 Running command terraform plan Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # aws_subnet.demo_subnet will be created + resource "aws_subnet" "demo_subnet" { + 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.0.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" = "fp_demo_subnet" } + tags_all = { + "Name" = "fp_demo_subnet" } + vpc_id = (known after apply) } # aws_vpc.demo_vpc will be created + resource "aws_vpc" "demo_vpc" { + arn = (known after apply) + cidr_block = "10.0.0.0/16" + default_network_acl_id = (known after apply) + default_route_table_id = (known after apply) + default_security_group_id = (known after apply) + dhcp_options_id = (known after apply) + enable_dns_hostnames = (known after apply) + enable_dns_support = true + enable_network_address_usage_metrics = (known after apply) + id = (known after apply) + instance_tenancy = "default" + ipv6_association_id = (known after apply) + ipv6_cidr_block = (known after apply) + ipv6_cidr_block_network_border_group = (known after apply) + main_route_table_id = (known after apply) + owner_id = (known after apply) + tags = { + "Name" = "fp_demo_vpc" } + tags_all = { + "Name" = "fp_demo_vpc" } } Plan: 2 to add, 0 to change, 0 to destroy. Changes to Outputs: + demo_subnet_id = (known after apply) + vpc_id_consumable = (known after apply) ───────────────────────────────────────────────────────────────────────────── Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now. [Container] 2024/04/08 01:45:40.416522 Running command terraform apply -auto-approve Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # aws_subnet.demo_subnet will be created + resource "aws_subnet" "demo_subnet" { + 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.0.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" = "fp_demo_subnet" } + tags_all = { + "Name" = "fp_demo_subnet" } + vpc_id = (known after apply) } # aws_vpc.demo_vpc will be created + resource "aws_vpc" "demo_vpc" { + arn = (known after apply) + cidr_block = "10.0.0.0/16" + default_network_acl_id = (known after apply) + default_route_table_id = (known after apply) + default_security_group_id = (known after apply) + dhcp_options_id = (known after apply) + enable_dns_hostnames = (known after apply) + enable_dns_support = true + enable_network_address_usage_metrics = (known after apply) + id = (known after apply) + instance_tenancy = "default" + ipv6_association_id = (known after apply) + ipv6_cidr_block = (known after apply) + ipv6_cidr_block_network_border_group = (known after apply) + main_route_table_id = (known after apply) + owner_id = (known after apply) + tags = { + "Name" = "fp_demo_vpc" } + tags_all = { + "Name" = "fp_demo_vpc" } } Plan: 2 to add, 0 to change, 0 to destroy. Changes to Outputs: + demo_subnet_id = (known after apply) + vpc_id_consumable = (known after apply) aws_vpc.demo_vpc: Creating... aws_vpc.demo_vpc: Creation complete after 1s [id=vpc-008e918ad3b7b99d0] aws_subnet.demo_subnet: Creating... aws_subnet.demo_subnet: Creation complete after 0s [id=subnet-0a80ca6cd7a54de2d] Apply complete! Resources: 2 added, 0 changed, 0 destroyed. Outputs: demo_subnet_id = "subnet-0a80ca6cd7a54de2d" vpc_id_consumable = "vpc-008e918ad3b7b99d0"
コンソールからも無事リソースが確認でき、アーティファクトも出力されています。
当然ですが、生成された tfstate ファイルを含めずにもう一度ビルドを実行すると全く同じリソースが作成されるため、ビルドソースに tfstate を含めた状態でビルドする必要があります。 以下ビルドソースに tfstate を含め、再度ビルドを実行したログとなります。
[Container] 2024/04/08 05:51:43.577940 Running command terraform plan aws_vpc.demo_vpc: Refreshing state... [id=vpc-008e918ad3b7b99d0] aws_subnet.demo_subnet: Refreshing state... [id=subnet-0a80ca6cd7a54de2d] No changes. Your infrastructure matches the configuration. Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.
おまけ:タイムアウトさせてみよう
ここまで問題なく Terraform によるビルド、リソースの作成が行えましたが、CodeBuild の Lambda コンピューティングは制約として 15分を超えた処理を行うことができません。
AWS Lambda は、キャッシュ、バッチビルド、カスタムビルドのタイムアウト、キューのタイムアウト、ビルドバッジ、特権モード、カスタムランタイム環境、または 15 分を超えるランタイムをサポートしていません。
つまり Terraform で作成に時間のかかるリソースを作成しようとした場合途中で停止してしまうわけです。 今回はあえてタイムアウトするようなリソースを作成し、問題を発生させてみます。
作成するリソース
作成に時間のかかるリソースということで、FSx を作成してみます。 同時に Managed Microsoft AD も構築されるため、15分以上はかかると想定しています。
Terraform のモジュールとして FSx が用意されていますのでこちらを使っていきます。
ビルド仕様ファイル
buildspec.yml は以下の様にディレクトリの指定を行います。
version: 0.2 phases: pre_build: on-failure: ABORT commands: - terraform --version - cd ./terraform-aws-fsx/examples/windows - terraform init build: commands: # - terraform plan - terraform apply -auto-approve artifacts: files: - terraform-aws-fsx/examples/windows/terraform.tfstate
ビルド実行
ログを確認すると、Still creating… で終了してしましました。
[Container] 2024/04/10 06:20:36.942197 YAML location is /tmp/codebuild/output/src2005/src/git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/terraform-trial/buildspec.yml [Container] 2024/04/10 06:20:36.942524 Processing environment variables [Container] 2024/04/10 06:20:36.949186 Moving to directory /tmp/codebuild/output/src2005/src/git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/terraform-trial [Container] 2024/04/10 06:20:37.073792 Running command terraform --version Terraform v1.7.5 on linux_amd64 [Container] 2024/04/10 06:20:37.267720 Running command cd ./terraform-aws-fsx/examples/windows [Container] 2024/04/10 06:20:37.271309 Running command terraform init Initializing the backend... Initializing modules... - fsx_windows in ../../modules/windows - fsx_windows_disabled in ../../modules/windows Downloading registry.terraform.io/terraform-aws-modules/vpc/aws 5.7.1 for vpc... - vpc in .terraform/modules/vpc Initializing provider plugins... - Finding hashicorp/aws versions matching ">= 5.30.0, >= 5.34.0"... - Installing hashicorp/aws v5.44.0... - Installed hashicorp/aws v5.44.0 (signed by HashiCorp) Terraform has created a lock file .terraform.lock.hcl to record the provider selections it made above. Include this file in your version control repository so that Terraform can guarantee to make the same selections by default when you run "terraform init" in the future. Terraform has been successfully initialized! You may now begin working with Terraform. Try running "terraform plan" to see any changes that are required for your infrastructure. All Terraform commands should now work. If you ever set or change modules or backend configuration for Terraform, rerun this command to reinitialize your working directory. If you forget, other commands will detect it and remind you to do so if necessary. [Container] 2024/04/10 06:20:43.795292 Running command terraform apply -auto-approve data.aws_availability_zones.available: Reading... data.aws_availability_zones.available: Read complete after 1s [id=eu-west-1] 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: # aws_directory_service_directory.this will be created + resource "aws_directory_service_directory" "this" { + access_url = (known after apply) + alias = (known after apply) + desired_number_of_domain_controllers = (known after apply) + dns_ip_addresses = (known after apply) + edition = "Standard" + enable_sso = false + id = (known after apply) + name = "corp.notexample.com" + password = (sensitive value) + security_group_id = (known after apply) + short_name = (known after apply) + size = (known after apply) + tags = { + "Example" = "ex-fsx-windows" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } + tags_all = { + "Example" = "ex-fsx-windows" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } + type = "MicrosoftAD" + vpc_settings { + availability_zones = (known after apply) + subnet_ids = (known after apply) + vpc_id = (known after apply) } } # module.fsx_windows.data.aws_subnet.this[0] will be read during apply # (config refers to values not yet known) <= data "aws_subnet" "this" { + arn = (known after apply) + assign_ipv6_address_on_creation = (known after apply) + availability_zone = (known after apply) + availability_zone_id = (known after apply) + available_ip_address_count = (known after apply) + cidr_block = (known after apply) + customer_owned_ipv4_pool = (known after apply) + default_for_az = (known after apply) + enable_dns64 = (known after apply) + enable_lni_at_device_index = (known after apply) + enable_resource_name_dns_a_record_on_launch = (known after apply) + enable_resource_name_dns_aaaa_record_on_launch = (known after apply) + id = (known after apply) + ipv6_cidr_block = (known after apply) + ipv6_cidr_block_association_id = (known after apply) + ipv6_native = (known after apply) + map_customer_owned_ip_on_launch = (known after apply) + map_public_ip_on_launch = (known after apply) + outpost_arn = (known after apply) + owner_id = (known after apply) + private_dns_hostname_type_on_launch = (known after apply) + state = (known after apply) + tags = (known after apply) + vpc_id = (known after apply) } # module.fsx_windows.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 = (known after apply) + name_prefix = "/aws/fsx/ex-fsx-windows-" + retention_in_days = 90 + skip_destroy = false + tags = { + "Example" = "ex-fsx-windows" + "Name" = "/aws/fsx/ex-fsx-windows" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } + tags_all = { + "Example" = "ex-fsx-windows" + "Name" = "/aws/fsx/ex-fsx-windows" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } } # module.fsx_windows.aws_fsx_windows_file_system.this[0] will be created + resource "aws_fsx_windows_file_system" "this" { + active_directory_id = (known after apply) + aliases = [ + "filesystem1.example.com", ] + arn = (known after apply) + automatic_backup_retention_days = 7 + copy_tags_to_backups = true + daily_automatic_backup_start_time = "05:00" + deployment_type = "MULTI_AZ_1" + dns_name = (known after apply) + id = (known after apply) + kms_key_id = (known after apply) + network_interface_ids = (known after apply) + owner_id = (known after apply) + preferred_file_server_ip = (known after apply) + preferred_subnet_id = (known after apply) + remote_administration_endpoint = (known after apply) + security_group_ids = (known after apply) + skip_final_backup = true + storage_capacity = 1024 + storage_type = "SSD" + subnet_ids = (known after apply) + tags = { + "Example" = "ex-fsx-windows" + "Name" = "ex-fsx-windows" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" + "terraform-aws-modules" = "fsx" } + tags_all = { + "Example" = "ex-fsx-windows" + "Name" = "ex-fsx-windows" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" + "terraform-aws-modules" = "fsx" } + throughput_capacity = 512 + vpc_id = (known after apply) + weekly_maintenance_start_time = "1:06:00" + audit_log_configuration { + audit_log_destination = (known after apply) + file_access_audit_log_level = "SUCCESS_AND_FAILURE" + file_share_access_audit_log_level = "SUCCESS_AND_FAILURE" } + disk_iops_configuration { + iops = 3072 + mode = "USER_PROVISIONED" } + timeouts {} } # module.fsx_windows.aws_security_group.this[0] will be created + resource "aws_security_group" "this" { + arn = (known after apply) + description = "Managed by Terraform" + egress = (known after apply) + id = (known after apply) + ingress = (known after apply) + name = (known after apply) + name_prefix = "ex-fsx-windows-" + owner_id = (known after apply) + revoke_rules_on_delete = false + tags = { + "Example" = "ex-fsx-windows" + "Name" = "ex-fsx-windows" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } + tags_all = { + "Example" = "ex-fsx-windows" + "Name" = "ex-fsx-windows" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } + vpc_id = (known after apply) } # module.fsx_windows.aws_vpc_security_group_egress_rule.this["ipv4"] will be created + resource "aws_vpc_security_group_egress_rule" "this" { + arn = (known after apply) + cidr_ipv4 = "0.0.0.0/0" + description = "Allow all outbound traffic by default" + id = (known after apply) + ip_protocol = "-1" + security_group_id = (known after apply) + security_group_rule_id = (known after apply) + tags = { + "Example" = "ex-fsx-windows" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } + tags_all = { + "Example" = "ex-fsx-windows" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } } # module.fsx_windows.aws_vpc_security_group_egress_rule.this["ipv6"] will be created + resource "aws_vpc_security_group_egress_rule" "this" { + arn = (known after apply) + cidr_ipv6 = "::/0" + description = "Allow all outbound traffic by default" + id = (known after apply) + ip_protocol = "-1" + security_group_id = (known after apply) + security_group_rule_id = (known after apply) + tags = { + "Example" = "ex-fsx-windows" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } + tags_all = { + "Example" = "ex-fsx-windows" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } } # module.fsx_windows.aws_vpc_security_group_ingress_rule.this["in"] will be created + resource "aws_vpc_security_group_ingress_rule" "this" { + arn = (known after apply) + cidr_ipv4 = "10.0.0.0/16" + description = "Allow all traffic from the VPC" + from_port = 0 + id = (known after apply) + ip_protocol = "tcp" + security_group_id = (known after apply) + security_group_rule_id = (known after apply) + tags = { + "Example" = "ex-fsx-windows" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } + tags_all = { + "Example" = "ex-fsx-windows" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } + to_port = 0 } # 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 = (known after apply) + id = (known after apply) + owner_id = (known after apply) + tags = { + "Example" = "ex-fsx-windows" + "Name" = "ex-fsx-windows-default" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } + tags_all = { + "Example" = "ex-fsx-windows" + "Name" = "ex-fsx-windows-default" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } + vpc_id = (known after apply) + egress { + action = "allow" + from_port = 0 + ipv6_cidr_block = "::/0" + protocol = "-1" + rule_no = 101 + to_port = 0 } + egress { + action = "allow" + cidr_block = "0.0.0.0/0" + from_port = 0 + protocol = "-1" + rule_no = 100 + to_port = 0 } + ingress { + action = "allow" + from_port = 0 + ipv6_cidr_block = "::/0" + protocol = "-1" + rule_no = 101 + to_port = 0 } + ingress { + action = "allow" + cidr_block = "0.0.0.0/0" + from_port = 0 + protocol = "-1" + rule_no = 100 + to_port = 0 } } # 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 = (known after apply) + id = (known after apply) + owner_id = (known after apply) + route = (known after apply) + tags = { + "Example" = "ex-fsx-windows" + "Name" = "ex-fsx-windows-default" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } + tags_all = { + "Example" = "ex-fsx-windows" + "Name" = "ex-fsx-windows-default" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } + 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 = { + "Example" = "ex-fsx-windows" + "Name" = "ex-fsx-windows-default" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } + tags_all = { + "Example" = "ex-fsx-windows" + "Name" = "ex-fsx-windows-default" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } + vpc_id = (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 = { + "Example" = "ex-fsx-windows" + "Name" = "ex-fsx-windows" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } + tags_all = { + "Example" = "ex-fsx-windows" + "Name" = "ex-fsx-windows" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } + vpc_id = (known after apply) } # 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 = { + "Example" = "ex-fsx-windows" + "Name" = "ex-fsx-windows-private-eu-west-1a" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } + tags_all = { + "Example" = "ex-fsx-windows" + "Name" = "ex-fsx-windows-private-eu-west-1a" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } + vpc_id = (known after apply) } # module.vpc.aws_route_table.private[1] 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 = { + "Example" = "ex-fsx-windows" + "Name" = "ex-fsx-windows-private-eu-west-1b" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } + tags_all = { + "Example" = "ex-fsx-windows" + "Name" = "ex-fsx-windows-private-eu-west-1b" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } + vpc_id = (known after apply) } # module.vpc.aws_route_table.private[2] 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 = { + "Example" = "ex-fsx-windows" + "Name" = "ex-fsx-windows-private-eu-west-1c" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } + tags_all = { + "Example" = "ex-fsx-windows" + "Name" = "ex-fsx-windows-private-eu-west-1c" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } + vpc_id = (known after apply) } # 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 = { + "Example" = "ex-fsx-windows" + "Name" = "ex-fsx-windows-public" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } + tags_all = { + "Example" = "ex-fsx-windows" + "Name" = "ex-fsx-windows-public" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } + vpc_id = (known after apply) } # 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 = (known after apply) } # 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 = (known after apply) } # 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 = (known after apply) } # 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[0] will be created + resource "aws_subnet" "private" { + arn = (known after apply) + assign_ipv6_address_on_creation = false + availability_zone = "eu-west-1a" + availability_zone_id = (known after apply) + cidr_block = "10.0.10.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 = { + "Example" = "ex-fsx-windows" + "Name" = "ex-fsx-windows-private-eu-west-1a" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } + tags_all = { + "Example" = "ex-fsx-windows" + "Name" = "ex-fsx-windows-private-eu-west-1a" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } + vpc_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 = "eu-west-1b" + availability_zone_id = (known after apply) + cidr_block = "10.0.11.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 = { + "Example" = "ex-fsx-windows" + "Name" = "ex-fsx-windows-private-eu-west-1b" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } + tags_all = { + "Example" = "ex-fsx-windows" + "Name" = "ex-fsx-windows-private-eu-west-1b" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } + vpc_id = (known after apply) } # module.vpc.aws_subnet.private[2] will be created + resource "aws_subnet" "private" { + arn = (known after apply) + assign_ipv6_address_on_creation = false + availability_zone = "eu-west-1c" + availability_zone_id = (known after apply) + cidr_block = "10.0.12.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 = { + "Example" = "ex-fsx-windows" + "Name" = "ex-fsx-windows-private-eu-west-1c" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } + tags_all = { + "Example" = "ex-fsx-windows" + "Name" = "ex-fsx-windows-private-eu-west-1c" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } + vpc_id = (known after apply) } # 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 = "eu-west-1a" + availability_zone_id = (known after apply) + cidr_block = "10.0.0.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 = { + "Example" = "ex-fsx-windows" + "Name" = "ex-fsx-windows-public-eu-west-1a" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } + tags_all = { + "Example" = "ex-fsx-windows" + "Name" = "ex-fsx-windows-public-eu-west-1a" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } + vpc_id = (known after apply) } # module.vpc.aws_subnet.public[1] will be created + resource "aws_subnet" "public" { + arn = (known after apply) + assign_ipv6_address_on_creation = false + availability_zone = "eu-west-1b" + availability_zone_id = (known after apply) + cidr_block = "10.0.1.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 = { + "Example" = "ex-fsx-windows" + "Name" = "ex-fsx-windows-public-eu-west-1b" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } + tags_all = { + "Example" = "ex-fsx-windows" + "Name" = "ex-fsx-windows-public-eu-west-1b" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } + vpc_id = (known after apply) } # 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 = "eu-west-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 = { + "Example" = "ex-fsx-windows" + "Name" = "ex-fsx-windows-public-eu-west-1c" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } + tags_all = { + "Example" = "ex-fsx-windows" + "Name" = "ex-fsx-windows-public-eu-west-1c" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } + vpc_id = (known after apply) } # module.vpc.aws_vpc.this[0] will be created + resource "aws_vpc" "this" { + arn = (known after apply) + cidr_block = "10.0.0.0/16" + default_network_acl_id = (known after apply) + default_route_table_id = (known after apply) + default_security_group_id = (known after apply) + dhcp_options_id = (known after apply) + enable_dns_hostnames = true + enable_dns_support = true + enable_network_address_usage_metrics = (known after apply) + id = (known after apply) + instance_tenancy = "default" + ipv6_association_id = (known after apply) + ipv6_cidr_block = (known after apply) + ipv6_cidr_block_network_border_group = (known after apply) + main_route_table_id = (known after apply) + owner_id = (known after apply) + tags = { + "Example" = "ex-fsx-windows" + "Name" = "ex-fsx-windows" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } + tags_all = { + "Example" = "ex-fsx-windows" + "Name" = "ex-fsx-windows" + "Repository" = "https://github.com/terraform-aws-modules/terraform-aws-fsx" } } Plan: 29 to add, 0 to change, 0 to destroy. Changes to Outputs: + cloudwatch_log_group_arn = (known after apply) + cloudwatch_log_group_name = (known after apply) + file_system_arn = (known after apply) + file_system_dns_name = (known after apply) + file_system_id = (known after apply) + file_system_network_interface_ids = (known after apply) + file_system_preferred_file_server_ip = (known after apply) + file_system_remote_administration_endpoint = (known after apply) + security_group_arn = (known after apply) + security_group_id = (known after apply) module.fsx_windows.aws_cloudwatch_log_group.this[0]: Creating... module.vpc.aws_vpc.this[0]: Creating... module.vpc.aws_vpc.this[0]: Still creating... [10s elapsed] module.vpc.aws_vpc.this[0]: Creation complete after 14s [id=vpc-004e5139440c732ce] module.vpc.aws_default_route_table.default[0]: Creating... module.vpc.aws_default_security_group.this[0]: Creating... module.vpc.aws_route_table.private[1]: Creating... module.vpc.aws_subnet.public[2]: Creating... module.vpc.aws_route_table.private[2]: Creating... module.vpc.aws_route_table.public[0]: Creating... module.vpc.aws_internet_gateway.this[0]: Creating... module.vpc.aws_subnet.private[2]: Creating... module.vpc.aws_default_network_acl.this[0]: Creating... module.vpc.aws_route_table.private[0]: Creating... module.vpc.aws_default_route_table.default[0]: Creation complete after 2s [id=rtb-0c489d9e300d92f6d] module.vpc.aws_subnet.public[0]: Creating... module.vpc.aws_internet_gateway.this[0]: Creation complete after 2s [id=igw-06cf14f5148ab2fba] module.vpc.aws_subnet.public[1]: Creating... module.vpc.aws_route_table.private[2]: Creation complete after 2s [id=rtb-0bcd9fca253f6b2e6] module.vpc.aws_subnet.private[1]: Creating... module.vpc.aws_subnet.public[2]: Creation complete after 2s [id=subnet-09f3751fdaf32c7c4] module.vpc.aws_subnet.private[0]: Creating... module.vpc.aws_subnet.private[2]: Creation complete after 2s [id=subnet-07f4c5ee5c33bedc0] module.vpc.aws_route_table.private[1]: Creation complete after 2s [id=rtb-0d44afdf2ed5af3ba] module.vpc.aws_route_table.private[0]: Creation complete after 2s [id=rtb-072a5bb94f1af844d] module.vpc.aws_route_table.public[0]: Creation complete after 2s [id=rtb-045d2f28308a891d0] module.vpc.aws_route.public_internet_gateway[0]: Creating... module.vpc.aws_subnet.public[0]: Creation complete after 1s [id=subnet-0065c8dc6e62fc931] module.vpc.aws_subnet.public[1]: Creation complete after 1s [id=subnet-0d2273cfad22b73ab] module.vpc.aws_route_table_association.public[2]: Creating... module.vpc.aws_route_table_association.public[1]: Creating... module.vpc.aws_subnet.private[1]: Creation complete after 1s [id=subnet-0e2b9ae8d94de3f09] module.vpc.aws_route_table_association.public[0]: Creating... module.vpc.aws_subnet.private[0]: Creation complete after 1s [id=subnet-0715acf42fa934da1] module.vpc.aws_route_table_association.private[2]: Creating... module.vpc.aws_route_table_association.private[0]: Creating... module.vpc.aws_route_table_association.private[1]: Creating... aws_directory_service_directory.this: Creating... module.vpc.aws_default_security_group.this[0]: Creation complete after 3s [id=sg-00088e92ba9c15cf6] module.fsx_windows.data.aws_subnet.this[0]: Reading... module.vpc.aws_default_network_acl.this[0]: Creation complete after 4s [id=acl-08124b7b46ac5b2d9] module.vpc.aws_route.public_internet_gateway[0]: Creation complete after 2s [id=r-rtb-045d2f28308a891d01080289494] module.fsx_windows.data.aws_subnet.this[0]: Read complete after 1s [id=subnet-0715acf42fa934da1] module.fsx_windows.aws_security_group.this[0]: Creating... module.vpc.aws_route_table_association.public[2]: Creation complete after 1s [id=rtbassoc-02c97863ab5903ba5] module.vpc.aws_route_table_association.public[1]: Creation complete after 1s [id=rtbassoc-0570dec546ba8bdf8] module.vpc.aws_route_table_association.public[0]: Creation complete after 1s [id=rtbassoc-0db6b52185d464922] module.vpc.aws_route_table_association.private[2]: Creation complete after 1s [id=rtbassoc-04cf348857ce0e2ef] module.vpc.aws_route_table_association.private[1]: Creation complete after 1s [id=rtbassoc-0a001e153ef60dac8] module.vpc.aws_route_table_association.private[0]: Creation complete after 1s [id=rtbassoc-0a2b50ff984f34450] module.fsx_windows.aws_security_group.this[0]: Creation complete after 3s [id=sg-0345f2901c16beff5] module.fsx_windows.aws_vpc_security_group_egress_rule.this["ipv6"]: Creating... module.fsx_windows.aws_vpc_security_group_ingress_rule.this["in"]: Creating... module.fsx_windows.aws_vpc_security_group_egress_rule.this["ipv4"]: Creating... module.fsx_windows.aws_vpc_security_group_ingress_rule.this["in"]: Creation complete after 1s [id=sgr-04f6c9c20bf038251] module.fsx_windows.aws_vpc_security_group_egress_rule.this["ipv4"]: Creation complete after 1s [id=sgr-0d4340527fa1e7799] module.fsx_windows.aws_vpc_security_group_egress_rule.this["ipv6"]: Creation complete after 1s [id=sgr-0c936787e9f3ae7e3] aws_directory_service_directory.this: Still creating... [10s elapsed] aws_directory_service_directory.this: Still creating... [20s elapsed] aws_directory_service_directory.this: Still creating... [30s elapsed] aws_directory_service_directory.this: Still creating... [40s elapsed] aws_directory_service_directory.this: Still creating... [50s elapsed] aws_directory_service_directory.this: Still creating... [1m0s elapsed] aws_directory_service_directory.this: Still creating... [1m10s elapsed] aws_directory_service_directory.this: Still creating... [1m20s elapsed] aws_directory_service_directory.this: Still creating... [1m30s elapsed] aws_directory_service_directory.this: Still creating... [1m40s elapsed] aws_directory_service_directory.this: Still creating... [1m50s elapsed] aws_directory_service_directory.this: Still creating... [2m0s elapsed] aws_directory_service_directory.this: Still creating... [2m10s elapsed] aws_directory_service_directory.this: Still creating... [2m20s elapsed] aws_directory_service_directory.this: Still creating... [2m30s elapsed] aws_directory_service_directory.this: Still creating... [2m40s elapsed] aws_directory_service_directory.this: Still creating... [2m50s elapsed] aws_directory_service_directory.this: Still creating... [3m0s elapsed] aws_directory_service_directory.this: Still creating... [3m10s elapsed] aws_directory_service_directory.this: Still creating... [3m20s elapsed] aws_directory_service_directory.this: Still creating... [3m30s elapsed] aws_directory_service_directory.this: Still creating... [3m40s elapsed] aws_directory_service_directory.this: Still creating... [3m50s elapsed] aws_directory_service_directory.this: Still creating... [4m0s elapsed] aws_directory_service_directory.this: Still creating... [4m10s elapsed] aws_directory_service_directory.this: Still creating... [4m20s elapsed] aws_directory_service_directory.this: Still creating... [4m30s elapsed] aws_directory_service_directory.this: Still creating... [4m40s elapsed] aws_directory_service_directory.this: Still creating... [4m50s elapsed] aws_directory_service_directory.this: Still creating... [5m0s elapsed] aws_directory_service_directory.this: Still creating... [5m10s elapsed] aws_directory_service_directory.this: Still creating... [5m20s elapsed] aws_directory_service_directory.this: Still creating... [5m30s elapsed] aws_directory_service_directory.this: Still creating... [5m40s elapsed] aws_directory_service_directory.this: Still creating... [5m50s elapsed] aws_directory_service_directory.this: Still creating... [6m0s elapsed] aws_directory_service_directory.this: Still creating... [6m10s elapsed] aws_directory_service_directory.this: Still creating... [6m20s elapsed] aws_directory_service_directory.this: Still creating... [6m30s elapsed] aws_directory_service_directory.this: Still creating... [6m40s elapsed] aws_directory_service_directory.this: Still creating... [6m50s elapsed] aws_directory_service_directory.this: Still creating... [7m0s elapsed] aws_directory_service_directory.this: Still creating... [7m10s elapsed] aws_directory_service_directory.this: Still creating... [7m20s elapsed] aws_directory_service_directory.this: Still creating... [7m30s elapsed] aws_directory_service_directory.this: Still creating... [7m40s elapsed] aws_directory_service_directory.this: Still creating... [7m50s elapsed] aws_directory_service_directory.this: Still creating... [8m0s elapsed] aws_directory_service_directory.this: Still creating... [8m10s elapsed] aws_directory_service_directory.this: Still creating... [8m20s elapsed] aws_directory_service_directory.this: Still creating... [8m30s elapsed] aws_directory_service_directory.this: Still creating... [8m40s elapsed] aws_directory_service_directory.this: Still creating... [8m50s elapsed] aws_directory_service_directory.this: Still creating... [9m0s elapsed] aws_directory_service_directory.this: Still creating... [9m10s elapsed] aws_directory_service_directory.this: Still creating... [9m20s elapsed] aws_directory_service_directory.this: Still creating... [9m30s elapsed] aws_directory_service_directory.this: Still creating... [9m40s elapsed] aws_directory_service_directory.this: Still creating... [9m50s elapsed] aws_directory_service_directory.this: Still creating... [10m0s elapsed] aws_directory_service_directory.this: Still creating... [10m10s elapsed] aws_directory_service_directory.this: Still creating... [10m20s elapsed] aws_directory_service_directory.this: Still creating... [10m30s elapsed] aws_directory_service_directory.this: Still creating... [10m40s elapsed] aws_directory_service_directory.this: Still creating... [10m50s elapsed] aws_directory_service_directory.this: Still creating... [11m0s elapsed] aws_directory_service_directory.this: Still creating... [11m10s elapsed] aws_directory_service_directory.this: Still creating... [11m20s elapsed] aws_directory_service_directory.this: Still creating... [11m30s elapsed] aws_directory_service_directory.this: Still creating... [11m40s elapsed] aws_directory_service_directory.this: Still creating... [11m50s elapsed] aws_directory_service_directory.this: Still creating... [12m0s elapsed] aws_directory_service_directory.this: Still creating... [12m10s elapsed] aws_directory_service_directory.this: Still creating... [12m20s elapsed] aws_directory_service_directory.this: Still creating... [12m30s elapsed] aws_directory_service_directory.this: Still creating... [12m40s elapsed] aws_directory_service_directory.this: Still creating... [12m50s elapsed] aws_directory_service_directory.this: Still creating... [13m0s elapsed] aws_directory_service_directory.this: Still creating... [13m10s elapsed] aws_directory_service_directory.this: Still creating... [13m20s elapsed] aws_directory_service_directory.this: Still creating... [13m30s elapsed] aws_directory_service_directory.this: Still creating... [13m40s elapsed] aws_directory_service_directory.this: Still creating... [13m50s elapsed] aws_directory_service_directory.this: Still creating... [14m0s elapsed] aws_directory_service_directory.this: Still creating... [14m10s elapsed] aws_directory_service_directory.this: Still creating... [14m20s elapsed]
フェーズ詳細を確認すると、ビルドフェーズでタイムアウトになっていることが確認できます。
作成中だった AD についてコンソールから確認すると作成中状態です。 ちなみに、API の呼び出しが開始された(今回で言う AD)リソースの作成は CodeBuild が動作しなくなってからも動いているようで、暫く経つと完了していました。作成が開始すらされなかった FSx については構築はされていませんでした。
ビルドが完了していないため、アーティファクトに tfstate も出力されず、terraform destroy
を CodeBuild で実行しようにも不可能です。
main.tf に backend として S3 に tfstate ファイルを保存するよう設定を行うことで外部に出力することは可能なので、このようにタイムアウトのせいでロールバックも行われず、アーティファクトも出力されなかった場合に有用になるかもしれません。
terraform { backend "s3" { bucket = "xxx" key = "backend/fsx/terraform.tfstate" region = "ap-northeast-1" encrypt = true } }
まとめ
本ブログでは CodeBuild に Lambda コンピューティングを使用して、アップデートにて追加されたカスタムイメージを Terraform で実行してみました。 Lambda コンピューティングはビルドの起動が早く、料金も安く実行可能ですが、タイムアウトした場合の処理も考えておかないと問題が発生する可能性があります。 そのため、時間がかかる処理を確実に完了させたい場合は向かない点、使用する場合は注意が必要になるでしょう。
末廣 満希(執筆記事の一覧)
2022年新卒入社です。ここに何かかっこいい一言を書くことができるエンジニアになれるように頑張ります。