SQLでインフラ管理? IaSQLを試してみた

2022.05.02

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

中山です

今日は、twitterで見かけたIaSQLなるサービスを試したので紹介してみたいと思います。

IaSQLとは

IaSQLとは、インフラの状態をPostgreSQLで管理管理できるSaaSです。

IaSQL

Why IaSQL

メリットとしては以下の3点が挙げられていました。

Import existing cloud infrastructure Connect an AWS account to a hosted IaSQL DB to automatically backfill the database with your existing cloud resources. No need to redefine or reconcile existing infrastructure.

The definitive state of your cloud IaSQL's module system lets you specify which parts of your cloud infrastructure you wish to control as tables in PostgreSQL

Infrastructure changes can be version controlled Commit IaSQL database changes to your codebase using any migration system or a script with idempotent SQL inserts

IaSQL

・・・よく分からなかったのですが、おもしろそうなコンセプトだと思ったのでとりあえず触ってみます。

やってみた

公式ドキュメントのチュートリアルを参考にしつつ、以下の手順で動作を確認してみました。

  • アクセスキーの発行
  • Databaseの作成
  • Cloud9環境(SQL Client)の作成
  • Helpの参照
  • モジュールのインストール
  • 新しいAWSリソースを定義(レコードの挿入)
  • Apply
  • 既存のAWSリソースをインポート(Sync)
  • Sync
  • 作成したリソースの削除

この記事は2022年5月2日頃の情報に基づいて執筆しています。このサービスはリリースされたばかりのため、UIやコマンドが大幅に変化する可能性があります。

アクセスキーの発行

まず、IaSQLがAWSアカウントを操作できるようにAWSからアクセスキーを発行します。 手順はここでは解説しませんので、詳細は以下のドキュメントを確認してください。

Managing access keys (console)

Databaseの作成

ここから、IaSQLの管理コンソールを操作します。

まずはIaSQLにサインアップします。

GoogleおよびGitHubのアカウントと認証連携ができるようです。

サインアップすると、データベースを作成するウィザードが開始されるので、リージョンの選択とアクセスキーの入力を行います。

成功すると、データベースへの接続情報が表示されるので記録します。

Cloud9環境(SQL Client)の作成

次に作成したデータベースに接続するための環境を用意します。 今回はCloud9でUbuntu18の環境を利用したいと思います。

Creating an EC2 Environment

環境が作成できたらクライアントをインストールします。 なお、クライアントにはPostgreSQLをサポートするあらゆるクライアントが利用可能であるとしています。

sudo apt install postgresql

クライアントをインストールできたら、データベースに接続します。

psql -h db.iasql.com -d _xxxxxxxxxxxxxxxx -U yyyyyyyy
Password for user vb7c6skx: 
psql (10.19 (Ubuntu 10.19-0ubuntu0.18.04.1), server 13.4)
WARNING: psql major version 10, server major version 13.
         Some psql features might not work.
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

_xxxxxxxxxxxxxxxx=>

Helpの参照

とりあえずヘルプを表示したいと思います。

SELECT * FROM iasql_help();
       name        |            signature             |                              description                              |                       sample_usage                        
-------------------+----------------------------------+-----------------------------------------------------------------------+-----------------------------------------------------------
 apply             | iasql_apply()                    | Create, delete, or update the cloud resources in a hosted db          | SELECT * FROM iasql_apply()
 plan_apply        | iasql_plan_apply()               | Preview of the resources in the db to be modified on the next `apply` | SELECT * FROM iasql_plan_apply()
 sync              | iasql_sync()                     | Synchronize the hosted db with the current state of the cloud account | SELECT * FROM iasql_sync()
 plan_sync         | iasql_plan_sync()                | Preview of the resources in the db to be modified on the next `sync`  | SELECT * FROM iasql_plan_sync()
 install           | iasql_install(variadic text[])   | Install modules in the hosted db                                      | SELECT * FROM iasql_install('aws_vpc', 'aws_ec2@0.0.2')
 uninstall         | iasql_uninstall(variadic text[]) | Uninstall modules in the hosted db                                    | SELECT * FROM iasql_uninstall('aws_vpc@0.0.2', 'aws_ec2')
 modules_list      | iasql_modules_list()             | Lists all modules available to be installed                           | SELECT * FROM iasql_modules_list()
 modules_installed | iasql_modules_installed()        | Lists all modules currently installed in the hosted db                | SELECT * FROM iasql_modules_installed()
 upgrade           | iasql_upgrade()                  | Upgrades the db to the latest IaSQL Platform                          | SELECT iasql_upgrade()
