y-ohgi's blog

TODO: ここになにかかく

Cloud Control APIで操作するAWS

TL;DR

  • AWS Cloud Control APIでAWSリソースを操作する
  • CLIとOpenTofuからVPCの作成を行った
  • Cloud Control APIは各AWSリソースに対してCRUD-LなAPIを提供してくれるため、統一的な操作が可能

About

AWSはCloud Control APIというCRUD-L(CREATE・READ・UPDATE・LIST)で操作できるAPIが存在します。
そのAPIを使用することで統一的な操作が行える点が魅力であり、サードパーティな製品(IaCのProviderやプログラミングのSDK)がAWSのアップデートに対応しやすくなることがメリットなのかなと思います。

公式doc What is AWS Cloud Control API? - Cloud Control API

対応リソース
Resource types that support Cloud Control API - Cloud Control API

How to

CLIから触る

Cloud Control APIは標準で aws cli から叩くことが可能です。
以下のようにサブコマンドとして cloudcontrol が備わっています。

$ aws cloudcontrol 

単純に触るのであればCloud Shellから叩くのが手っ取り早いかと思います。

VPCを操作する

まずはVPCの作成を行います。
作成時は create-resource でCREATEの宣言を行い、あとは「 --type-name でどのリソースを作成するか」を指定し、「 --desired-state でどのような構成にするか」を宣言します。
--desired-state は各リソースのCFnのPropertiesのJSONが入ります。

$ aws cloudcontrol create-resource \
  --type-name AWS::EC2::VPC \
  --desired-state '{"CidrBlock": "10.0.0.0/16", "Tags": [{"Key": "Name", "Value": "example"}]}'
{
    "ProgressEvent": {
        "TypeName": "AWS::EC2::VPC",
        "RequestToken": "5543dadd-1e7c-4208-ba9e-xxxxxxxx",
        "Operation": "CREATE",
        "OperationStatus": "IN_PROGRESS",
        "EventTime": "2025-03-25T11:07:52.653000+00:00"
    }
}

コマンドは非同期的に実行されます。
ProgressEvent.RequestToken の値が重要で、このトークンの値を元にCloud Control APIで操作しているリソースの状態を知ることができます。

状態を確認するためには get-resource-request-status サブコマンドと --request-token オプションにトークンの値を入れます。

$ aws cloudcontrol get-resource-request-status \
  --request-token 5543dadd-1e7c-4208-ba9e-xxxxxxxx
{
    "ProgressEvent": {
        "TypeName": "AWS::EC2::VPC",
        "Identifier": "vpc-xxxxxxxx",
        "RequestToken": "5543dadd-1e7c-4208-ba9e-xxxxxxxx",
        "Operation": "CREATE",
        "OperationStatus": "SUCCESS",
        "EventTime": "2025-03-25T11:08:04.434000+00:00"
    }
}

ProgressEvent.OperationStatus"IN_PROGRESS" から "SUCCESS" になりました。

実際に存在するか確認してみましょう。
get-resource サブコマンドを使用し、 --type-name でリソースを指定し、 --identiferProgressEvent.Identifier の値を宣言します。
今回の場合、VPC IDになります。

$ aws cloudcontrol get-resource \
  --type-name AWS::EC2::VPC \
  --identifier vpc-xxxxxxxx
{
    "TypeName": "AWS::EC2::VPC",
    "ResourceDescription": {
        "Identifier": "vpc-xxxxxxxx",
        "Properties": "{\"VpcId\":\"vpc-xxxxxxxx\",\"InstanceTenancy\":\"default\",\"CidrBlockAssociations\":[\"vpc-cidr-assoc-0ccfb9a2f2cc8b5cd\"],\"CidrBlock\":\"10.0.0.0/16\",\"DefaultNetworkAcl\":\"acl-08ba13f5c5e43bd42\",\"EnableDnsSupport\":true,\"Ipv6CidrBlocks\":[],\"DefaultSecurityGroup\":\"sg-04a895b6d81ac2816\",\"EnableDnsHostnames\":false,\"Tags\":[{\"Value\":\"example\",\"Key\":\"Name\"}]}"
    }
}

実際に確認できました。

最後に削除です。
先ほどの get-resourcedelete-resource に変更することで削除できます。
統一的なAPIであるため非常にシンプルに実行可能です。

$ aws cloudcontrol delete-resource \
  --type-name AWS::EC2::VPC \
  --identifier vpc-xxxxxxxx
{
    "ProgressEvent": {
        "TypeName": "AWS::EC2::VPC",
        "Identifier": "vpc-xxxxxxxx",
        "RequestToken": "b03ad40e-745d-4716-b454-xxxxxxxx",
        "Operation": "DELETE",
        "OperationStatus": "IN_PROGRESS",
        "EventTime": "2025-03-25T11:06:09.053000+00:00"
    }
}

OpenTofu

Terraform・OpenTofu共に AWSCC という AWS Cloud Control用のProviderがあります。

CLIで行ったVPCの作成をOpenTofuで記載すると以下になります。

terraform {
  required_providers {
    awscc = {
      source = "opentofu/awscc"
      version = "1.34.0"
    }
  }
}

provider "awscc" {
  # Configuration options
}

variable "name" {
  description = "The name of the VPC"
  type = string
  default = "example"
}

variable "cidr_block" {
  description = "The CIDR block for the VPC"
  type = string
  default = "10.0.0.0/16"
}

resource "awscc_ec2_vpc" "this" {
  cidr_block = var.cidr_block

  tags = [{
    key = "Name"
    value = var.name
  }]
}

その後、initとapplyをすることでVPCの作成を行えます。

$ tofu init
$ tofu apply

CFnのProperiesを使用していると述べた通り、AWS Providerとあまり変わりなく書くことが可能です。
短いコードですが差異として、 tagskey , value になっており、普段よりアトミックな(CFnのような)書き方をします。

所感

個人的に業務でCloud Control APIを積極的に使用するのはあまりイメージが付きませんでした。
冒頭で記述した通り、サードパーティ製品がAWSのアップデートに追従しやすくなり、間接的にメリットを受けれるのが最大の魅力だと感じています。