AWS App RunnerのVPCコネクターのエラーとルール

ようやく先日、AWS App RunnerでVPCリソースへのアクセスができるようになりました。その際に作成するVPC Connectorの思わぬエラーやルールがあったので小ネタとして書いてみました。


まとめ

  1. VPC Connectorごとにセキュリティグループの組み合わせが被ってはいけない
  2. CloudFormationにおけるVPC Connector自体の設定変更はReplacement(再構築)になる
  3. そもそもVPC Connector自体の設定変更がエラーになる
  4. VPC Connector自体にUpdateのAPIはない

※CloudFormationを通して構築した際に発見したものになります。が、コンソールでも同じような感じでした。


概要

ついにApp RunnerでVPCリソースにアクセスできるようになりましたね。

※以下記事ではCloudFormationで構築する方法を書いてみたのでよかったらぜひ。(以下で話すVPC Connectorを含めて構築しています。)

go-to-k.hatenablog.com


そこで何気なく、CloudFormationを通してApp RunnerのVPC Connectorのサブネットを変更しようとしたらエラーになったため、色々検証してみました。


試したこと

以下をCloudFormationを通して構築・変更を試しました。

  • サブネット変更
  • セキュリティグループ変更
  • VPCコネクタ名(VpcConnectorName)変更


サブネット変更

最初はこのようなリソース構成で構築してみました。

※他にもApp Runnerのサービスなどもありますが省略。

※Subnetsの値は実際の値から書き換えています。

  VpcConnector:
    Type: AWS::AppRunner::VpcConnector
    Properties: 
      VpcConnectorName: "test-app-runner"
      Subnets: 
        - "subnet-aaaaaaaaaaaaaaaaa"
        - "subnet-bbbbbbbbbbbbbbbbb"
      SecurityGroups:
        - !Ref AppRunnerSecurityGroup1

  AppRunnerSecurityGroup1:
    Type: AWS::EC2::SecurityGroup
    Properties: 
      VpcId: !Ref VpcID
      GroupName: "test-sg-1"
      GroupDescription: "for App Runner"


これをもとにAppRunnerを構築し、そのあとにVpcConnectorのサブネットを以下のように変更しようとしました。

  • "subnet-bbbbbbbbbbbbbbbbb"
    • -> "subnet-ccccccccccccccccc"


このようにCloudFormationのテンプレートを変更しデプロイをすると、以下のようなエラーが出ました。

Resource handler returned message: "The security groups combination provided in the request already exists on existing vpc connector. Existing VPC connector arn: arn:aws:apprunner:ap-northeast-1:123456789012:vpcconnector/test-app-runner/1/***************************, Security Groups: [sg-******************] (Service: AppRunner, Status Code: 400, Request ID: ******************, Extended Request ID: null)" (RequestToken: ******************, HandlerErrorCode: InvalidRequest)


読んでみると、「すでに他のVPCネクターで、同じ組み合わせのセキュリティグループがある」ので作成が失敗しているようです。


そこで公式ドキュメントを読んでみました。

2022年2月12日現在日本語版の方にはVPCアクセスのページはなく、英語版の方には 「Enabling VPC access for your service」というページが作成されていました。

しかし読んでみても、それらしき記述はない・・・

いくつかのリージョンではAZ・サブネットが非対応という注意書きはありますが、今回は東京リージョンで一度成功してからのサブネット変更だし、エラーメッセージ的にも違うので、別件と判断しました。)


まあしかしエラーになったということで、

  • VPC Connectorごとにセキュリティグループの組み合わせが被ってはいけない

というルールがあることがわかりました。


セキュリティグループ変更

サブネットを変えるにはセキュリティグループを変更しなくてはならなさそうだ、ということで、

次は(サブネットの指定を変えたまま)、セキュリティグループを変更してみます。


こちらから

      Subnets: 
        - "subnet-aaaaaaaaaaaaaaaaa"
        - "subnet-bbbbbbbbbbbbbbb"
      SecurityGroups:
        - !Ref AppRunnerSecurityGroup1

以下のように変更してみます。

※AppRunnerSecurityGroup2はもとのAppRunnerSecurityGroup1と同様の設定のコードで新規で作成します。

      Subnets: 
        - "subnet-aaaaaaaaaaaaaaaaa"
        - "subnet-ccccccccccccccccc"
      SecurityGroups:
        - !Ref AppRunnerSecurityGroup2


すると今度は、以下のエラーが出ました。

同じ名前のVPCネクターが存在しているとのことです。

Resource handler returned message: "VPC connector name test-app-runner already exists (Service: AppRunner, Status Code: 400, Request ID: ******************, Extended Request ID: null)" (RequestToken: ******************, HandlerErrorCode: InvalidRequest)


後出しになるのですが、実はCloudFormationのAppRunnerのドキュメントで、VPCコネクタの各パラメータは「Update requires: Replacement」とありました。

「Update requires: Replacement」と書いてあるパラメータを更新する際は、該当リソースが再構築されるというものになります。


VPCコネクタに対応する「AWS::AppRunner::VpcConnector」は以下のパラメータ構成になっており、全てのパラメータが「Update requires: Replacement」となっています。

  • SecurityGroups
  • Subnets
  • Tags
  • VpcConnectorName


つまり、今回Replacement対象のパラメータを変更したことによりリソースの再構築が走り、同じVpcConnectorNameのままリソース更新をしようとしているため、更新前と後で名前が被っているのでエラーが出ている、ということでしょうか。