(9 rows)

どうやら、

  • 管理したいAWSリソースに併せてモジュールをインストールする
  • AWSアカウントの状態とDBのレコードを同期させることができる(sync)
  • データベースのレコードを操作してリソースの作成や削除ができる(apply)
  • syncやapplyの前にplan(dry run)を実行できる

ワークフロー的には、terraformっぽいですね。

モジュールのインストール

モジュールにインストールをやってみましょう。

まずは、どのようなモジュールが用意されているかを確認します。

SELECT * FROM iasql_modules_list();
       module_name        | module_version |                                                       dependencies                                                        
--------------------------+----------------+---------------------------------------------------------------------------------------------------------------------------
 aws_account              | 0.0.2          | {}
 aws_cloudwatch           | 0.0.2          | {aws_account@0.0.2}
 aws_ec2                  | 0.0.2          | {aws_account@0.0.2,aws_security_group@0.0.2}
 aws_ecr                  | 0.0.2          | {aws_account@0.0.2}
 aws_ecs_fargate          | 0.0.2          | {aws_account@0.0.2,aws_ecr@0.0.2,aws_elb@0.0.2,aws_security_group@0.0.2,aws_cloudwatch@0.0.2,aws_vpc@0.0.2,aws_iam@0.0.2}
 aws_elb                  | 0.0.2          | {aws_account@0.0.2,aws_security_group@0.0.2,aws_vpc@0.0.2}
 aws_rds                  | 0.0.2          | {aws_account@0.0.2,aws_security_group@0.0.2}
 aws_route53_hosted_zones | 0.0.2          | {aws_account@0.0.2}
 aws_security_group       | 0.0.2          | {aws_account@0.0.2,aws_vpc@0.0.2}
 aws_vpc                  | 0.0.2          | {aws_account@0.0.2}
 aws_iam                  | 0.0.2          | {aws_account@0.0.2}
(11 rows)

今回はVPCを作成してみたいと思うので、aws_vpcをインストールします。

SELECT * FROM iasql_install('aws_vpc');
  module_name  | created_table_name | record_count 
---------------+--------------------+--------------
 aws_vpc@0.0.2 | vpc                |            2
 aws_vpc@0.0.2 | subnet             |            6
(2 rows)

モジュールをインストールしたことで2つのテーブルが作成されたようです。 内容を確認してみると、既存のリソースに関するレコードが併せて作成されているようです(既存のリソースはモジュールのインストール時に自動でインポートされる仕様?)。

select * from vpc;
 id |        vpc_id         |  cidr_block   |   state   | is_default 
----+-----------------------+---------------+-----------+------------
  1 | vpc-0617ce61          | 172.16.0.0/16 | available | f
  2 | vpc-0465f7d00a472a8d4 | 172.31.0.0/16 | available | t
(2 rows)
select * from subnet;
 id | availability_zone |   state   | available_ip_address_count |   cidr_block   |        subnet_id         |   owner_id   |                               subnet_arn                                | vpc_id 
----+-------------------+-----------+----------------------------+----------------+--------------------------+--------------+-------------------------------------------------------------------------+--------
  1 | ap-northeast-1d   | available |                        251 | 172.16.2.0/24  | subnet-71ff8c59          | XXXXXXXXXXXX | arn:aws:ec2:ap-northeast-1:XXXXXXXXXXXX:subnet/subnet-71ff8c59          |      1
  2 | ap-northeast-1a   | available |                        250 | 172.16.0.0/24  | subnet-aedba4e7          | XXXXXXXXXXXX | arn:aws:ec2:ap-northeast-1:XXXXXXXXXXXX:subnet/subnet-aedba4e7          |      1
  3 | ap-northeast-1c   | available |                       4089 | 172.31.0.0/20  | subnet-02fa41ebcecd9f3d4 | XXXXXXXXXXXX | arn:aws:ec2:ap-northeast-1:XXXXXXXXXXXX:subnet/subnet-02fa41ebcecd9f3d4 |      2
  4 | ap-northeast-1c   | available |                        250 | 172.16.1.0/24  | subnet-878822dc          | XXXXXXXXXXXX | arn:aws:ec2:ap-northeast-1:XXXXXXXXXXXX:subnet/subnet-878822dc          |      1
  5 | ap-northeast-1d   | available |                       4091 | 172.31.16.0/20 | subnet-028c9ed3e85d5aebd | XXXXXXXXXXXX | arn:aws:ec2:ap-northeast-1:XXXXXXXXXXXX:subnet/subnet-028c9ed3e85d5aebd |      2
  6 | ap-northeast-1a   | available |                       4091 | 172.31.32.0/20 | subnet-09061fa4b4d24697e | XXXXXXXXXXXX | arn:aws:ec2:ap-northeast-1:XXXXXXXXXXXX:subnet/subnet-09061fa4b4d24697e |      2
