OCI Operations Associate - Security Operations and Cost Management¶
Table of Contents¶
- Security Operations
- IAM Operations
- Compliance and Auditing
- Cost Management
- Billing and Usage
- Exam Tips
Security Operations¶
Cloud Guard Operations¶
Enabling Cloud Guard:
# Enable Cloud Guard
oci cloud-guard cloud-guard-configuration update \
--reporting-region "us-phoenix-1" \
--status ENABLED
# Create target
oci cloud-guard target create \
--compartment-id $COMPARTMENT_ID \
--display-name "Production-Monitoring" \
--target-resource-id $COMPARTMENT_ID \
--target-resource-type COMPARTMENT \
--target-detector-recipes '[{
"detectorRecipeId":"ocid1.cloudguarddetectorrecipe..."
}]' \
--target-responder-recipes '[{
"responderRecipeId":"ocid1.cloudguardresponderrecipe..."
}]'
Managing Problems:
# List problems
oci cloud-guard problem list \
--compartment-id $COMPARTMENT_ID \
--status OPEN \
--sort-by timeCreated \
--sort-order DESC
# Get problem details
oci cloud-guard problem get \
--problem-id $PROBLEM_ID
# Dismiss problem
oci cloud-guard problem-status update \
--problem-id $PROBLEM_ID \
--status DISMISSED \
--comment "False positive - approved configuration"
# Resolve problem
oci cloud-guard problem-status update \
--problem-id $PROBLEM_ID \
--status RESOLVED
Common Problems and Remediation:
Public Bucket:
# Problem: Bucket is public
# Auto-remediation:
oci os bucket update \
--bucket-name "sensitive-data" \
--public-access-type NoPublicAccess
Overly Permissive Security List:
# Problem: Security list allows 0.0.0.0/0:22
# Manual remediation:
oci network security-list update \
--security-list-id $SL_ID \
--ingress-security-rules '[{
"protocol":"6",
"source":"203.0.113.0/24",
"tcpOptions":{"destinationPortRange":{"min":22,"max":22}}
}]'
Unencrypted Volume:
# Problem: Block volume not using customer-managed key
# Cannot encrypt existing volume, must:
# 1. Backup volume
oci bv backup create --volume-id $VOLUME_ID
# 2. Create new encrypted volume from backup
oci bv volume create \
--backup-id $BACKUP_ID \
--kms-key-id $KEY_ID
Security Zones Operations¶
Creating Security Zone:
# Create security zone
oci cloud-guard security-zone create \
--compartment-id $COMPARTMENT_ID \
--display-name "PCI-Compliance-Zone" \
--security-zone-recipe-id ocid1.securityzonerecipe.oc1..maximum
Moving Compartment to Security Zone:
# Move compartment (resources must comply first)
oci cloud-guard security-zone update \
--security-zone-id $ZONE_ID \
--target-compartment-id $COMPARTMENT_ID
Security Zone Violations:
Common violations and fixes:
1. Public bucket
Fix: Make bucket private
2. Unencrypted resource
Fix: Enable encryption
3. Missing audit logs
Fix: Enable audit logging
4. Overly permissive security rules
Fix: Tighten security lists/NSGs
Vault Operations¶
Key Management:
# Create vault
oci kms management vault create \
--compartment-id $COMPARTMENT_ID \
--display-name "production-vault" \
--vault-type VIRTUAL_PRIVATE
# Create master encryption key
oci kms management key create \
--compartment-id $COMPARTMENT_ID \
--display-name "volume-encryption-key" \
--key-shape '{"algorithm":"AES","length":32}' \
--management-endpoint "https://..."
# Rotate key
oci kms management key create-key-version \
--key-id $KEY_ID \
--management-endpoint "https://..."
# Disable key
oci kms management key disable \
--key-id $KEY_ID \
--management-endpoint "https://..."
Using Vault Keys:
# Create encrypted volume
oci bv volume create \
--availability-domain "Uocm:PHX-AD-1" \
--compartment-id $COMPARTMENT_ID \
--kms-key-id $KEY_ID \
--size-in-gbs 500
# Create encrypted bucket
oci os bucket create \
--name "encrypted-data" \
--compartment-id $COMPARTMENT_ID \
--kms-key-id $KEY_ID
IAM Operations¶
User Management¶
Creating Users:
# Create user
oci iam user create \
--name "john.doe@example.com" \
--description "Operations Engineer" \
--email "john.doe@example.com"
# Enable capabilities
oci iam user update-user-capabilities \
--user-id $USER_ID \
--can-use-console-password true \
--can-use-api-keys true \
--can-use-auth-tokens true
# Generate initial password
oci iam user create-or-reset-ui-password \
--user-id $USER_ID
Adding to Groups:
# Add user to group
oci iam group add-user \
--group-id $GROUP_ID \
--user-id $USER_ID
# Remove from group
oci iam group remove-user \
--group-id $GROUP_ID \
--user-id $USER_ID
MFA Enforcement:
# Check MFA status
oci iam user get \
--user-id $USER_ID \
--query 'data."is-mfa-activated"'
# Users enable MFA via console
# Operations: Verify MFA is enabled for all admin users
Group and Policy Management¶
Creating Groups:
# Create operational groups
oci iam group create \
--name "NetworkOperators" \
--description "Network operations team"
oci iam group create \
--name "DatabaseOperators" \
--description "Database operations team"
oci iam group create \
--name "ReadOnlyUsers" \
--description "Read-only access for monitoring"
Common Operational Policies:
Network Operators:
Allow group NetworkOperators to manage virtual-network-family in compartment Production
Allow group NetworkOperators to manage load-balancers in compartment Production
Allow group NetworkOperators to read all-resources in compartment Production
Allow group NetworkOperators to use network-security-groups in compartment Production
Database Operators:
Allow group DatabaseOperators to manage database-family in compartment Production
Allow group DatabaseOperators to manage autonomous-database-family in compartment Production
Allow group DatabaseOperators to read virtual-network-family in compartment Production
Allow group DatabaseOperators to manage volume-family in compartment Production where any {
request.operation = 'CreateVolumeBackup',
request.operation = 'CreateBackup'
}
Read-Only Users:
Allow group ReadOnlyUsers to inspect all-resources in tenancy
Allow group ReadOnlyUsers to read metrics in tenancy
Allow group ReadOnlyUsers to read logs in tenancy
Allow group ReadOnlyUsers to read alarms in tenancy
Incident Response Team:
Allow group IncidentResponse to manage instances in compartment Production where request.operation = 'InstanceAction'
Allow group IncidentResponse to read all-resources in tenancy
Allow group IncidentResponse to manage console-history in compartment Production
Allow group IncidentResponse to read audit-events in tenancy
Dynamic Groups¶
Creating Dynamic Groups:
# Instance principals for specific compartment
oci iam dynamic-group create \
--name "prod-instances" \
--description "Production compute instances" \
--matching-rule "instance.compartment.id = '$PROD_COMPARTMENT_ID'"
# Function principals
oci iam dynamic-group create \
--name "automation-functions" \
--description "Automation functions" \
--matching-rule "resource.type = 'fnfunc'"
Dynamic Group Policies:
# Allow instances to access Object Storage
Allow dynamic-group prod-instances to read buckets in compartment Production
Allow dynamic-group prod-instances to read objects in compartment Production
# Allow functions to manage resources
Allow dynamic-group automation-functions to manage instances in compartment Production
Allow dynamic-group automation-functions to use virtual-network-family in compartment Production
Compliance and Auditing¶
Audit Logs¶
Viewing Audit Events:
# List recent audit events
oci audit event list \
--compartment-id $COMPARTMENT_ID \
--start-time "2024-10-10T00:00:00Z" \
--end-time "2024-10-10T23:59:59Z"
# Find specific operations
oci audit event list \
--compartment-id $COMPARTMENT_ID \
--start-time "2024-10-10T00:00:00Z" \
--end-time "2024-10-10T23:59:59Z" \
| jq '.data[] | select(.data."event-name" == "LaunchInstance")'
# Find actions by specific user
oci audit event list \
--compartment-id $COMPARTMENT_ID \
--start-time "2024-10-10T00:00:00Z" \
--end-time "2024-10-10T23:59:59Z" \
| jq '.data[] | select(.data.identity."principal-name" == "john.doe@example.com")'
Audit Log Analysis Queries:
# IAM changes
search "compartment-ocid/audit-logs" |
where data.eventType =~ 'com.oraclecloud.identitycontrolplane.*' |
sort by datetime desc
# Resource deletions
search "compartment-ocid/audit-logs" |
where data.request.operation =~ '.*Delete.*' |
where data.response.status = '200' |
stats count() by data.request.operation, data.identity.principalName
# Failed authentication attempts
search "compartment-ocid/audit-logs" |
where data.message =~ 'authentication failed' |
stats count() as failures by data.identity.principalName, data.request.sourceAddress |
where failures > 5 |
sort by failures desc
Audit Log Archival:
# Archive to Object Storage (via Service Connector)
oci sch service-connector create \
--compartment-id $COMPARTMENT_ID \
--display-name "audit-log-archival" \
--source '{
"kind":"logging",
"logSources":[{
"compartmentId":"'$TENANCY_ID'",
"logId":"'$AUDIT_LOG_ID'"
}]
}' \
--target '{
"kind":"objectStorage",
"bucketName":"audit-archive",
"namespace":"'$NAMESPACE'",
"objectNamePrefix":"audit-logs/"
}'
Compliance Reporting¶
Generating Compliance Reports:
#!/usr/bin/env python3
# Generate compliance report
import oci
from datetime import datetime, timedelta
config = oci.config.from_file()
def generate_compliance_report():
report = {
"date": datetime.now().isoformat(),
"findings": []
}
# Check 1: All users have MFA
identity = oci.identity.IdentityClient(config)
users = identity.list_users(config["tenancy"]).data
for user in users:
if not user.is_mfa_activated:
report["findings"].append({
"severity": "HIGH",
"finding": f"User {user.name} does not have MFA enabled",
"remediation": "Enable MFA in user profile"
})
# Check 2: No public buckets
object_storage = oci.object_storage.ObjectStorageClient(config)
namespace = object_storage.get_namespace().data
buckets = object_storage.list_buckets(
namespace,
config["compartment_id"]
).data
for bucket in buckets:
bucket_details = object_storage.get_bucket(namespace, bucket.name).data
if bucket_details.public_access_type != "NoPublicAccess":
report["findings"].append({
"severity": "CRITICAL",
"finding": f"Bucket {bucket.name} allows public access",
"remediation": "Set public access to NoPublicAccess"
})
# Check 3: All volumes encrypted
block_storage = oci.core.BlockstorageClient(config)
volumes = block_storage.list_volumes(config["compartment_id"]).data
for volume in volumes:
if not volume.kms_key_id:
report["findings"].append({
"severity": "MEDIUM",
"finding": f"Volume {volume.display_name} not encrypted with customer key",
"remediation": "Create encrypted volume from backup"
})
return report
# Generate report
report = generate_compliance_report()
print(json.dumps(report, indent=2))
Cost Management¶
Cost Analysis¶
Viewing Costs:
# Get cost data (requires cost tracking setup)
oci usage-api usage-summary request-summarized-usages \
--tenant-id $TENANCY_ID \
--time-usage-started "2024-10-01T00:00:00Z" \
--time-usage-ended "2024-10-31T23:59:59Z" \
--granularity DAILY \
--group-by '["service"]'
Cost by Compartment:
oci usage-api usage-summary request-summarized-usages \
--tenant-id $TENANCY_ID \
--time-usage-started "2024-10-01T00:00:00Z" \
--time-usage-ended "2024-10-31T23:59:59Z" \
--granularity MONTHLY \
--group-by '["compartmentPath"]'
Cost by Tag:
oci usage-api usage-summary request-summarized-usages \
--tenant-id $TENANCY_ID \
--time-usage-started "2024-10-01T00:00:00Z" \
--time-usage-ended "2024-10-31T23:59:59Z" \
--granularity MONTHLY \
--group-by '["tags"]'
Budget Management¶
Creating Budgets:
# Monthly budget with alerts
oci budgets budget create \
--amount 5000 \
--reset-period MONTHLY \
--target-compartment-id $COMPARTMENT_ID \
--target-type COMPARTMENT \
--display-name "Production-Monthly-Budget" \
--description "Monthly budget for production"
# Add alert rules
oci budgets alert-rule create \
--budget-id $BUDGET_ID \
--type ACTUAL \
--threshold 80 \
--threshold-type PERCENTAGE \
--recipients '["finance@example.com"]' \
--display-name "80%-Alert" \
--message "Production spending at 80% of budget"
oci budgets alert-rule create \
--budget-id $BUDGET_ID \
--type FORECAST \
--threshold 100 \
--threshold-type PERCENTAGE \
--recipients '["finance@example.com","ops@example.com"]' \
--display-name "Forecast-Exceed" \
--message "Production forecast to exceed budget"
Cost Optimization¶
Identifying Unused Resources:
import oci
from datetime import datetime, timedelta
config = oci.config.from_file()
def find_unused_resources():
compute = oci.core.ComputeClient(config)
block_storage = oci.core.BlockstorageClient(config)
unused = {
"stopped_instances": [],
"unattached_volumes": [],
"old_backups": []
}
# Find stopped instances (>30 days)
instances = compute.list_instances(
config["compartment_id"],
lifecycle_state="STOPPED"
).data
cutoff = datetime.now() - timedelta(days=30)
for instance in instances:
if instance.time_created < cutoff:
unused["stopped_instances"].append({
"name": instance.display_name,
"id": instance.id,
"age_days": (datetime.now() - instance.time_created).days
})
# Find unattached volumes
volumes = block_storage.list_volumes(
config["compartment_id"],
lifecycle_state="AVAILABLE"
).data
for volume in volumes:
attachments = compute.list_volume_attachments(
config["compartment_id"],
volume_id=volume.id
).data
if not attachments:
unused["unattached_volumes"].append({
"name": volume.display_name,
"id": volume.id,
"size_gb": volume.size_in_gbs,
"cost_per_month": volume.size_in_gbs * 0.085
})
# Find old backups (>365 days)
backups = block_storage.list_volume_backups(
config["compartment_id"]
).data
cutoff = datetime.now() - timedelta(days=365)
for backup in backups:
if backup.time_created < cutoff:
unused["old_backups"].append({
"name": backup.display_name,
"id": backup.id,
"age_days": (datetime.now() - backup.time_created).days
})
return unused
# Find and report
unused = find_unused_resources()
print(f"Stopped instances (>30 days): {len(unused['stopped_instances'])}")
print(f"Unattached volumes: {len(unused['unattached_volumes'])}")
print(f"Old backups (>1 year): {len(unused['old_backups'])}")
Right-Sizing Recommendations:
def analyze_utilization():
# Get CPU utilization for last 30 days
monitoring = oci.monitoring.MonitoringClient(config)
end_time = datetime.now()
start_time = end_time - timedelta(days=30)
metrics = monitoring.summarize_metrics_data(
compartment_id=config["compartment_id"],
summarize_metrics_data_details=oci.monitoring.models.SummarizeMetricsDataDetails(
namespace="oci_computeagent",
query="CpuUtilization[1d].mean()",
start_time=start_time,
end_time=end_time
)
).data
recommendations = []
for metric in metrics:
avg_cpu = sum([dp.value for dp in metric.aggregated_datapoints]) / len(metric.aggregated_datapoints)
if avg_cpu < 20:
recommendations.append({
"resource": metric.dimensions["resourceId"],
"current_usage": f"{avg_cpu:.1f}%",
"recommendation": "Consider downsizing or stopping"
})
return recommendations
Billing and Usage¶
Usage Reports¶
Downloading Usage Reports:
# List available reports
oci usage-api usage-summary request-summarized-usages \
--tenant-id $TENANCY_ID \
--time-usage-started "2024-10-01T00:00:00Z" \
--time-usage-ended "2024-10-31T23:59:59Z" \
--granularity MONTHLY
# Export to CSV
oci usage-api usage-summary request-summarized-usages \
--tenant-id $TENANCY_ID \
--time-usage-started "2024-10-01T00:00:00Z" \
--time-usage-ended "2024-10-31T23:59:59Z" \
--granularity DAILY \
--output-file usage-report.json
Cost Allocation¶
Tagging for Cost Tracking:
# Define cost tracking tags
oci iam tag create \
--tag-namespace-id $NAMESPACE_ID \
--name "CostCenter" \
--description "Cost center for billing"
oci iam tag create \
--tag-namespace-id $NAMESPACE_ID \
--name "Project" \
--description "Project name"
# Apply to resources
oci compute instance update \
--instance-id $INSTANCE_ID \
--defined-tags '{
"Finance": {
"CostCenter": "Engineering",
"Project": "WebApp"
}
}'
# View costs by tag
oci usage-api usage-summary request-summarized-usages \
--tenant-id $TENANCY_ID \
--time-usage-started "2024-10-01T00:00:00Z" \
--time-usage-ended "2024-10-31T23:59:59Z" \
--granularity MONTHLY \
--group-by '["tags"]'
Exam Tips¶
Critical Concepts¶
Security Operations: - Cloud Guard: Detect and respond to security issues - Security Zones: Prevent non-compliant configurations - Vault: Manage encryption keys - Audit logs: Track all API activity (90 days)
IAM: - Users, groups, policies - MFA enforcement for admins - Dynamic groups for resource principals - Least privilege principle
Compliance: - Audit logs: Who did what, when - Compliance reports: Regular checks - Security zones for high-security compartments - Tag resources for tracking
Cost Management: - Budgets: Set spending limits - Tags: Track costs by project/department - Unused resources: Identify and cleanup - Right-sizing: Match resources to workload
Common Scenarios¶
Q: Enforce encryption for all resources? A: Security Zones with maximum security recipe
Q: Track who deleted an instance? A: Search audit logs for DeleteInstance operation
Q: Alert when spending reaches $4000? A: Budget with 80% threshold alert
Q: Auto-remediate public buckets? A: Cloud Guard responder with auto-action mode
Q: Find unused volumes? A: List volumes with AVAILABLE state and no attachments
Summary¶
Security: Cloud Guard, Security Zones, Vault, audit logs
IAM: Users, groups, policies, dynamic groups, MFA
Compliance: Audit logs, compliance checks, reporting
Cost: Budgets, tags, usage reports, optimization
Operations: Automation, monitoring, proactive management
Congratulations on completing OCI Operations Associate study notes!