Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ def __init__(self):
self.billing_client = BillingManagementClient(credential=self.__default_creds,
subscription_id=self.subscription_id)
self.__account_id = self.__environment_variables_dict.get('AZURE_ACCOUNT_ID')
self.global_tags = self.__environment_variables_dict.get('GLOBAL_TAGS')
self.cloud_name = 'AZURE'
self.scope = f'subscriptions/{self.subscription_id}'

Expand Down
1 change: 1 addition & 0 deletions cloud_governance/main/environment_variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ def __init__(self):
self._environment_variables_dict['account'] = EnvironmentVariables.get_env('account', '').upper().strip()
self._environment_variables_dict['AWS_DEFAULT_REGION'] = EnvironmentVariables.get_env('AWS_DEFAULT_REGION', '')
self._environment_variables_dict['log_level'] = EnvironmentVariables.get_env('log_level', 'INFO')
self._environment_variables_dict['GLOBAL_TAGS'] = literal_eval(EnvironmentVariables.get_env('GLOBAL_TAGS', "{}"))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this GLOBAL_TAGS?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @inntran,

app-code: 
service-phase: 
cost-center: 


self._environment_variables_dict['DAYS_TO_TAKE_ACTION'] = int(
EnvironmentVariables.get_env('DAYS_TO_TAKE_ACTION', "7"))
Expand Down
2 changes: 1 addition & 1 deletion cloud_governance/main/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ def main():
if environment_variables_dict.get('PUBLIC_CLOUD_NAME') and environment_variables_dict.get(
'PUBLIC_CLOUD_NAME').upper() == 'AZURE':
azure_cost_policy_runner = None
is_azure_policy_runner = policy in environment_variables_dict.get('cost_policies')
is_azure_policy_runner = policy in environment_variables_dict.get('cost_policies') or environment_variables_dict.get('azure_policies')
if is_azure_policy_runner:
azure_cost_policy_runner = AzurePolicyRunner()

Expand Down
74 changes: 74 additions & 0 deletions cloud_governance/policy/azure/tag_azure_resource_group.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
from azure.mgmt.resource import ResourceManagementClient
from cloud_governance.common.logger.init_logger import logger
from cloud_governance.common.clouds.azure.subscriptions.azure_operations import AzureOperations


class TagAzureResourceGroup:
def __init__(self):
"""
Initialize Azure clients and set the tags to apply.

:param tags_to_add: Dictionary of tags to add to resource groups and their resources.
"""
self.azure_operations = AzureOperations()
self.subscription_id = self.azure_operations.subscription_id
self.credential = self.azure_operations._AzureOperations__default_creds # reuse credentials
self.resource_client = ResourceManagementClient(self.credential, self.subscription_id)
self.tags_to_add = self.azure_operations.global_tags

def tag_all(self):
"""
Tag all resource groups and their contained resources with the specified tags.
"""
resource_groups = self.resource_client.resource_groups.list()

for rg in resource_groups:
logger.info(f"Processing resource group: {rg.name}")

# Tag the resource group
try:
self.resource_client.resource_groups.update(
resource_group_name=rg.name,
parameters={"tags": self.tags_to_add}
)
logger.info(f"Tagged resource group: {rg.name}")
except Exception as e:
logger.error(f"Failed to tag resource group {rg.name}: {e}")
continue

# Tag all resources in the resource group
for resource in self.resource_client.resources.list_by_resource_group(rg.name):
logger.info(f" Tagging resource: {resource.name} ({resource.type})")

existing_tags = resource.tags or {}
updated_tags = {**existing_tags, **self.tags_to_add}

try:
provider_ns, resource_type_str = resource.type.split('/')
provider = self.resource_client.providers.get(provider_ns)
resource_type_info = next(
rt for rt in provider.resource_types if rt.resource_type.lower() == resource_type_str.lower()
)
api_version = next(
(v for v in resource_type_info.api_versions if 'preview' not in v.lower()),
resource_type_info.api_versions[0]
)

poller = self.resource_client.resources.begin_update_by_id(
resource_id=resource.id,
api_version=api_version,
parameters={
'location': resource.location,
'tags': updated_tags
}
)
poller.result()
logger.info(f" Tagged resource: {resource.name}")
except Exception as e:
logger.error(f" Failed to tag resource {resource.name}: {e}")

def run(self):
"""
This method tags all Azure resources.
"""
self.tag_all()
2 changes: 1 addition & 1 deletion jenkins/clouds/azure/daily/policies/run_policies.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def get_policies(file_type: str = '.py', exclude_policies: list = None):
return custodian_policies


GLOBAL_COST_POLICIES = ['cost_billing_reports']
GLOBAL_COST_POLICIES = ['cost_billing_reports', 'tag_azure_resource_group']
available_policies = get_policies(exclude_policies=GLOBAL_COST_POLICIES)