(6 rows)

併せてスキーマも確認してみましょう。 IaSQLが提供するデータベースのスキーマは以下のURLから確認できるようです。 テーブルsubnetのカラムvpc_idに外部キー制約が設定されていることも確認できます。

public.vpc

public.subnet

新しいAWSリソースを定義(レコードの挿入)

それでは、IaSQLで新しいレコードを作成してみたいと思います。 そのために、まずはレコードを追加します。

insert into vpc (cidr_block) values ('10.0.1.0/16');
INSERT 0 1

このときのテーブルの状態を確認してみます。 idにはNOT NULL制約がありますが、自動的にインクリメントされた値が設定されるようです(コンソールからデータベースをダンプすると確認できますが、この記事では割愛)。

select * from vpc;
 id |        vpc_id         |  cidr_block   |   state   | is_default 
----+-----------------------+---------------+-----------+------------
  1 | vpc-0617ce61          | 172.16.0.0/16 | available | f
  2 | vpc-0465f7d00a472a8d4 | 172.31.0.0/16 | available | t
  6 |                       | 10.0.1.0/16   |           | f
(3 rows)

Planを実行してみます。

SELECT * FROM iasql_plan_apply();
 action | table_name | id | description 
--------+------------+----+-------------
 create | vpc        |  6 | 6
(1 row)

想定通りの内容(テーブルvpcにレコードが1つ追加されている状態)なので、Applyを行います。

SELECT * FROM iasql_apply();
 action | table_name | id | description 
--------+------------+----+-------------
 create | vpc        |  6 | 6
(1 row)

テーブルを確認します。 Apply後はvpc_idおよびstateの値が設定されています。

select * from vpc;
 id |        vpc_id         |  cidr_block   |   state   | is_default 
----+-----------------------+---------------+-----------+------------
  1 | vpc-0617ce61          | 172.16.0.0/16 | available | f
  2 | vpc-0465f7d00a472a8d4 | 172.31.0.0/16 | available | t
  6 | vpc-0ce062d12e5e98c75 | 10.0.0.0/16   | pending   | f
(3 rows)

既存のAWSリソースをインポート(Sync)

次に既存のリソースをIaSQLに取り込んでみたいと思います。

まずは同期する機能を利用してみます。 今回はSubnetを作成したいと思います。

aws ec2 create-subnet \
    --cidr-block 10.0.0.0/24 \
    --vpc-id vpc-0ce062d12e5e98c75
{
    "Subnet": {
        "AvailabilityZone": "ap-northeast-1d",
        "AvailabilityZoneId": "apne1-az2",
        "AvailableIpAddressCount": 251,
        "CidrBlock": "10.0.0.0/24",
        "DefaultForAz": false,
        "MapPublicIpOnLaunch": false,
        "State": "available",
        "SubnetId": "subnet-02e21fcd200b0493c",
        "VpcId": "vpc-0ce062d12e5e98c75",
        "OwnerId": "XXXXXXXXXXXX",
        "AssignIpv6AddressOnCreation": false,
        "Ipv6CidrBlockAssociationSet": [],
        "SubnetArn": "arn:aws:ec2:ap-northeast-1:XXXXXXXXXXXX:subnet/subnet-02e21fcd200b0493c",
        "EnableDns64": false,
        "Ipv6Native": false,
        "PrivateDnsNameOptionsOnLaunch": {
            "HostnameType": "ip-name",
            "EnableResourceNameDnsARecord": false,
            "EnableResourceNameDnsAAAARecord": false
        }
    }
}

これで、IaSQLとAWSアカウントの状態にずれが発生しました。 この状態でSyncするとどうなるかPlanで確認します。 先ほど作成したリソースのIDがリストアップされました。

