oci iam compartment list
Table of Contents
- 1. Getting Started
- 2. What you will need
- 3. Oracle Cloud Vault
- 4. The Application
- 5. Creating an Oracle Cloud Vault
- 6. Using Vault with Micronaut
- 7. Distributed Configuration
- 8. Configuration changes
- 9. MySQL Database
- 10. Deploying the Application
- 11. Configuring MySQL Access
- 12. Creating Secrets
- 13. Instance Principal authentication
- 14. Start the application
- 15. Cleaning up
- 16. Next steps
Securely store Micronaut Application secrets in Oracle Cloud Vault
Learn how to create secrets in Oracle Cloud Vault and easily access them in a Micronaut application.
Authors: Burt Beckwith
Micronaut Version: 3.9.2
1. Getting Started
In this guide, we will create a Micronaut application written in Kotlin.
2. What you will need
To complete this guide, you will need the following:
-
Some time on your hands
-
A decent text editor or IDE
-
JDK 1.8 or greater installed with
JAVA_HOME
configured appropriately
-
An Oracle Cloud account (create a free trial account at signup.oraclecloud.com)
-
Oracle Cloud CLI installed with local access to Oracle Cloud configured by running
oci setup config
3. Oracle Cloud Vault
Oracle Cloud Vault lets you securely store and retrieve secrets such as passwords or other information that shouldn’t be accessible in cleartext.
In this guide we’ll use Vault to store database connection information for a Micronaut application that uses MySQL, and use the Micronaut support for Oracle Cloud to make the process seamless.
4. The Application
Download the complete solution of the Access a database with Micronaut Data JDBC guide. You will use the sample application as a starting point.
5. Creating an Oracle Cloud Vault
We’ll do the work of creating the vault with the Oracle Cloud CLI. See the Vault CLI command reference for more information.
If you prefer to use the Oracle Cloud web console to create the vault, follow the steps in the "Using Oracle Cloud Vault" section of the Access an Oracle Autonomous Database guide. |
Some of the following commands use jq
jq is a lightweight and flexible command-line JSON processor
There are three required parameters for the create command; compartment OCID, display name, and vault type.
5.1. Compartment OCID
Find the OCID of the compartment where we’ll be deploying. Run this to list all the compartments in your root compartment:
and find the compartment by the name or description in the JSON output. It should look like this:
{
"compartment-id": "ocid1.tenancy.oc1..aaaaaaaaud4g4e5ovjaw...",
"defined-tags": {},
"description": "Micronaut guides",
"freeform-tags": {},
"id": "ocid1.compartment.oc1..aaaaaaaarkh3s2wcxbbm...",
"inactive-status": null,
"is-accessible": null,
"lifecycle-state": "ACTIVE",
"name": "micronaut-guides",
"time-created": "2021-05-02T23:54:28.392000+00:00"
}
Use the OCID from the id
property; the compartment-id
property is the parent compartment.
For convenience, save the compartment OCID as an environment variable. For Linux or Mac, run
export C=ocid1.compartment.oc1..aaaaaaaarkh3s2wcxbbm...
or for Windows, if using cmd
run
set C=ocid1.compartment.oc1..aaaaaaaarkh3s2wcxbbm...
and if using PowerShell run
$C = "ocid1.compartment.oc1..aaaaaaaarkh3s2wcxbbm..."
In the examples below we use Linux/Mac syntax for environment variables, e.g. -c $C . If you use Windows cmd , change those to -c %C% (but no change needed if using PowerShell)
|
5.2. Create the Vault
Choose a display name (1-100 characters) and a vault type, either DEFAULT
or VIRTUAL_PRIVATE
. We recommend that you choose DEFAULT
to avoid the cost of a virtual private vault.
Run the create command with the compartment OCID, display name, and vault type substituted:
oci kms management vault create -c $C \
--display-name mn_guide_vault \
--vault-type DEFAULT \
| jq -r '.data.id'
The jq
utility will extract the vault OCID from the id
property in the response; this is the unique identifier for your vault which you’ll need later. Store the value as the VAULT_ID
environment variable:
export VAULT_ID=ocid1.vault.oc1.iad.b5re3....abuwcljryp5dmxbu3si7...
If you use Linux or Mac, you can combine both commands into one, creating the vault and setting the environment variable at the same time:
|
5.2.1. Create a Master Encryption Key
Next we need to create a Master Encryption Key.
For this we need the management endpoint URL that wasn’t available yet in the response from the vault create
command. Run the get command:
oci kms management vault get --vault-id $VAULT_ID
The response should look like this:
{
"data": {
"compartment-id": "ocid1.tenancy.oc1..aaaaaaaaixksuiqo3rx6...",
"crypto-endpoint": "https://b5re3...-crypto.kms.us-ashburn-1.oraclecloud.com",
...
"display-name": "mn_guide_vault",
"id": "ocid1.vault.oc1.iad.b5re3....abuwcljryp5dmxbu3si7...",
"is-primary": true,
"lifecycle-state": "ACTIVE",
"management-endpoint": "https://b5re3...-management.kms.us-ashburn-1.oraclecloud.com",
...
}
}
It will take a few minutes for the vault to finish provisioning. Re-run the get
command until the value of lifecycle-state
is ACTIVE
. The URL is available in the management-endpoint
property.
Store the URL as the VAULT_ENDPOINT
environment variable:
export VAULT_ENDPOINT=https://b5re3...-management.kms.us-ashburn-1.oraclecloud.com
Choose a name for the key, e.g., "mn-guide-encryption-key", and a "Protection Mode", either SOFTWARE
or HSM
. We recommend that you choose SOFTWARE
to avoid the cost of using a hardware security module (HSM). You also need to decide on a key shape algorithm and key length; for this guide we’ll use AES
and a key length of 32 (256 bits).
Run the create command with the compartment OCID, display name, protection mode, key shape, and management endpoint substituted:
oci kms management key create -c $C \
--display-name mn-guide-encryption-key \
--protection-mode SOFTWARE \
--key-shape '{"algorithm":"AES","length":"32"}' \
--endpoint $VAULT_ENDPOINT
| jq -r '.data.id'
If you use Windows, escape the inner double quotes in the value for key-shape : '{\"algorithm\":\"AES\",\"length\":\"32\"}
|
The jq
utility will extract the id
value from the response:
ocid1.key.oc1.iad.b5re3.....abuwcljrcuie7t6gctc6...
Store the key ID as the VAULT_KEY_ID
environment variable:
export VAULT_KEY_ID=ocid1.key.oc1.iad.b5re3.....abuwcljrcuie7t6gctc6...
6. Using Vault with Micronaut
6.1. micronaut-oraclecloud-vault Dependency
The micronaut-oracle-cloud subproject provides integration between Micronaut apps and Oracle Cloud, including using Vault as a distributed configuration source. Add a dependency to your build for the micronaut-oraclecloud-vault
library to add Vault support:
implementation("io.micronaut.oraclecloud:micronaut-oraclecloud-vault")
7. Distributed Configuration
7.1. Enable Distributed Configuration
Create a bootstrap.yml
file in the resources
directory to enable distributed configuration.
Add the following:
micronaut:
application:
name: micronautguide (1)
config-client:
enabled: true (2)
1 | Set the application name in bootstrap.yml instead of application.yml so that it is available when reading configuration from distributed sources.
properties |
2 | Set microanut.config-client.enabled: true which is used to read and resolve configuration from distributed sources. |
7.2. Clean up Application Configuration
If application.yml
sets micronaut.application.name
, remove it. You moved it to bootstrap.yml
.
- micronaut:
- application:
- name: micronautguide
7.3. Disable Distributed Configuration for Test
To disable distributed configuration for tests, create a bootstrap-test.yml
file:
micronaut:
config-client:
enabled: false
8. Configuration changes
8.1. bootstrap-oraclecloud.yml
Then create src/main/resources/bootstrap-oraclecloud.yml
with the following content:
oci:
config:
instance-principal:
enabled: true (1)
vault:
config:
enabled: true
vaults:
- ocid: ${VAULT_ID} (2)
compartment-ocid: (3)
1 | We’ll use Instance Principal authentication to allow the Micronaut application to access Vault |
2 | Set the value of the ocid property with the vault OCID unique identifier you saved when creating the vault. |
3 | Set the value of the compartment-ocid property with the OCID unique identifier of the compartment where you created the vault and secrets |
9. MySQL Database
Use the Deploy a Micronaut MySQL Database Application to Oracle Cloud guide to create a MySQL database; follow the steps in the "Creating a MySQL DB System at Oracle Cloud" section.
10. Deploying the Application
Use the Deploy a Micronaut application to Oracle Cloud guide to create a compute instance and deploy the application to it; follow the steps in the "Create an Oracle Cloud Compute Instance" and "Deploy to Oracle Cloud" sections up to the step where you start the application. We need to connect the application to the MySQL database before starting it up.
When creating the compute VM at Oracle Cloud, use the same subnet as the one where you created the MySQL database, otherwise the application will not be able to access the database. |
11. Configuring MySQL Access
Use the Deploy a Micronaut MySQL Database Application to Oracle Cloud guide to configure access to the MySQL database; follow the steps in the "Configure MySQL" section. You will need the private IP address of the VM, the MySQL private IP address, and the admin username and password you chose when creating the database.
12. Creating Secrets
In the Access a database with Micronaut Data JDBC guide, the values for the JDBC URL, database username and password, and the JDBC driver class are "externalized" properties with default values:
datasources:
default:
url: ${JDBC_URL:`jdbc:mysql://localhost:3306/db`}
username: ${JDBC_USER:root}
password: ${JDBC_PASSWORD:}
dialect: MYSQL
driverClassName: ${JDBC_DRIVER:com.mysql.cj.jdbc.Driver}
The guide recommends that you set environment variables to override the default values, but in this guide we’ll go a step further and store some of those values in our Oracle Cloud Vault. We’ll leave the default for the driver class, but create vault secrets for JDBC_USER
, JDBC_PASSWORD
, and JDBC_URL
.
12.1. JDBC_USER
The first secret will be for the database username, so the secret name will be JDBC_USER
.
Secret values must be Base64-encoded. You can encode the value programmatically, e.g., Base64.getEncoder().encodeToString("the value".getBytes())
, or use an online tool such as https://www.base64encode.org/.
Run the create-base64 command with the compartment OCID, encryption key OCID, vault OCID, secret name, and Base64-encoded secret value substituted. If you use guide_user
as the username, the Base64-encoded value will be Z3VpZGVfdXNlcg==
oci vault secret create-base64 -c $C \
--key-id $VAULT_KEY_ID \
--vault-id $VAULT_ID \
--secret-name JDBC_USER \
--secret-content-content Z3VpZGVfdXNlcg==
Note that running that command will leave the Base64-encoded value in your shell history. To avoid this, you can create a JSON file containing the parameters and pass that as an argument to the command.
To use this approach, create a file like this with values substituted, and save it as key.json:
{
"compartmentId": "ocid1.compartment.oc1..aaaaaaaarkh3s2wcxbbm...",
"keyId": "ocid1.key.oc1.iad.b5re3.....abuwcljrcuie7t6gctc6...",
"vaultId": "ocid1.vault.oc1.iad.b5re3....abuwcljryp5dmxbu3si7...",
"secretName": "JDBC_USER",
"secretContentContent": "Z3VpZGVfdXNlcg=="
}
and run this create-base64
command instead:
oci vault secret create-base64 --from-json file://key.json
With either approach the response should look like this:
{
"data": {
"compartment-id": "ocid1.compartment.oc1..aaaaaaaarkh3s2wcxbbm...",
...
"id": "ocid1.vaultsecret.oc1.iad.amaaaaaafzr7royabqgz...",
"key-id": "ocid1.key.oc1.iad.b5re3.....abuwcljrcuie7t6gctc6...",
"lifecycle-state": "CREATING",
"secret-name": "JDBC_USER",
...
"vault-id": "ocid1.vault.oc1.iad.b5re3....abuwcljryp5dmxbu3si7..."
}
}
12.2. JDBC_PASSWORD
Create a second secret with the name JDBC_PASSWORD
. The value will be the Base64-encoded database user password you chose earlier.
12.3. JDBC_URL
Create a third secret with the name JDBC_URL
. The URL will be jdbc:mysql://<MySQL IP address>:3306/micronaut
with the private IP address of your MySQL database substituted. Set the value of the secret as the Base64-encoded URL value.
13. Instance Principal authentication
We’ll use Instance Principal authentication to allow the Micronaut application to retrieve secrets from Vault. To use this, we need to create a dynamic group and add a policy statement granting permission.
If you prefer to use the Oracle Cloud web console to create the dynamic group and policy statements, follow the steps in the "Instance Principal authentication" section of the Oracle Cloud Streaming and the Micronaut Framework - Event-Driven Applications at Scale guide. |
13.1. Dynamic Group
Choose a group name, e.g., "mn-guide-dg", and a matching rule, i.e., the logic that will be used to determine group membership. We’ll make the rule fairly broad - use ALL {instance.compartment.id = 'ocid1.compartment.oc1..aaaaaaaarkh3s2wcxbbm…'}
replacing ocid1.compartment.oc1..aaaaaaaarkh3s2wcxbbm…
with the compartment OCID:
Run the create command with the compartment OCID substituted:
oci iam dynamic-group create \
--name mn-guide-dg \
--description mn-guide-dg \
--matching-rule "ALL {instance.compartment.id = 'ocid1.compartment.oc1..aaaaaaaarkh3s2wcxbbm...'}" \
| jq -r '.data."compartment-id"'
The jq
utility will extract the compartment-id
value from the response. Store the ID (the tenancy ID) as the T
environment variable:
export T=ocid1.tenancy.oc1..aaaaaaaaud4g4e5ovjaw...
See the Dynamic Group docs for more information.
13.2. Dynamic Group Policy Statements
Next, create the policy granting read access to Vault.
We’ll create the policy in the root compartment, i.e., the tenancy, so we’ll use the tenancy OCID saved from the dynamic group creation response.
Run the create command with the tenancy OCID substituted:
oci iam policy create -c $T \
--name mn-guide-policy \
--description mn-guide-policy \
--statements '["allow dynamic-group mn-guide-dg to read secret-family in tenancy"]' \
| jq -r '.data.id'
The jq
utility will extract the policy OCID from the id
property in the response. Store the value as the POLICY_ID
environment variable:
export POLICY_ID=ocid1.policy.oc1..aaaaaaaau7uhwxr3ynlr...
14. Start the application
Finally, start the application. From the SSH session into your VM, run:
java -jar application.jar
Verify that the application is working correctly with some cURL commands.
Create a genre by running
curl -X POST http://[VM IP Address]:8080/genres \
-H 'Content-Type: application/json; charset=utf-8' \
-d $'{ "name": "music" }'
The response should look like this:
{"id":1,"name":"music"}
List all genres by running
curl http://[VM IP Address]:8080/genres/list
The response should look like this:
[{"id":1,"name":"music"}]
15. Cleaning up
After you’ve finished this guide, you can clean up the resources you created.
Delete the policy by running
oci iam policy delete --policy-id $POLICY_ID
To delete the dynamic group, find its OCID by running the list command:
oci iam dynamic-group list | jq -r '.data[] | select(.name=="mn-guide-dg") | .id'
and run the delete command, substituting the group OCID:
oci iam dynamic-group delete --dynamic-group-id ocid1.dynamicgroup.oc1..aaaaaaaaipoabhhaqnj77urm...
Finally, delete the vault. You cannot delete it directly; instead you can request deletion at a date at least seven days in the future. Run this, replacing the date with one seven days (or more) from now:
oci kms management vault schedule-deletion \
--vault-id $VAULT_ID \
--time-of-deletion 2022-05-12
16. Next steps
Explore more features with Micronaut Guides.
Read more about the Micronaut Oracle Cloud integration.