EC2+RDS Proxy+SecretsManager+RDS

# はじめに
今年のカレンダーはとある会社のとあるチームで活動した1年間を振り返っていきます

今回は業務で初めてAWSを触ったときの自己学習を備忘録として残していたので供養します
少し情報が古い可能性もありますので、ご注意ください。

# やりたいこと
- EC2を踏み台にしてRDSに接続
- RDS接続は、SecretsManagerを使ってRDS Proxy経由で行う

## インバウンドルールの設定
- 各リソースやネットワーク系の構築に加えてネットワーク間の通信設定が必要
- ec2からproxyを経由してrdsへアクセスしたいので、インバウンドルールの設定をする
    - ec2からproxyにアクセスする許可を設定したいので、proxyのインバウンドルールにec2のIPアドレスを指定 
    - proxyからrdsにアクセスする許可を設定したいので、rdsのインバウンドルールにproxyのIPアドレスを指定

# 構成図
![qita_aws.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2889192/74f43783-a707-dd43-5da6-634623853544.png)


# cloudformationのテンプレート

ファイルに記載する基本的な構成は以下の通り
```yaml
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
  UserName:
    Description: Type of this UserName.
    Type: String

Resources:
  QiitaUser:
    Type: AWS::IAM::User
    Properties:
      UserName: !Sub "${UserName}"
```

|  プロパティ  |  概要  |
| :--- | :--- |
|AWSTemplateFormatVersion|テンプレート形式を指定|
|Parameters|一部の項目を変数にできる。同じ構成で複数の環境を立てる際に使える|
|Resource|使用するAWSリソースを指定|
|Logical ID|テンプレート内でユニークなID。他リソースから参照するときに使える|
|Type|AWSリソースプロパティタイプのリファレンスに一覧がある|
|Properties|リソース作成時に指定する。タイプによって利用できるプロパティが異なるので、公式ドキュメントなどを参考に指定する|
|tags|リソースに命名できる|
|Outputs|作成したスタックの出力タブに指定した値を表示させることができる|

- !Sub "${hoge}" ：リージョン名やID、スタック名などをパラメータ参照できる
- !Ref hoge　：指定したリソースの値を返す事ができる
- !GetAtt：　リソースの属性を返せる(リソースによって返せる値は異なる)

### export/import

```stackA.yml
Outputs:
  OutputQiitaName:
    Value: !Ref QiitaName
    Export:
      Name: ExportQiitaName
  OutputQiitaArn:
    Value: !GetAtt Qiita.Arn
    Export:
      Name: ExportQiitaArn
```

```stackB.yml
Resources:
 Qiita:
    Type:
    Properties:
      hogeName: !ImportValue ExportQiitaName
      hogeArn: !ImportValue ExportQiitaArn
```

- スタックAでexportしたNameやArnは、スタックBでimportすると参照できる
- !ImportValue :別のスタックでエクスポートされた値を参照できる
- exportはOutputsで出力したい値を指定
- exportされている値の一覧は ```aws cloudformation list-exports``` で確認できる

## IAMスタックを作成
以下のqita_iam.ymlを使用してcloudformationでスタックを作成

```qiita_iam.yml
AWSTemplateFormatVersion: "2010-09-09"
Description: Create IAM

Parameters:
  UserName:
    Description: Type of this UserName.
    Type: String

Resources:
  # ------------------------------------------------------------#
  #  qiita IAM User
  # ------------------------------------------------------------#
  QiitaIAMUser:
    Type: AWS::IAM::User
    Properties:
      UserName: !Sub "${UserName}"
      Tags:
        - Key: "name"
          Value: "qiita"
  QiitaIAMUserAccessKey:
    Type: AWS::IAM::AccessKey
    Properties:
      UserName: !Ref QiitaIAMUser

  QiitaIAMUserAccessKeySecret:
    Type: AWS::SecretsManager::Secret
    Properties:
      Name:
        Fn::Sub: "${QiitaIAMUser}-credentials"
      SecretString:
        Fn::Sub: '{"accessKeyId":"${QiitaIAMUserAccessKey}","secretAccessKey":"${QiitaIAMUserAccessKey.SecretAccessKey}"}'

Outputs:
  AccessKey:
    Value: !Ref QiitaIAMUserAccessKey
  SecretAccessKey:
    Value: !GetAtt QiitaIAMUserAccessKey.SecretAccessKey

```

