AWS Console-to-Code でコンソール操作をコード化する

# Console-to-Code とは

AWS マネジメントコンソールを使って直接 IaC 化できるツールです。

Console to Code では、CLI、Cloudformation、CDK 形式のコードに変換できます。

まあ、Console-to-Code、略するとそのままですね。

https://aws.amazon.com/jp/about-aws/whats-new/2024/10/general-availability-console-to-code-generate-code/

https://aws.amazon.com/jp/blogs/news/convert-aws-console-actions-to-reusable-code-with-aws-console-to-code-now-generally-available/


# 対応サービス

GA 時点で対応している AWS サービスは以下の通りです。

- Amazon VPC
- Amazon EC2
- Amazon RDS


# やってみる

## ステップ 1: 記録を開始

[記録を開始] ボタンを選択し、キャプチャを開始します。

![スクリーンショット 2024-11-08 20.27.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/476543c6-e9d7-4688-32ee-b54c8ec69de8.png)

## ステップ 2: アクションを選択し、CLI コマンドをコピー

適当な EC2 インスタンスを作成します。

すると、以下の通り記録されました。

![スクリーンショット 2024-11-08 20.39.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/6287edf1-b115-fcf0-4549-39f1469aedd4.png)

Read のものをどれか選択してみます。当たり前ですが「読み取りアクションは生成されたコードから除外されます。ただし、読み取り専用の CLI コマンドはコピーできます。」とのことなので、「CLI をコピー」をクリックするとシンプルな CLI がコピーできました。

![スクリーンショット 2024-11-08 20.41.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/97305a32-fa5a-0c98-a2b1-43a09d25b10f.png)

```
aws ec2 describe-instances --instance-ids "i-XXXXXXXXXX" 
```

## ステップ 3: 生成とエクスポート

無料利用枠の上限を超えた後にコードを生成するには、Amazon Q Developer Pro サブスクリプションが必要なようです。

まずは、Clouformation を生成してみます。Write のものを選択し、「CFN YAML」をクリック。

![スクリーンショット 2024-11-08 20.46.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/e425a433-eccd-45b5-ae2a-ac9c4e5a445e.png)

```yaml
Resources:
  EC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-08ce76bae392de7dc
      InstanceType: t2.micro
      KeyName: naata2
      NetworkInterfaces:
        - AssociatePublicIpAddress: true
          DeviceIndex: 0
          GroupSet:
            - sg-0d2f271a4991b3aad
      CreditSpecification:
        CPUCredits: standard
      Tags:
        - Key: Name
          Value: Console-to-Code
      MetadataOptions:
        HttpEndpoint: enabled
        HttpPutResponseHopLimit: 2
        HttpTokens: required
      PrivateDnsNameOptions:
        HostnameType: ip-name
        EnableResourceNameDnsARecord: true
        EnableResourceNameDnsAAAARecord: false
      MaxCount: 1
      MinCount: 1

Reasoning: {The provided AWS CLI commands create an EC2 instance with specific configurations. The generated CloudFormation YAML code creates an AWS::EC2::Instance resource with the corresponding properties set based on the CLI command options. The ImageId, InstanceType, KeyName, NetworkInterfaces, CreditSpecification, Tags, MetadataOptions, PrivateDnsNameOptions, and instance count are all set according to the CLI command. The code follows the CloudFormation YAML syntax and includes only the resources and properties specified in the CLI command.}
```

次に CDK を生成してみます。「CDK TypeScript を生成」をクリック。

![スクリーンショット 2024-11-08 20.49.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/91036d55-96b7-cebc-aaad-06f85c450838.png)