Expand Down
73 changes: 73 additions & 0 deletions jenkins/clouds/azure/hourly/tagging/Jenkinsfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
def accounts_list = ['perfscale']
pipeline {
agent {
docker {
label 'cloud-governance-worker'
image 'quay.io/cloud-governance/centos-stream8-podman:latest'
args '-u root -v /etc/postfix/main.cf:/etc/postfix/main.cf --privileged'
}
}
environment {
QUAY_CLOUD_GOVERNANCE_REPOSITORY = credentials('QUAY_CLOUD_GOVERNANCE_REPOSITORY')
POLICIES_IN_ACTION = '[]'
AZURE_CLIENT_SECRET = credentials('cloud-governance-azure-client-secret')
AZURE_TENANT_ID = credentials('cloud-governance-azure-tenant-id')
AZURE_ACCOUNT_ID = credentials('cloud-governance-azure-account-id')
AZURE_CLIENT_ID = credentials('cloud-governance-azure-client-id')
ES_HOST = credentials('cloud-governance-es-host')
ES_PORT = credentials('cloud-governance-es-port')
LDAP_HOST_NAME = credentials('cloud-governance-ldap-host-name')
GLOBAL_TAGS = credentials('GLOBAL_TAGS')
contact2 = "yinsong@redhat.com"
}
stages {
stage('Checkout') { // Checkout (git clone ...) the projects repository
steps {
checkout scm
}
}
stage('Initial Cleanup') {
steps {
sh '''if [[ "$(podman images -q ${QUAY_CLOUD_GOVERNANCE_REPOSITORY} 2> /dev/null)" != "" ]]; then podman rmi -f $(podman images -q ${QUAY_CLOUD_GOVERNANCE_REPOSITORY} 2> /dev/null); fi'''
}
}
stage('Run Azure Policies') {
steps {
script {
for (account in accounts_list ) {
echo "Running for account ${account.toUpperCase()}"
withCredentials([string(credentialsId: "${account}-azure-client-secret", variable: 'client_secret'),
string(credentialsId: "${account}-azure-client-id", variable: 'client_id'),
string(credentialsId: "${account}-azure-tenant-id", variable: 'tenant_id'),
string(credentialsId: "${account}-azure-subscription-id", variable: 'subscription_id'),
string(credentialsId: "${account}-azure-account-id", variable: 'account_id')]) {
env.account_name = "Azure-${account}"
sh 'python3 jenkins/clouds/azure/daily/policies/run_policies.py'
}
}
}
}
}
stage('Finalize Cleanup') {
steps {
sh '''if [[ "$(podman images -q ${QUAY_CLOUD_GOVERNANCE_REPOSITORY} 2> /dev/null)" != "" ]]; then podman rmi -f $(podman images -q ${QUAY_CLOUD_GOVERNANCE_REPOSITORY} 2> /dev/null); fi'''
deleteDir()
}
}
}
post {
always {
deleteDir()
}
failure {
script {
msg = "Build error for ${env.JOB_NAME} ${env.BUILD_NUMBER} (${env.BUILD_URL})"
emailext body: """\
Jenkins job: ${env.BUILD_URL}\nSee the console output for more details: ${env.BUILD_URL}consoleFull\n\n
""",
subject: msg,
to: "${contact2}"
}
}
}
}
30 changes: 30 additions & 0 deletions jenkins/clouds/azure/hourly/tagging/tagging.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import os

# Read environment variables
AZURE_CLIENT_SECRET = os.environ['AZURE_CLIENT_SECRET']
AZURE_TENANT_ID = os.environ['AZURE_TENANT_ID']
AZURE_CLIENT_ID = os.environ['AZURE_CLIENT_ID']
AZURE_ACCOUNT_ID = os.environ['AZURE_ACCOUNT_ID']
GLOBAL_TAGS = os.environ['GLOBAL_TAGS']
QUAY_CLOUD_GOVERNANCE_REPOSITORY = os.environ.get(
'QUAY_CLOUD_GOVERNANCE_REPOSITORY',
'quay.io/cloud-governance/cloud-governance:latest'
)

print('Running the Azure tagging')

# Setup container environment variables
input_vars_to_container = [{
'account': 'perf-scale-azure',
'AZURE_CLIENT_ID': AZURE_CLIENT_ID,
'AZURE_TENANT_ID': AZURE_TENANT_ID,
'AZURE_CLIENT_SECRET': AZURE_CLIENT_SECRET,
'AZURE_ACCOUNT_ID': AZURE_ACCOUNT_ID,
'GLOBAL_TAGS': GLOBAL_TAGS
}]

for input_vars in input_vars_to_container:
envs = [f"{k}={v}" for k, v in input_vars.items()]
env_flags = ' '.join([f'-e {env}' for env in envs])
cmd = f"podman run --rm --name cloud-governance {env_flags} -e policy=tag_azure_resource_group {QUAY_CLOUD_GOVERNANCE_REPOSITORY}"
os.system(cmd)
Loading