- 作成したファイルをアップロードしてスタックを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2889192/125374b4-5cd0-f6cf-1aee-aa1245a4a5a0.png)


- スタックの作成に成功すると、CREATE_COMPLETEと表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2889192/83743730-0dad-9773-be5f-7bc39378fca7.png)

- qiita_iam.ymlのOutputsで記載したAccessKeyとSecretAccessKeyが「出力」タブに表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2889192/89afdced-33da-4966-ab69-3709ca6c84d5.png)

## ネットワーク系のスタックを作成(VPC、Subnet、SecurityGroup、RouteTable、InternetGateway)

https://www.techpit.jp/courses/77/curriculums/80/sections/609/parts/2060

- 以下のqiita_network.ymlをcloudformationにアップロードしてスタックを作成

```qiita_network.yml
Parameters:
  ProjectName:
    Description: Type of this ProjectName.
    Type: String

Resources:
  # ------------------------------------------------------------#
  #  vpc
  # ------------------------------------------------------------#
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/22
      Tags:
        - Key: "Name"
          Value: "qiita"

  # ------------------------------------------------------------#
  #  InternetGateway
  # ------------------------------------------------------------#
  InternetGateway:
    Type: "AWS::EC2::InternetGateway"
    Properties:
      Tags:
        - Key: Name
          Value: !Sub "${ProjectName}-igw"

  InternetGatewayAttachment:
    Type: "AWS::EC2::VPCGatewayAttachment"
    Properties:
      InternetGatewayId: !Ref InternetGateway
      VpcId: !Ref VPC

  # ------------------------------------------------------------#
  #  subnet
  # ------------------------------------------------------------#
  PublicSubnetA:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.0.0/24
      MapPublicIpOnLaunch: true
      AvailabilityZone: ap-northeast-1a
      Tags:
        - Key: "Name"
          Value: !Sub "${ProjectName}-public-subnet"
  PublicSubnetC:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.1.0/24
      MapPublicIpOnLaunch: true
      AvailabilityZone: ap-northeast-1c
      Tags:
        - Key: "Name"
          Value: !Sub "${ProjectName}-public-subnetC"
  PrivateSubnetA:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.2.0/24
      AvailabilityZone: ap-northeast-1a
      Tags:
        - Key: "Name"
          Value: !Sub "${ProjectName}-private-subnetA"
  PrivateSubnetC:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.3.0/24

      AvailabilityZone: ap-northeast-1c
      Tags:
        - Key: "Name"
          Value: !Sub "${ProjectName}-private-subnetC"

  # ------------------------------------------------------------#
  #  RouteTable
  # ------------------------------------------------------------#
  PublicRouteTableA:
    Type: "AWS::EC2::RouteTable"
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: "Name"
          Value: !Sub "${ProjectName}-public-routetableA"

  PublicRouteA:
    Type: "AWS::EC2::Route"
    Properties:
      RouteTableId: !Ref PublicRouteTableA
      DestinationCidrBlock: "0.0.0.0/0"
      GatewayId: !Ref InternetGateway

  PublicRouteAssociationA:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref PublicRouteTableA
      SubnetId: !Ref PublicSubnetA

  PublicRouteTableC:
    Type: "AWS::EC2::RouteTable"
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: "Name"
          Value: !Sub "${ProjectName}-public-routetableC"

  PublicRouteC:
    Type: "AWS::EC2::Route"
    Properties:
      RouteTableId: !Ref PublicRouteTableC
      DestinationCidrBlock: "0.0.0.0/0"
      GatewayId: !Ref InternetGateway

  PublicRouteAssociationC:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref PublicRouteTableC
      SubnetId: !Ref PublicSubnetC
```

### VPC

