Oracle Cloud (OCI)
Connect your Oracle Cloud (OCI) tenancy to OpsLyft optimization.
Contents
- Introduction
- Values
- Choose your path
- Integration Steps
- Set up your terminal
- Share with us
- Reference commands
- Troubleshooting
- Remove access
Introduction
OpsLyft reads resource configuration and metrics across your tenancy on a regular schedule. It is read-only and never reads data inside your resources (object contents, database rows, log contents, secrets).
You create a dedicated IAM user and group, upload OpsLyft's public API key and add a read-only policy.
Values
| Name | Value |
|---|---|
| OpsLyft public key | Shown in the block below the table |
| Suggested user name | opslyft |
| Suggested group name | opslyft |
| Suggested policy name | opslyft-read-only |
OpsLyft public key:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAh74wKlp1s95O4qBlmvnw
OUWNvnHN0XxZ0jWJCmC8BfAR64AIu8fXFlldP1zVjsB9eafJFbhZ/ErryddyPx7n
9PdWVq3eO0CtF/Pf5hzHyFQ4W23jKFxBgOBOGRyJfwU2xXqCBvTzP1PD38Zeqrhd
S2sKdXGibobm6Oix7e1UsMRkd4Fsus/5NM06AStEX2059BU+ztxiy7FjnaofyRGx
zvJ677nTLwZ72dFMhcxkfPkv+P57ukgZ/Ea0mdDwm8w9jFjygZdT0m2FswwFvkQT
hE0gv7TIGBESBQTx+pBaOjPSTECilY2VhFXpTd/3kBEOAR+5wPhdO0hI9BzWRVHb
BQIDAQAB
-----END PUBLIC KEY-----Choose your path
OpsLyft does not have access to your tenancy yet: follow New integration with OpsLyft. An OpsLyft user, group and policy already exist and you want to check or update them: follow Existing integration with OpsLyft.
Integration Steps
New integration with OpsLyft
Creates a dedicated user, group and policy in the tenancy, separate from any human user.
Create user, group and policy
-
Open Cloud Shell in the OCI console, or use a terminal with the OCI CLI.
-
Set the names to create (the suggestions from Values; edit them if you prefer others):
export USER_NAME=opslyft export GROUP_NAME=opslyft export POLICY_NAME=opslyft-read-only -
Check your administrator membership
Result:
1.0is fine if you hold equivalent rights to create IAM users, groups and policies in the tenancy through another group. -
Result:
0three times. If one prints1, set a different name in the previous step. If the object is an existing OpsLyft setup, follow Existing integration with OpsLyft. -
Create the group:
export OPSLYFT_GROUP_ID=$(oci iam group create --compartment-id "$TENANCY_ID" --name "$GROUP_NAME" \ --description "Group for the OpsLyft optimization integration" --query data.id --raw-output) echo "Group ID: $OPSLYFT_GROUP_ID"Result: a group ID starting
ocid1.group.. If not, see Troubleshooting. -
Create the user. The
--emailflag is required in tenancies that use Oracle Identity Cloud Service:export OPSLYFT_USER_ID=$(oci iam user create --compartment-id "$TENANCY_ID" --name "$USER_NAME" \ --description "User for the OpsLyft optimization integration (API key access)" --email oracle@opslyft.com --query data.id --raw-output) echo "User ID: $OPSLYFT_USER_ID"Result: a user ID starting
ocid1.user., and running Check the group and user state printsACTIVEtwice. If not, see Troubleshooting. -
Add the user to the group:
oci iam group add-user --group-id "$OPSLYFT_GROUP_ID" --user-id "$OPSLYFT_USER_ID"Result: run Check the user's group membership; it prints
1. If0, run the command again. -
Upload OpsLyft's public key:
oci iam user api-key upload --user-id "$OPSLYFT_USER_ID" --key "$OPSLYFT_PUBLIC_KEY"Result: run List the API keys on the user; it lists
$KEY_FINGERPRINT. If not, check that$OPSLYFT_PUBLIC_KEYis set and unchanged (Set up your terminal). -
Create the policy.
readmeans list and get only;inspectis used only to list region subscriptions. Agree narrower policies with OpsLyft first:oci iam policy create --compartment-id "$TENANCY_ID" --name "$POLICY_NAME" \ --description "OpsLyft read-only integration policy" \ --statements "[ \"allow group $GROUP_NAME to read all-resources in tenancy\", \"allow group $GROUP_NAME to read metrics in tenancy\", \"allow group $GROUP_NAME to read compartments in tenancy\", \"allow group $GROUP_NAME to inspect tenancies in tenancy\" ]"Result: run Show the policy statements by name; it prints exactly those four statements, with your group name after
allow group. If not, check your rights (Check your administrator membership) and see Troubleshooting. -
Then go to Share with us.
Existing integration with OpsLyft
Checks what is already in your tenancy and brings it up to date. Nothing is removed. If you find no OpsLyft user, follow New integration with OpsLyft.
Check current integration state
-
Open Cloud Shell in the OCI console, or use a terminal with the OCI CLI.
-
Find your OpsLyft user: run List the users. It is the user that carries OpsLyft's API key; its description usually names OpsLyft, and OpsLyft can confirm the key fingerprint.
Result: a list of users. If none looks like OpsLyft's, follow New integration with OpsLyft.
-
Store the user, with the name and ID you picked:
export USER_NAME=<name of the OpsLyft user> export OPSLYFT_USER_ID=<id of that user> -
Check the stored user: run Check the user name and Count the API keys on the user.
Result: the name equals
$USER_NAMEand the count is1or more. -
Find the user's group: run List the user's groups.
Result: at least one ID starting
ocid1.group.. If several, run Show the group details on each and pick the OpsLyft one, or ask OpsLyft. If it printed nothing, run List all groups and take theidof your OpsLyft group. -
Store the group. The second line prints the group name, which must not be empty:
export OPSLYFT_GROUP_ID=<group id> export GROUP_NAME=$(oci iam group get --group-id "$OPSLYFT_GROUP_ID" --query 'data.name' --raw-output); echo "$GROUP_NAME" -
Check the key: run List the API keys on the user.
Result: the list contains
$KEY_FINGERPRINT. If not, the update uploads it. -
Find the policy that covers your group: run Find the policy for your group.
Result: the policy name and OCID (your
<POLICY-ID>), its statements (note all of them) and four lines, eachpresentorMISSING. A statement written another way showsMISSING: compare it with the printed statements first. If all four arepresentand the key is listed, there is nothing to update: go to Share with us. If nothing prints, no policy names your group: ask OpsLyft. -
Store the policy name:
export POLICY_NAME=<policy name>Result: run Show the policy OCID; it prints the same OCID as Find the policy for your group.
-
Continue with Update the integration.
Update the integration
Only the parts the checks showed as missing.
-
Add the user to the group if Check the user's group membership prints
0:oci iam group add-user --group-id "$OPSLYFT_GROUP_ID" --user-id "$OPSLYFT_USER_ID"Result: run Check the user's group membership; it prints
1. -
Upload the key if List the API keys on the user lacks
$KEY_FINGERPRINT:oci iam user api-key upload --user-id "$OPSLYFT_USER_ID" --key "$OPSLYFT_PUBLIC_KEY"Result: run List the API keys on the user; it lists
$KEY_FINGERPRINT. -
Add the missing statements. This reads your policy, adds only what is missing and keeps every existing statement, so it is safe to re-run.
--version-date ""is required, even if your policy has no version date:POLICY_ID=$(oci iam policy list --compartment-id "$TENANCY_ID" --name "$POLICY_NAME" --query 'data[0].id' --raw-output) STATEMENTS=$(oci iam policy get --policy-id "$POLICY_ID" --query 'data.statements' | python3 -c " import json,os,sys g=os.environ['GROUP_NAME'] s=json.load(sys.stdin) have={x.strip().lower() for x in s} for r in ['read all-resources in tenancy','read metrics in tenancy','read compartments in tenancy','inspect tenancies in tenancy']: n='allow group '+g+' to '+r if n.lower() not in have: s.append(n) print(json.dumps(s))") echo "$STATEMENTS" oci iam policy update --policy-id "$POLICY_ID" --version-date "" --force --statements "$STATEMENTS"Result: run Find the policy for your group; it shows all four lines
presentand every statement you noted is still listed. If not, run the update again with the full list. -
Then go to Share with us.
Set up your terminal
Use a bash terminal or Cloud Shell. Run these once per terminal. If your terminal disconnects, run them again. If a command fails, run oci setup config, sign in with your own credentials and repeat it.
-
Only in your own terminal (not needed in OCI Cloud Shell): Check the OCI CLI version
-
Set the default variables. If your CLI config has several profiles, use the one you work with. The block prints your tenancy OCID (
ocid1.tenancy.), your user OCID (ocid1.user.) and the key fingerprint:export TENANCY_ID=$(oci iam compartment list \ --query "data[?contains(\"compartment-id\",'.tenancy.')].\"compartment-id\" | [0]" \ --raw-output) export MY_USER_ID=$(grep '^user' ~/.oci/config | head -1 | cut -d= -f2 | tr -d ' ') export OPSLYFT_PUBLIC_KEY="-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAh74wKlp1s95O4qBlmvnw OUWNvnHN0XxZ0jWJCmC8BfAR64AIu8fXFlldP1zVjsB9eafJFbhZ/ErryddyPx7n 9PdWVq3eO0CtF/Pf5hzHyFQ4W23jKFxBgOBOGRyJfwU2xXqCBvTzP1PD38Zeqrhd S2sKdXGibobm6Oix7e1UsMRkd4Fsus/5NM06AStEX2059BU+ztxiy7FjnaofyRGx zvJ677nTLwZ72dFMhcxkfPkv+P57ukgZ/Ea0mdDwm8w9jFjygZdT0m2FswwFvkQT hE0gv7TIGBESBQTx+pBaOjPSTECilY2VhFXpTd/3kBEOAR+5wPhdO0hI9BzWRVHb BQIDAQAB -----END PUBLIC KEY-----" export KEY_FINGERPRINT=$(echo "$OPSLYFT_PUBLIC_KEY" | openssl rsa -pubin -outform DER 2>/dev/null | openssl md5 -c | sed 's/^.*= //') echo "$TENANCY_ID"; echo "$MY_USER_ID"; echo "$KEY_FINGERPRINT"Do not change
OPSLYFT_PUBLIC_KEY.
Share with us
Send OpsLyft these values. Send only the rows that apply to you:
| Field | What to send | How to get it |
|---|---|---|
| Path followed | New integration with OpsLyft or Existing integration with OpsLyft | Enter manually |
| Tenancy OCID | Starts ocid1.tenancy. | Run echo "$TENANCY_ID" |
| User OCID | Starts ocid1.user. | Run echo "$OPSLYFT_USER_ID" |
| Fingerprint | Fingerprint of OpsLyft's key | Run echo "$KEY_FINGERPRINT" |
| Home region | Your home region name | Show your home region |
| Compartments | Only if you limited the statements to some compartments | Enter manually |
When something changes later, send an update to the same table.
Reference commands
Checks that the OCI CLI is installed.
oci --versionPrints a version number.
Checks your own rights. Uses $TENANCY_ID and $MY_USER_ID.
ADMIN_GROUP_ID=$(oci iam group list --compartment-id "$TENANCY_ID" --name Administrators --query 'data[0].id' --raw-output)
oci iam user list-groups --compartment-id "$TENANCY_ID" --user-id "$MY_USER_ID" --query "length(data[?id=='$ADMIN_GROUP_ID'])"Prints 1 if you are a direct member of Administrators. It sees direct membership only, so 0 can still mean you have the rights through another group.
Checks that the group, user and policy names are free. Uses $GROUP_NAME, $USER_NAME and $POLICY_NAME.
oci iam group list --compartment-id "$TENANCY_ID" --name "$GROUP_NAME" --query 'length(data)'
oci iam user list --compartment-id "$TENANCY_ID" --name "$USER_NAME" --query 'length(data)'
oci iam policy list --compartment-id "$TENANCY_ID" --name "$POLICY_NAME" --query 'length(data)'Prints 0 three times when all names are free.
Shows the state of the group and the user. Run it after they are created. Uses $OPSLYFT_GROUP_ID and $OPSLYFT_USER_ID.
oci iam group get --group-id "$OPSLYFT_GROUP_ID" --query 'data."lifecycle-state"' --raw-output
oci iam user get --user-id "$OPSLYFT_USER_ID" --query 'data."lifecycle-state"' --raw-outputPrints ACTIVE twice.
Checks that the user is in the group. Uses $OPSLYFT_GROUP_ID and $OPSLYFT_USER_ID.
oci iam user list-groups --compartment-id "$TENANCY_ID" --user-id "$OPSLYFT_USER_ID" --query "length(data[?id=='$OPSLYFT_GROUP_ID'])"Prints 1 when the user is in the group.
Lists the API keys the user carries. Uses $OPSLYFT_USER_ID.
oci iam user api-key list --user-id "$OPSLYFT_USER_ID" --query 'data[].fingerprint'Prints the fingerprints of the keys on the user.
Shows what a policy allows. Uses $POLICY_NAME.
oci iam policy list --compartment-id "$TENANCY_ID" --name "$POLICY_NAME" --query 'data[0].statements'Prints the statements of the policy.
Lists the users, to find your OpsLyft user. Uses $TENANCY_ID.
oci iam user list --compartment-id "$TENANCY_ID" --all --query 'data[].{name:name,id:id,description:description}'Prints name, id and description of each user; take the name and id of the OpsLyft user.
Shows the name of the stored user. Uses $OPSLYFT_USER_ID and $USER_NAME.
oci iam user get --user-id "$OPSLYFT_USER_ID" --query 'data.name' --raw-outputPrints the user name.
Counts the API keys on the user. Uses $OPSLYFT_USER_ID.
oci iam user api-key list --user-id "$OPSLYFT_USER_ID" --query 'length(data)'Prints the number of keys.
Lists the groups the user belongs to. Uses $OPSLYFT_USER_ID.
oci iam user list-groups --compartment-id "$TENANCY_ID" --user-id "$OPSLYFT_USER_ID" --query 'data[].id'Prints group IDs; take the OpsLyft one if there are several.
Shows the name and description of a group printed by List the user's groups.
oci iam group get --group-id <id>Prints the group's name and description.
Lists all groups. Run it when List the user's groups printed nothing. Uses $TENANCY_ID.
oci iam group list --compartment-id "$TENANCY_ID" --all --query 'data[].{name:name,id:id,description:description}'Prints name, id and description of each group; take the id of your OpsLyft group.
Finds the policy that names your group and shows which statements are missing. Uses $GROUP_NAME.
oci iam policy list --compartment-id "$TENANCY_ID" --all \
--query 'data[].{name:name,id:id,statements:statements}' | \
python3 -c "
import json,os,sys
g=os.environ['GROUP_NAME'].lower()
need=['read all-resources in tenancy','read metrics in tenancy','read compartments in tenancy','inspect tenancies in tenancy']
for p in json.load(sys.stdin):
have={s.strip().lower() for s in p.get('statements',[])}
if any(g in s for s in have):
print(p['name'], p['id'])
for s in p['statements']: print(' ', s)
for r in need: print('present' if ('allow group '+g+' to '+r) in have else 'MISSING', r)
"Prints the policy name and OCID on the first line, then its statements; the last four lines each say present or MISSING.
Shows the policy OCID. Uses $POLICY_NAME.
oci iam policy list --compartment-id "$TENANCY_ID" --name "$POLICY_NAME" --query 'data[0].id' --raw-outputPrints the policy OCID.
Shows your home region, a value to share.
oci iam region-subscription list --query 'data[?"is-home-region"==`true`]."region-name" | [0]' --raw-outputPrints your home region name.
Shows the statements of a policy by its OCID. Uses the <POLICY-ID> printed by Find the policy for your group.
oci iam policy get --policy-id <POLICY-ID> --query 'data.statements'Prints the statements of the policy.
Troubleshooting
| Problem | Fix |
|---|---|
oci iam user create or oci iam group create fails | A user or group of that name already exists. Look up the existing IDs with oci iam user list --compartment-id "$TENANCY_ID" --name "$USER_NAME" (and group list with $GROUP_NAME), set a different name or follow Existing integration with OpsLyft. |
oci iam policy update asks for --version-date | Pass --version-date "", even if your policy has no version date. |
| A resource type does not show up | Its list call is not allowed: a resource type appears only if the policy allows its list call. |
| Only the home region is read, or no metrics | inspect tenancies in tenancy or a tenancy-wide read metrics is missing from the policy. |
| OpsLyft asks you to change the statements | Run the oci iam policy update command from Existing integration with OpsLyft with the full list you want, for your $GROUP_NAME (it replaces the whole list). Then run Show the policy statements by ID. |
Remove access
Deleting the API key or the policy stops OpsLyft reading; deleting the user and group is optional. If the policy also holds statements that are not OpsLyft's, remove only the OpsLyft statements with oci iam policy update. Tell OpsLyft when you have removed access. Set $OPSLYFT_USER_ID, $OPSLYFT_GROUP_ID and <POLICY-ID> first (see steps 4, 7 and 9 of Check current integration state).
oci iam user api-key delete --user-id "$OPSLYFT_USER_ID" --fingerprint "$KEY_FINGERPRINT" --forceoci iam policy delete --policy-id <POLICY-ID> --forceoci iam group remove-user --group-id "$OPSLYFT_GROUP_ID" --user-id "$OPSLYFT_USER_ID" --forceoci iam user delete --user-id "$OPSLYFT_USER_ID" --forceoci iam group delete --group-id "$OPSLYFT_GROUP_ID" --forceResult: run Count the API keys on the user; it prints 0 (or the user no longer exists).