```typescript:
import * as ec2 from 'aws-cdk-lib/aws-ec2';

const instance = new ec2.Instance(this, 'Console-to-Code', {
  instanceType: ec2.InstanceType.of('t2.micro'),
  machineImage: ec2.MachineImage.fromAmi('ami-08ce76bae392de7dc'),
  keyName: 'naata2',
  vpc: /* Provide the VPC reference */,
  securityGroup: ec2.SecurityGroup.fromSecurityGroupId(this, 'SG', 'sg-0d2f271a4991b3aad'),
  creditSpecification: {
    cpuCredits: ec2.CpuCredits.STANDARD,
  },
  instanceInitOptions: {
    associatePublicIpAddress: true,
    metadataOptions: {
      httpEndpoint: ec2.HttpEndpointMetadataService.ENABLED,
      httpPutResponseHopLimit: 2,
      httpTokens: ec2.HttpTokensMetadataService.REQUIRED,
    },
    privateDnsNameOptions: {
      hostnameType: ec2.HostnameType.IP_NAME,
      enableResourceNameDnsARecord: true,
      enableResourceNameDnsAAAARecord: false,
    },
  },
});

instance.node.addMetadata('aws:cdk:asset-metadata', {
  'aws:asset-metadata:path': '/path/to/asset',
});

instance.node.addMetadata('aws:cdk:asset-metadata:package', {
  'aws:cdk:asset-metadata:package:path': '/path/to/asset.zip',
});

instance.node.addMetadata('aws:cdk:asset-metadata:package:md5', {
  'aws:cdk:asset-metadata:package:md5': 'md5hash',
});

instance.node.addMetadata('aws:cdk:asset-metadata:info', {
  'aws:cdk:asset-metadata:info': 'some info',
});

instance.node.addMetadata('aws:cdk:asset-metadata:source', {
  'aws:cdk:asset-metadata:source': 'source',
});

instance.node.addMetadata('aws:cdk:asset-metadata:service', {
  'aws:cdk:asset-metadata:service': 'ec2',
});

instance.node.addMetadata('aws:cdk:asset-metadata:computed', {
  'aws:cdk:asset-metadata:computed': 'computed',
});

instance.node.addMetadata('aws:cdk:asset-metadata:path', {
  'aws:cdk:asset-metadata:path': '/path/to/asset',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image', {
  'aws:cdk:asset-metadata:docker-image': 'docker-image',
});

instance.node.addMetadata('aws:cdk:asset-metadata:hash', {
  'aws:cdk:asset-metadata:hash': 'hash',
});

instance.node.addMetadata('aws:cdk:asset-metadata:id', {
  'aws:cdk:asset-metadata:id': 'id',
});

instance.node.addMetadata('aws:cdk:asset-metadata:packaging', {
  'aws:cdk:asset-metadata:packaging': 'zip',
});

instance.node.addMetadata('aws:cdk:asset-metadata:local-path', {
  'aws:cdk:asset-metadata:local-path': '/path/to/local/asset',
});

instance.node.addMetadata('aws:cdk:asset-metadata:s3-bucket', {
  'aws:cdk:asset-metadata:s3-bucket': 'bucket-name',
});

instance.node.addMetadata('aws:cdk:asset-metadata:s3-key', {
  'aws:cdk:asset-metadata:s3-key': 'key',
});

instance.node.addMetadata('aws:cdk:asset-metadata:last-modified', {
  'aws:cdk:asset-metadata:last-modified': 'last-modified-time',
});

instance.node.addMetadata('aws:cdk:asset-metadata:source-hash', {
  'aws:cdk:asset-metadata:source-hash': 'source-hash',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-digest', {
  'aws:cdk:asset-metadata:docker-image-digest': 'docker-image-digest',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-details', {
  'aws:cdk:asset-metadata:docker-image-details': 'docker-image-details',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-manifest', {
  'aws:cdk:asset-metadata:docker-image-manifest': 'docker-image-manifest',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-repository', {
  'aws:cdk:asset-metadata:docker-image-repository': 'docker-image-repository',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-tag', {
  'aws:cdk:asset-metadata:docker-image-tag': 'docker-image-tag',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-uri', {
  'aws:cdk:asset-metadata:docker-image-uri': 'docker-image-uri',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-version', {
  'aws:cdk:asset-metadata:docker-image-version': 'docker-image-version',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-version-digest', {
  'aws:cdk:asset-metadata:docker-image-version-digest': 'docker-image-version-digest',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-version-details', {
  'aws:cdk:asset-metadata:docker-image-version-details': 'docker-image-version-details',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-version-manifest', {
  'aws:cdk:asset-metadata:docker-image-version-manifest': 'docker-image-version-manifest',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-version-repository', {
  'aws:cdk:asset-metadata:docker-image-version-repository': 'docker-image-version-repository',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-version-tag', {
  'aws:cdk:asset-metadata:docker-image-version-tag': 'docker-image-version-tag',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-version-uri', {
  'aws:cdk:asset-metadata:docker-image-version-uri': 'docker-image-version-uri',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-version-version', {
  'aws:cdk:asset-metadata:docker-image-version-version': 'docker-image-version-version',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-version-version-digest', {
  'aws:cdk:asset-metadata:docker-image-version-version-digest': 'docker-image-version-version-digest',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-version-version-details', {
  'aws:cdk:asset-metadata:docker-image-version-version-details': 'docker-image-version-version-details',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-version-version-manifest', {
  'aws:cdk:asset-metadata:docker-image-version-version-manifest': 'docker-image-version-version-manifest',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-version-version-repository', {
  'aws:cdk:asset-metadata:docker-image-version-version-repository': 'docker-image-version-version-repository',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-version-version-tag', {
  'aws:cdk:asset-metadata:docker-image-version-version-tag': 'docker-image-version-version-tag',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-version-version-uri', {
  'aws:cdk:asset-metadata:docker-image-version-version-uri': 'docker-image-version-version-uri',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-version-version-version', {
  'aws:cdk:asset-metadata:docker-image-version-version-version': 'docker-image-version-version-version',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-version-version-version-digest', {
  'aws:cdk:asset-metadata:docker-image-version-version-version-digest': 'docker-image-version-version-version-digest',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-version-version-version-details', {
  'aws:cdk:asset-metadata:docker-image-version-version-version-details': 'docker-image-version-version-version-details',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-version-version-version-manifest', {
  'aws:cdk:asset-metadata:docker-image-version-version-version-manifest': 'docker-image-version-version-version-manifest',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-version-version-version-repository', {
  'aws:cdk:asset-metadata:docker-image-version-version-version-repository': 'docker-image-version-version-version-repository',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-version-version-version-tag', {
  'aws:cdk:asset-metadata:docker-image-version-version-version-tag': 'docker-image-version-version-version-tag',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-version-version-version-uri', {
  'aws:cdk:asset-metadata:docker-image-version-version-version-uri': 'docker-image-version-version-version-uri',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-version-version-version-version', {
  'aws:cdk:asset-metadata:docker-image-version-version-version-version': 'docker-image-version-version-version-version',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-version-version-version-version-digest', {
  'aws:cdk:asset-metadata:docker-image-version-version-version-version-digest': 'docker-image-version-version-version-version-digest',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-version-version-version-version-details', {
  'aws:cdk:asset-metadata:docker-image-version-version-version-version-details': 'docker-image-version-version-version-version-details',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-version-version-version-version-manifest', {
  'aws:cdk:asset-metadata:docker-image-version-version-version-version-manifest': 'docker-image-version-version-version-version-manifest',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-version-version-version-version-repository', {
  'aws:cdk:asset-metadata:docker-image-version-version-version-version-repository': 'docker-image-version-version-version-version-repository',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-version-version-version-version-tag', {
  'aws:cdk:asset-metadata:docker-image-version-version-version-version-tag': 'docker-image-version-version-version-version-tag',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-version-version-version-version-uri', {
  'aws:cdk:asset-metadata:docker-image-version-version-version-version-uri': 'docker-image-version-version-version-version-uri',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-version-version-version-version-version', {
  'aws:cdk:asset-metadata:docker-image-version-version-version-version-version': 'docker-image-version-version-version-version-version',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-version-version-version-version-version-digest', {
  'aws:cdk:asset-metadata:docker-image-version-version-version-version-version-digest': 'docker-image-version-version-version-version-version-digest',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-version-version-version-version-version-details', {
  'aws:cdk:asset-metadata:docker-image-version-version-version-version-version-details': 'docker-image-version-version-version-version-version-details',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-version-version-version-version-version-manifest', {
  'aws:cdk:asset-metadata:docker-image-version-version-version-version-version-manifest': 'docker-image-version-version-version-version-version-manifest',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-version-version-version-version-version-repository', {
  'aws:cdk:asset-metadata:docker-image-version-version-version-version-version-repository': 'docker-image-version-version-version-version-version-repository',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-version-version-version-version-version-tag', {
  'aws:cdk:asset-metadata:docker-image-version-version-version-version-version-tag': 'docker-image-version-version-version-version-version-tag',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-version-version-version-version-version-uri', {
  'aws:cdk:asset-metadata:docker-image-version-version-version-version-version-uri': 'docker-image-version-version-version-version-version-uri',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-version-version-version-version-version-version', {
  'aws:cdk:asset-metadata:docker-image-version-version-version-version-version-version': 'docker-image-version-version-version-version-version-version',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-version-version-version-version-version-version-digest', {
  'aws:cdk:asset-metadata:docker-image-version-version-version-version-version-version-digest': 'docker-image-version-version-version-version-version-version-digest',
});

instance.node.addMetadata('aws:cdk:asset-metadata:docker-image-version-version-version-version-version-version-details', {
  'aws:cdk:asset-metadata:docker-image-version-version-version-
```


# 所感

今回はサービス単体で利用してみましたが、更に Console-to-Code で利用できるサービスが増えた場合にどうでしょうか？複数サービスを選択したときに上手く循環参照などは解消してくれるのかが疑問に残ります。また、CDK の場合はコンストラクトで構成する場合も多いと思いますのでちょっと実際の利用にはまだまだこれからに期待と言った気がします。