|  プロパティ  |  概要  |
| :--- | :--- |
|CidrBlock|IPv4 CIDRブロック。作成するVPCにおけるIPアドレスの範囲|
|EnableDnsHostnames|DNSホスト名取得の有効/無効|
|EnableDnsSupport|VPCに対してDNS解決がサポートされているかどうか|
|InstanceTenancy|VPC内に起動されるインスタンスの許可されているテナンシー(設定するとEC2の料金が割増になる)|

- EC2 等のインスタンスはサブネット内で起動する。サブネットはVPC内に配置する必要があるため、VPCから作成
    - VPCの中にサブネットを作成(private/public)
    - VPCの作成には CIDR を1つだけ設定
    - 各サブネットにアベイラビリティゾーンを用意

### Subnet

|  プロパティ  |  概要  |
| :--- | :--- |
|VpcId|サブネットを作成するVPCのID|
|AvailabilityZone|サブネットを作成するアベイラビリティゾーン|
|CidrBlock|作成するサブネットにおけるIPアドレスの範囲|
|MapPublicIpOnLaunch|サブネットで起動されたインスタンスがパブリック IPv4 アドレスを受け取るかどうか。パブリックサブネットでは true、プライベートサブネットでは false を指定|

- 今回はEC2を配置するパブリックサブネットと、RDB サーバーを配置するプライベートサブネットの計3つを作成。
- プライベートサブネットに対してはAZを2つ用意し、冗長化
- 今回は 10.0.1.0/24 , 10.0.2.0/24 , 10.0.3.0/24 の3つのサブネットを作成

### InternetGateway

|  プロパティ  |  概要  |
| :--- | :--- |
|InternetGatewayId|インターネットゲートウェイのID|
|VpcId|VPC ID|
|VpnGatewayId|仮想プライベートゲートウェイのID|

- インターネットとVPCをつなぐ役割
インターネットゲートウェイはVPCに関連付ける

### RouteTable

|  プロパティ  |  概要  |
| :--- | :--- |
|DestinationCidrBlock|ルーティング先の照合に使用するIPv4CIDRブロック|
|DestinationIpv6CidrBlock|ルーティング先の照合に使用するIPv6CIDRブロック|
|EgressOnlyInternetGatewayId|EgressOnlyインターネットゲートウェイID|
|GatewayId|ゲートウェイID|
|InstanceId|NATインスタンスID|
|NatGatewayId|NATゲートウェイID|
|NetworkInterfaceId|ネットワークインターフェイスID|
|RouteTableId|ルートテーブルID|
|TransitGatewayId|トランジットゲートウェイID|
|VpcPeeringConnectionId|VPC ピア接続ID|

- ネットワーク経路を示す役割
- 1つのサブネットに1つのルートテーブルを用意
- ルートテーブルへのアタッチはRouteTableId:で指定
- Type: AWS::EC2::SubnetRouteTableAssociationで、インターネットへ抜けられるサブネットを指定


### RDS MySQL Aurora

secret&rds
https://techblog.nhn-techorus.com/archives/17674

セキュリティグループも一緒につくる
依存関係はよしなにしてくれる

