AWS環境からOCIリソースのAPI操作(Secrets Managerを使用)

## 概要
AWS EC2からPythonを使用してOCIリソースのAPI操作(Computeの開始操作)を行います。
OCI資格情報について下記の投稿ではEC2内に配置していましたが、今回の記事ではOCI資格情報をSecrets Managerに保存してセキュリティを高めています。

[AWS環境からOCIリソースのAPI操作](https://qiita.com/tktk2712/items/7ae9080471ae4935cb13)

<font color="red">(トークンベース認証方法から通常のAPI認証に変更しました）</font>

## 構成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730992/d9c956eb-d7a4-08a2-9476-81d1349f1901.png)

## 設定手順
* AWS Secrets Managerへのアクセス許可
EC2からAWS Secrets Managerへのアクセス許可付与します。
付与方法については公式情報等を参考に設定するためここでは割愛します。
[AWS Secrets Manager の認証とアクセスコントロール](https://docs.aws.amazon.com/ja_jp/secretsmanager/latest/userguide/auth-and-access.html)

* OCI資格情報取得
OCIリソース操作可能なOCIユーザーIDの資格情報を取得します。
[コマンドライン(CLI)でOCIを操作する](https://oracle-japan.github.io/ocitutorials/intermediates/using-cli/)

* OCI Compute OCID
OCIコンソールにログインしてCompute>Instanceから対象のInstanceを選択してOCIDを入手します

* Python実行可能なEC2の準備
EC2にAWS CLIやPythonをインストールします。

* ociライブラリ追加
ociライブラリを使用するのでPython実行可能なEC2にpip installコマンドを実行します
```
pip3 install oci
```

* Secrets Managerに資格情報を配置するための準備
取得したOCI資格情報を元にJSON形式でテキストを作成します
    * oci_api_key
oci_api_key:ファイルoci_api_key.pemから"-----BEGIN PRIVATE KEY-----"および"-----END PRIVATE KEY-----"を取り除きLF文字を\nに置換します。
```
例
元情報
-----BEGIN PRIVATE KEY-----
aaaaaaaaaa
aaaaaaaaaa
aaaaaaaaaa
-----END PRIVATE KEY-----

変換後
aaaaaaaaaa\naaaaaaaaaa\naaaaaaaaaa
```
*
    * fingerprint：configファイルのfingerprint項目
    * user：configファイルのuser項目またはOCIコンソールメニューから アイデンティティ>ドメイン>Default>ユーザーで対象のユーザーIDを選択しOCIDを取得
    * tenancy：configファイルのtenancy項目
    * region：configファイルのregion項目
```
作成例
{"oci_api_key":"aaaaaaaaaa\naaaaaaaaaa\naaaaaaaaaa","fingerprint":"**:**:**:**:**","user":"ocid1.user.oc1*****","tenancy":"ocid1.tenancy.oc1*****","region":"*****"}

```
 
* Secrets Managerに資格情報を配置
AWS マネジメントコンソールにログインして、AWS Secrets Manager>シークレットを選択して新しいシークレットを保存するを押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730992/dcdc6b48-0f9c-a824-bffc-be7dae96d9bd.png)
その他のシークレットのタイプを選択し、プレーンテキストに先ほど作成したJSONテキストを貼り付けて次を押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730992/dfadecf1-882b-ef4e-f6e7-726dca957a91.png)
シークレットの名前に名前を入力して次を押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730992/12345c2b-9cbf-aa70-c30c-2773c8bce9f2.png)
今回はローテーションを設定しないので次を押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730992/fc8fa821-1b19-d6be-e580-51a87ff4ddd3.png)
設定を確認して保存

正常に保管できたことを確認します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730992/c815192b-383c-4fa9-2139-f1ea2023030f.png)

* Pythonコード
```pythonコード.py
import oci
import boto3
from botocore.exceptions import ClientError
import ast

# Secretmanager
session = boto3.session.Session()
client = session.client(
    service_name='secretsmanager',
    region_name='ap-northeast-1'
    )

#OCI config
get_secret_value_response = client.get_secret_value(
    SecretId= 'OCIuser'
    )

secret_data = get_secret_value_response['SecretString']
secret = ast.literal_eval(secret_data)
fingerprint = secret['fingerprint']
oci_api_key = secret['oci_api_key']
user = secret['user']
tenancy = secret['tenancy']
region = secret['region']

pem_prefix = '-----BEGIN RSA PRIVATE KEY-----\n'
pem_suffix = '\n-----END RSA PRIVATE KEY-----'
key_content = '{}{}{}'.format(pem_prefix, oci_api_key, pem_suffix)

config = {
    "user": user,
    "key_content": key_content,
    "fingerprint": fingerprint,
    "tenancy": tenancy,
    "region": region
    }

oci.config.validate_config(config)

# VM action
core_client = oci.core.ComputeClient(config, service_endpoint='https://iaas.【リージョン】.oraclecloud.com')

instance_action_response = core_client.instance_action(
    instance_id="【開始するComputeのOCID】",
    action="START")

print(instance_action_response.data)
```
参考
[Docs » API Reference » Core Services » ComputeClient](https://docs.oracle.com/en-us/iaas/tools/python/2.112.0/api/core/client/oci.core.ComputeClient.html)
[oci-python-sdk/examples/configuration_example.py](
https://github.com/oracle/oci-python-sdk/blob/master/examples/configuration_example.py)

## 実行結果
成功すれば以下のようなレスポンスが返ってきます。
また、OCIコンソールで該当Computeを確認すると開始に成功しています。
```
$ python3 pythonコード.py
{
  略
  "display_name": "開始するComputeのインスタンス名",
  "id": "開始するComputeのOCID",
  略
  "lifecycle_state": "STARTING",
  略
}
```