Amazon EventBridge と AWS Step Functions によるプライベート API 実行を使って、プライベートネットワークのJenkins JOBを実行してみる

以下のリリースによって、プライベートAPIの実行が可能になりました

https://aws.amazon.com/jp/about-aws/whats-new/2024/12/amazon-eventbridge-step-functions-integration-private-apis/

https://dev.classmethod.jp/articles/stepfunctions-to-private-api-with-eventbridge/

今回はこの機能を使用して、プライベートネットワーク内のJenkins JOBを実行してみます

上記の記事では、実際にAPI実行をするところまで実施できていなかったので、実際に検証をしてみて動作確認と接続の際の注意点をまとめます


## このリリースで嬉しいこと

基本的には前述の記事に書かれていますが、改めてまとめると

- 今までは、VPC内のプライベートネットワーク内のリソースに対してのAPI（以下プライベートAPI）実行にはLambdaなどの利用が必要だった
- そのため、プライベートAPIの実行が絡むアーキテクチャーにおいては、ノーコードでのイベント駆動処理やワークフローの構築は難しい
- 今回のアップデートでそれが不要になり、よりシンプルかつ運用コストの低い構成が可能になりました


## 今回の構成

社内で利用しているJenkinsサーバー（EC2）があり、その中のあるJOBをStep Functions から実行したいという要件があるとします
JenkinsサーバーはVPCのprivate subnetの中にあり、パブリックIPは保持していません。VPCピアリングを利用して社内ネットワークからアクセスをしてJOBを実行している状態です

JenkinsはAPIでJOB実行が可能ですが、インターネットからアクセスはできないため、Step Functionsから直接実行はできずJOB実行にはLambdaを経由して実行が必要でした

https://qiita.com/_mi/items/0cfb91fbe5cac090ff33

なお、今回はすべてのリソースは1つのアカウントで作成し、クロスアカウントアクセスはしません

## この機能を使う場合に認識しておくこと

この機能を使う際には、以下のリソースの作成が必要です

- VPC LatticeのResource GatewayとResource Configuration
- EventBridgeのConnection(接続)
- Secret Manager

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372042/1c348eca-edf3-42f6-8f6a-85149f607b9d.png)


https://docs.aws.amazon.com/ja_jp/eventbridge/latest/userguide/connection-private.html

注意点としては、接続にはHTTPSのみをサポートしていることです。EC2に直接接続する場合EC2自体でHTTPS(443 port)での通信ができる必要があります。

>プライベート HTTPS エンドポイントへの接続を作成して、パブリックインターネットを経由することなくVPCs またはオンプレミスのリソースへの安全なpoint-to-pointネットワークアクセスを提供できます。



## 進め方とポイント

基本的にローンチブログに基づいて各種リソースを作成していきます

https://aws.amazon.com/blogs/aws/securely-share-aws-resources-across-vpc-and-account-boundaries-with-privatelink-vpc-lattice-eventbridge-and-step-functions/


ブログと異なる点は以下になります。

- Resource Configurationで設定するアクセスエンドポイントにはALBを紐づけたRoute53レコードを指定
  - Jenkinsサーバー自体は8080 portでの接続になるので、そのままブログと同じようにEC2サーバーのIPを指定するとhttps(443 port)にならないため、接続できない

ブログ内ではサーバーのPrivateIPを直接Route53のレコードに登録して、Resource ConfigurationでのDomain Nameとして設定していますが、この場合サーバー自体でHTTPS(443 port)での通信をできる必要があります。

現在のAWS構成ではALBを利用したSSL Terminationをしていることが多いと思うので、実際には今回のようなALBを紐づけたRoute53レコードを指定した構成になることが多いと思います。
このJenkinsサーバーには直接接続をしていたので、この対応のためにInternal ALBを作成しました

また、各種リソースに設定するセキュリティグループに関しては以下のドキュメントを確認してください

https://docs.aws.amazon.com/eventbridge/latest/userguide/connection-private-rc-provider.html#connection-private-provider-security