```qita_rds.yml
Parameters:
  ProjectName:
    Description: Type of this ProjectName.
    Type: String
  VPC:
    Type: "AWS::EC2::VPC::Id"
  SubnetIds:
    Type: List<AWS::EC2::Subnet::Id>
  DBName:
    Description: Type of this DatabaseName example sample_db.
    Type: String
  DBPassword:
    Description: Type of this DatabasePassword.
    Type: String
  # ProxyTargetDBClusterIdentifiers:
  #     Type: CommaDelimitedList

Resources:
  DBCluster:
    Type: AWS::RDS::DBCluster
    Properties:
      DBClusterIdentifier: !Sub "${ProjectName}-db-cluster"
      DBSubnetGroupName: !Ref "DBSubnetGroup"
      DatabaseName: !Sub "${DBName}"
      Engine: aurora-mysql
      EngineMode: "serverless"
      EngineVersion: "5.7.mysql_aurora.2.10.2"
      DBClusterParameterGroupName: !Ref DBParameterGroup
      # MasterUserPassword: !Sub "${DBPassword}"
      # MasterUsername: admin
      MasterUsername: !Join ['', ['{{resolve:secretsmanager:', !Ref SecretManager, ':SecretString:username}}' ]]
      MasterUserPassword: !Join ['', ['{{resolve:secretsmanager:', !Ref SecretManager, ':SecretString:password}}' ]]
      StorageEncrypted: true
      ScalingConfiguration:
        MinCapacity: 1
        AutoPause: false
        MaxCapacity: 2
      VpcSecurityGroupIds:
        - !Ref AuroraSecurityGroup
      DBSubnetGroupName: !Ref DBSubnetGroup
    DeletionPolicy: Delete

  # ------------------------------------------------------------#
  #  parameter group
  # ------------------------------------------------------------#
  DBParameterGroup:
    Type: AWS::RDS::DBClusterParameterGroup
    Properties:
      Family: aurora-mysql5.7
      Description: Database Parameter Group
      Parameters:
        character_set_database: utf8mb4
        character_set_client: utf8mb4
        character_set_connection: utf8mb4
        character_set_results: utf8mb4
        character_set_server: utf8mb4
        time_zone: Asia/Tokyo

  # ------------------------------------------------------------#
  #  subnet group
  # ------------------------------------------------------------#
  DBSubnetGroup:
    Type: AWS::RDS::DBSubnetGroup
    Properties:
      DBSubnetGroupName: !Sub "${ProjectName}-db-subnet-group"
      DBSubnetGroupDescription: for db
      SubnetIds: !Split [",", !Join [",", !Ref SubnetIds]]

  # ------------------------------------------------------------#
  #  security group
  # ------------------------------------------------------------#
  AuroraSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: SecurityGroup for Aurora
      VpcId: !Sub "${VPC}"
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 3306
          ToPort: 3306
          CidrIp: 10.0.1.0/24
      Tags:
        - Key: "Name"
          Value: !Sub "${ProjectName}-db-sg"
    # DependsOn: VPC

  # ------------------------------------------------------------#
  #  secret manager
  # ------------------------------------------------------------#
  SecretManager:
    Type: AWS::SecretsManager::Secret
    Properties: 
      Description: "Secrets Manager for RDS"
      SecretString:
        !Sub '{"username": "admin","password": "${DBPassword}"}'
      Name: !Sub "${ProjectName}-Secrets"
      Tags:
        - Key: Name
          Value: !Sub ${ProjectName}-Secrets

  SecretManagerAttachment:
    Type: AWS::SecretsManager::SecretTargetAttachment
    Properties: 
      SecretId: !Ref SecretManager
      TargetId: !Ref DBCluster
      TargetType: AWS::RDS::DBCluster



  QitaRDSInstance:
    Type: AWS::RDS::DBInstance
    Properties:
      AllocatedStorage: 5
      DBInstanceClass: db.t3.small
      Engine: MySQL
      MasterUsername: !Join ['', ['{{resolve:secretsmanager:', !Ref SecretManager, ':SecretString:username}}' ]]
      MasterUserPassword: !Join ['', ['{{resolve:secretsmanager:', !Ref SecretManager, ':SecretString:password}}' ]]
      BackupRetentionPeriod: 0
      DBInstanceIdentifier: 'qiita-proxy-instance'
 
  QitaRDSProxy:
    Type: AWS::RDS::DBProxy
    Properties:
      DBProxyName: !Sub "QitaRDBProxyName"
      EngineFamily: MYSQL
      RoleArn: !GetAtt IAMRole.Arn
      Auth:
        - AuthScheme: SECRETS
        # プロキシが使用するシークレットを選択
          SecretArn: !Ref "SecretManager"
      # RDS Proxyにアタッチするセキュリティグループ
      VpcSecurityGroupIds:
        - !ImportValue EC2-SG
        # RDS Proxyを構築するVPC Subnet
        # 選択したvpcでデータベースが使用可能なIP範囲を指定
      VpcSubnetIds:
        - !ImportValue private-subnetA
        - !ImportValue private-subnetC

  QitaRDSProxyTargetGroup:
    Type: AWS::RDS::DBProxyTargetGroup
    DependsOn:
      - QitaRDSInstance
    Properties:
      DBProxyName: !Ref QitaRDSProxy
      TargetGroupName: default
      # Proxyが接続するRDS Auroraクラスターの識別子
      # DBClusterIdentifier: !Ref DBCluster
      DBInstanceIdentifiers: 
        - !Ref QitaRDSInstance
      # DBClusterIdentifiers: !Ref ProxyTargetDBClusterIdentifiers

  RDSProxySecurityGroup:
    Type: "AWS::EC2::SecurityGroup"
    Properties:
      GroupDescription: "RDS Proxy security group"
      VpcId: !Sub "${VPC}"
      SecurityGroupIngress: 
        # ec2のIPアドレスをインバウンドルールに設定
        - SourceSecurityGroupId: !ImportValue EC2-SG
          IpProtocol: "tcp"
          FromPort: 3306
          ToPort: 3306

  IAMRole:
      Type: "AWS::IAM::Role"
      Properties:
          AssumeRolePolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Principal:
                  Service:
                    - rds.amazonaws.com
                Action:
                  - 'sts:AssumeRole'
          ManagedPolicyArns: 
            - !Ref IAMPolicy


  IAMPolicy:
      Type: "AWS::IAM::ManagedPolicy"
      Properties:
          PolicyDocument: |
              {
                  "Version": "2012-10-17",
                  "Statement": [
                      {
                          "Sid": "GetSecretValue",
                          "Action": [
                              "secretsmanager:GetSecretValue",
                              "secretsmanager:GetResourcePolicy",
                              "secretsmanager:DescribeSecret",
                              "secretsmanager:ListSecretVersionIds"
                          ],
                          "Effect": "Allow",
                          "Resource": [
                              "*"
                          ]
                      },
                      {
                          "Sid": "DecryptSecretValue",
                          "Action": [
                              "kms:Decrypt"
                          ],
                          "Effect": "Allow",
                          "Resource": [
                              "*"
                          ],
                          "Condition": {
                              "StringEquals": {
                                  "kms:ViaService": "secretsmanager.ap-northeast-1.amazonaws.com"
                              }
                          }
                      }
                  ]
              }

Outputs:
  Endpoint:
    Value: !GetAtt DBCluster.Endpoint.Address
  ResourceArn:
    Value: !Sub "arn:aws:rds:ap-northeast-1:${AWS::AccountId}:cluster:${ProjectName}-db-cluster"
  SecretArn:
    Value: !Ref SecretManagerAttachment
```
### security group