SELECT * FROM iasql_plan_sync();
 action | table_name | id |       description        
--------+------------+----+--------------------------
 create | subnet     |    | subnet-02e21fcd200b0493c
(1 row)

Syncコマンドで同期します。

SELECT * FROM iasql_sync();
 action | table_name | id |       description        
--------+------------+----+--------------------------
 create | subnet     |    | subnet-02e21fcd200b0493c
(1 row)

テーブルも参照してみます。

select * from subnet;
 id | availability_zone |   state   | available_ip_address_count |   cidr_block   |        subnet_id         |   owner_id   |                               subnet_arn                                | vpc_id 
----+-------------------+-----------+----------------------------+----------------+--------------------------+--------------+-------------------------------------------------------------------------+--------
  1 | ap-northeast-1d   | available |                        251 | 172.16.2.0/24  | subnet-71ff8c59          | XXXXXXXXXXXX | arn:aws:ec2:ap-northeast-1:XXXXXXXXXXXX:subnet/subnet-71ff8c59          |      1
  2 | ap-northeast-1a   | available |                        250 | 172.16.0.0/24  | subnet-aedba4e7          | XXXXXXXXXXXX | arn:aws:ec2:ap-northeast-1:XXXXXXXXXXXX:subnet/subnet-aedba4e7          |      1
  3 | ap-northeast-1c   | available |                       4089 | 172.31.0.0/20  | subnet-02fa41ebcecd9f3d4 | XXXXXXXXXXXX | arn:aws:ec2:ap-northeast-1:XXXXXXXXXXXX:subnet/subnet-02fa41ebcecd9f3d4 |      2
  4 | ap-northeast-1c   | available |                        250 | 172.16.1.0/24  | subnet-878822dc          | XXXXXXXXXXXX | arn:aws:ec2:ap-northeast-1:XXXXXXXXXXXX:subnet/subnet-878822dc          |      1
  5 | ap-northeast-1d   | available |                       4091 | 172.31.16.0/20 | subnet-028c9ed3e85d5aebd | XXXXXXXXXXXX | arn:aws:ec2:ap-northeast-1:XXXXXXXXXXXX:subnet/subnet-028c9ed3e85d5aebd |      2
  6 | ap-northeast-1a   | available |                       4091 | 172.31.32.0/20 | subnet-09061fa4b4d24697e | XXXXXXXXXXXX | arn:aws:ec2:ap-northeast-1:XXXXXXXXXXXX:subnet/subnet-09061fa4b4d24697e |      2
  7 | ap-northeast-1d   | available |                        251 | 10.0.0.0/24    | subnet-02e21fcd200b0493c | XXXXXXXXXXXX | arn:aws:ec2:ap-northeast-1:XXXXXXXXXXXX:subnet/subnet-02e21fcd200b0493c |      6
(7 rows)

作成したリソースの削除

最後に、作成したサブネットとVPCを削除します。

delete from subnet where id = 7;
delete from vpc where id = 6;
SELECT * FROM iasql_plan_apply();
 action | table_name | id |       description        
--------+------------+----+--------------------------
 delete | subnet     |    | subnet-02e21fcd200b0493c
(1 row)

本来であれば、ここでSubnetとVPCの2つが表示される想定でしたが、なぜかVPCが表示されず・・・後でIssue書く。

SELECT * FROM iasql_apply();
 action | table_name | id |       description        
--------+------------+----+--------------------------
 delete | subnet     |    | subnet-02e21fcd200b0493c
(1 row)

まとめ

簡単に触ってみましたが、簡単に感想をまとめます。

従来のIaCは独自のDSLでインフラを記述するのに対してIaSQLではSQLでインフラを定義するため、SQLに慣れた方にはある程度とっつきやすい(かもしれない)と思いました。 また、AWSリソース = レコードという捉え方ができるのでかなりとっつきやすい印象も受けました。

同時に、CloudFormation/Terrafrom/CDK等のツールやサービスがかなり成熟している現状を考えると、今後このサービスがどの程度受け入れられるんだろうか?とも思いました。

コンセプトは非常におもしろいと思ったので、今後も注目したいと思います。

その他

以下の様な類似のサービスも存在するようです。

また、ドキュメントにはFlyway等のDB migration toolを利用する場合のチュートリアルもありました。