### 作成リソース

- Resource Gateway

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372042/87be3a5f-32eb-4039-967d-f85c3308e7e1.png)


- Resource Configuration

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372042/be19e5c0-a8de-4dcc-a9ac-554b089f6ee8.png)


- EventBridge Connection
  - 認証方法はBasicでpasswordにはログインユーザーのAPIトークンを設定して下さい
  - Secret Managerのリソースは自動で作成されます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372042/8511a629-ba67-4c1e-bfb1-d3dad3b04584.png)

## Step function側の設定

こちらも、基本的にはブログをベースに、以下の情報を設定してください

- API エンドポイントに実行したいJenkins JOBのURL
  - e.g. https://jenkins.example.com/job/TestJob/buildWithParameters
- クエリパラメータ
  - JOB内の設定で定義したtokenの値
  - JOBパラメータのKey/Value

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372042/ccc61bb1-641f-4363-8e69-a53d2d44c277.png)

上記を設定して、テスト実行をしてみると以下のように表示されて、API実行が成功していることがわかります

そして、Jenkins側のページを見ると、確かに実行ができていることがわかると思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372042/a2ba5649-7fdb-4d19-a329-99011a199318.png)

なお、Resource Configurationの作成時に、ログ出力をCloudwatch logsに設定している場合、以下のように通信のログを確認できます

今回の場合、Resource Gateway側のリソース 192.168.82.122 からALBのIPである 192.168.82.89への通信が確認できます

```json
{
    "eventTimestamp": "2025-04-30T15:40:27.110Z",
    "serviceNetworkResourceAssociationId": "snra-098766e1fa3103999",
    "resourceConfigurationArn": "arn:aws:vpc-lattice:ap-northeast-1:895153766100:resourceconfiguration/rcfg-09c327e616a537834",
    "protocol": "tcp",
    "gatewayIpPort": "192.168.82.122:18503",
    "resourceIpPort": "192.168.82.89:443"
}
{
    "eventTimestamp": "2025-04-30T15:58:38.021Z",
    "serviceNetworkResourceAssociationId": "snra-098766e1fa3103999",
    "resourceConfigurationArn": "arn:aws:vpc-lattice:ap-northeast-1:895153766100:resourceconfiguration/rcfg-09c327e616a537834",
    "protocol": "tcp",
    "gatewayIpPort": "192.168.82.122:60979",
    "resourceIpPort": "192.168.82.89:443"
}
{
    "eventTimestamp": "2025-04-30T15:59:42.420Z",
    "serviceNetworkResourceAssociationId": "snra-098766e1fa3103999",
    "resourceConfigurationArn": "arn:aws:vpc-lattice:ap-northeast-1:895153766100:resourceconfiguration/rcfg-09c327e616a537834",
    "protocol": "tcp",
    "gatewayIpPort": "192.168.82.122:46400",
    "resourceIpPort": "192.168.82.89:443"
}
```


## まとめ

このような形で、Step FunctionsからプライベートネットワークのJenkins JOBを実行が実現できました。
接続したいサーバーのネットワーク状態を正しく把握しておく必要がありますが、そこができていれば設定自体はかなり簡単に行えました。
（リリース直後は、同じように設定してもなぜがConnectionを作る部分うまくいきませんでしたが、今回改めて実施したところすんなり通過しました。 ~~多分何か修正が入っている~~ ）

やはりLambdaを作成しなくてもよくなるのはかなりありがたいですね。コード・ランタイム管理が不要になるのは強いです。



ConnectionはEventBridgeのイベントルールでも使用できるので、例えば特定のイベントをトリガーにJOB実行なども容易に可能です。
その場合はEventBridgeコンソールよりAPI送信先のリソースを作成してください。

クロスアカウントの場合はRAMによるリソース共有なども必要になるので、以下のドキュメントを参考に設定してみてください
https://docs.aws.amazon.com/ja_jp/eventbridge/latest/userguide/connection-private-cross-region.html