|  プロパティ  |  概要  |
| :--- | :--- |
|GroupDescription|セキュリティグループの説明|
|GroupName|セキュリティグループの名前|
|SecurityGroupIngress|インバウンドルールを宣言|
|IpProtocol|IPプロトコル|
|FromPort|ポート範囲の開始番号|
|FromPort|ポート範囲の終了番号|
|CidrIp|IPv4の範囲|
|VpcId|VPCのID|

### Type: AWS::RDS::DBProxy

|  プロパティ  |  概要  |
| :--- | :--- |
|DBProxyName|作成するRDS Proxy名|
|EngineFamily||
|RequireTLS|TLSが必須かどうか|
|RoleArn|RDS Proxyに設定するIAM Role|
|Auth|Secrets Managerを利用してユーザ名とパスワードで認証|
|VpcSecurityGroupIds|RDS Proxyにアタッチするセキュリティグループ|
|VpcSubnetIds|RDS Proxyを構築するVPC Subnet|


### Type: AWS::RDS::DBProxyTargetGroup

|  プロパティ  |  概要  |
| :--- | :--- |
|DBProxyName|AWS::RDS::DBProxyで作成したRDS Proxy名|
|TargetGroupName|ターゲットグループ名はdefaultが必須|

### Type: "AWS::EC2::SecurityGroup"
|  プロパティ  |  概要  |
| :--- | :--- |
|SecurityGroupIngress|ec2のIPアドレスをインバウンドルールに設定|


## ec2