何にせよ、

  • CloudFormationにおけるVPC Connector自体の設定変更はReplacement(再構築)になる

ということがわかりました。


VPCコネクタ名(VpcConnectorName)変更

そして、最後にVPCコネクタ名(VpcConnectorName)を変更してみます。


その前に、CloudFormationドキュメントでVpcConnectorNameを確認してみると、以下のようなことが書いてありました。

If you don't specify a name, AWS CloudFormation generates a name for your VPC connector.


どうやら名前を指定しないと、自動で名前を付けてくれるそうです。

CloudFormationではこのように置換が発生するリソースに関して、名前被りが生じて更新に失敗しないように、名前を明示的につけず自動生成に任せるというセオリーがあったりします。(S3バケットなど)


そこで、今回はVpcConnectorNameをコメントアウトして、先程のサブネット変更・セキュリティグループ変更と共に実行してみます。

  VpcConnector:
    Type: AWS::AppRunner::VpcConnector
    Properties: 
      # VpcConnectorName: "test-app-runner"
      Subnets: 
        - "subnet-aaaaaaaaaaaaaaaaa"
        - "subnet-ccccccccccccccccc"
      SecurityGroups:
        - !Ref AppRunnerSecurityGroup2


すると、スタックの更新は成功しました!!


しかし、イベントを見てみるとどうやら正常に成功したわけではなさそうで・・・


  • 旧リソースのVPCコネクタを削除しようとしてエラーが出て失敗(DELETE_FAILED)し、
  • それが3回ほど繰り返され
  • 最終的に削除が失敗したままスタック更新が完了(UPDATE_COMPLETE)
    • 「Update successful. One or more resources could not be deleted.」というメッセージ

となりました。。

そのときのエラーですが、他のAppRunnerサービスで使われているから消せないとのことです。

Resource handler returned message: "Provided VPC connector arn is being used by other services. ARN: arn:aws:apprunner:ap-northeast-1:123456789012:vpcconnector/test-app-runner/1/****************** (Service: AppRunner, Status Code: 400, Request ID: ******************, Extended Request ID: null)" (RequestToken: ******************, HandlerErrorCode: InvalidRequest)


これでリソースの更新ができたからいいや、とはならず一応CLIのListVpcConnectorsコマンドで見てみると、やっぱり旧リソース(名前を変更する前の)が残っていて、この手法はちょっとだめだなと思いました。

そして上記の他のAppRunnerサービスで使われているというエラーにも関わらず、上記CloudFormation実行後に、CLIでDeleteVpcConnectorコマンドによって削除することはできました。

$ aws apprunner list-vpc-connectors
{
    "VpcConnectors": [
        {
            "VpcConnectorName": "test-app-runner",
            "VpcConnectorArn": "arn:aws:apprunner:ap-northeast-1:123456789012:vpcconnector/test-app-runner/1/***************************",
            ...
            ...

$ aws apprunner delete-vpc-connector --vpc-connector-arn "arn:aws:apprunner:ap-northeast-1:123456789012:vpcconnector/test-app-runner/1/***************************"
{
    "VpcConnectors": [
        {
            "VpcConnectorName": "test-app-runner",
            "VpcConnectorArn": "arn:aws:apprunner:ap-northeast-1:123456789012:vpcconnector/test-app-runner/1/***************************",
            ...
            ...

$ aws apprunner list-vpc-connectors
# -> 更新後のリソースのみになった
{
    "VpcConnectors": [
        {
            "VpcConnectorName": "VpcConnector-abcdefg123456"
            ...
            ...


また、そもそもサブネットを変えたいのに、セキュリティグループやVpcConnector名を変更しないと変更できないなんて許容できないですよね。

おとなしく、「スタック更新を2回に分けて、一旦コネクター削除→作成」や、「別コネクタを作成(セキュリティグループ被らないように)してアタッチ」というような方法が良かったりするのでしょうか。

(そもそもサブネット変更はあまり頻度は高くないため、あまり気にしなくて良いかとは思います。)


というわけで、

  • そもそもVPC Connector自体の設定変更がエラーになる

というルールも発見されました。(正確には、設定変更は可能だが実質できないようなもの


おまけ

少しAWSAppRunnerのActionドキュメントを読んでいたら、App RunnerのAPIに更新操作にあたるもの(UpdateVpcConnectorなど)がありませんでした(2022年2月12日現在)。


VpcConnectorと名のつくものは以下の4つのみでした。

  • CreateVpcConnector
  • DeleteVpcConnector
  • DescribeVpcConnector
  • ListVpcConnectors


つまり、

  • VPC Connector自体にUpdateのAPIはない

ということもわかりました。



まとめ(再掲)

AWS App RunnerのVPC Connectorに関して、以下のルールがわかりました。

  1. VPC Connectorごとにセキュリティグループの組み合わせが被ってはいけない
  2. CloudFormationにおけるVPC Connector自体の設定変更はReplacement(再構築)になる
  3. そもそもVPC Connector自体の設定変更がエラーになる
  4. VPC Connector自体にUpdateのAPIはない


※ドキュメントの見落としや、動作確認の漏れ・間違いなどがある可能性もあるためご了承ください。


最後に

App RunnerにVPCリソースのアクセスが可能になり、早速色々試していたのですが、思わぬ挙動に当たったためとりあえず書いてみました。

新しいサービス・リソースにはよくあることですね。