```qita_ec2.yml
Parameters:
  ProjectName:
    Description: Type of this ProjectName.
    Type: String
  KeyName:
    Description: The EC2 Key Pair to allow SSH access to the instance
    Type: "AWS::EC2::KeyPair::KeyName"
  PubSub:
    Type: "AWS::EC2::Subnet::Id"
  VPC:
    Type: "AWS::EC2::VPC::Id"

Resources:
  # ------------------------------------------------------------#
  #  ec2
  # ------------------------------------------------------------#
  EC2:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-078296f82eb463377
      KeyName: !Ref KeyName
      InstanceType: t2.micro
      NetworkInterfaces:
        - AssociatePublicIpAddress: "true"
          DeviceIndex: "0"
          SubnetId: !Ref PubSub
          GroupSet:
            - !Ref EC2SG
      UserData: !Base64 |
        #!/bin/bash
        sudo yum install -y mysql
      Tags:
        - Key: Name
          Value: !Sub "${ProjectName}-ec2"

  # ------------------------------------------------------------#
  #  ec2 security group
  # ------------------------------------------------------------#
  EC2SG:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: !Sub "${ProjectName}-ec2-sg"
      GroupDescription: Allow SSH access only MyIP
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
# グローバルIP
          CidrIp: 0.0.0.0
Outputs:
  EC2PublicIP:
    Value: !GetAtt EC2.PublicIp
    Description: Public IP of EC2 instance

```

|  プロパティ  |  概要  |
| :--- | :--- |
|ImageId|マシンイメージのIDを使用。インスタンスを起動するのに必要なOSやボリューム情報などのテンプレートのこと|
|keyname|キーペア名|

https://maku.blog/p/pcp3doy/

- キーペアの作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2889192/21baf0a9-f423-4898-f48e-e686463f168f.png)


- EC2へセキュリティを考慮したSSH接続をするための認証方式にキーペアを使用。
1つは自身で管理するプライベートキー。もう1つはEC2のインスタンスに保管されるパブリックキー。

ssh pemについて
https://qiita.com/miriwo/items/3da2391f37dab6b5452c
https://blog.recruit.co.jp/rmp/infrastructure/retry-aws-bastion-host-vpc/

ec2へのssh接続を確認するコマンドは以下
```
ssh -i ~/.ssh/hoge-ec2.pem ec2-user@EC2のpublicIP
```


https://dev.classmethod.jp/articles/aws-beginner-ec2-ssh/

このような表示がされればOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2889192/3efb9fa8-1f2b-977d-6e15-8bc5242513a8.png)

mysqlへ接続
```
mysql -u username -p -h RDSのエンドポイント
```

secret managerで作成したパスワードを入力すると接続が確認できる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2889192/996e40fa-43aa-16e0-0661-68812a338c93.png)




# 参考
CloudFormationテンプレート
https://dev.classmethod.jp/articles/cloudformation-beginner01/

組み込み関数
https://dev.classmethod.jp/articles/cloudformation-tips-focused-on-refs/

cloudformationメモ
https://www.magata.net/memo/index.php?AWS%20CloudFormation%A5%E1%A5%E2

ネットワークの構築
https://qiita.com/kono-hiroki/items/6863aa06754fb25f28fc

VPC とサブネット
https://zenn.dev/tmasuyama1114/articles/aws-cloudformation-basics

ネットワーク系
https://zenn.dev/anaka/articles/627d0a112d57ed

インバウンドルール
https://qiita.com/yz2cm/items/2448f1545fef406ce8e3

lambda/secrets
https://www.seeds-std.co.jp/blog/creators/2021-08-13-002824/

cloudformationに秘密情報を渡す
https://techblog.zozo.com/entry/pass_secrets_to_cloudformation

ダイナミックリファレンスでシークレットを取得
https://docs.aws.amazon.com/ja_jp/secretsmanager/latest/userguide/cfn-example_reference-secret.html

https://zenn.dev/hamo/articles/c61d0a0f0dafd7

proxyはsecretをどのように利用しているのか
https://dev.classmethod.jp/articles/how-rdsproxy-uses-secrets-manager/

https://qiita.com/horitomoyuki/items/22aab25efcbc6d25655c

proxyの構築
https://qiita.com/homoluctus/items/be6c9565ddd615d1d9ac

IAMroleにsecretへの権限許可
https://dev.classmethod.jp/articles/rds-proxy-useradd/