fedramp-20x-mcp 0.4.8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fedramp_20x_mcp/__init__.py +14 -0
- fedramp_20x_mcp/__main__.py +12 -0
- fedramp_20x_mcp/data_loader.py +673 -0
- fedramp_20x_mcp/prompts/__init__.py +62 -0
- fedramp_20x_mcp/prompts/api_design_guide.txt +432 -0
- fedramp_20x_mcp/prompts/ato_package_checklist.txt +75 -0
- fedramp_20x_mcp/prompts/audit_preparation.txt +592 -0
- fedramp_20x_mcp/prompts/authorization_boundary_review.txt +76 -0
- fedramp_20x_mcp/prompts/azure_ksi_automation.txt +997 -0
- fedramp_20x_mcp/prompts/continuous_monitoring_setup.txt +61 -0
- fedramp_20x_mcp/prompts/documentation_generator.txt +499 -0
- fedramp_20x_mcp/prompts/gap_analysis.txt +25 -0
- fedramp_20x_mcp/prompts/initial_assessment_roadmap.txt +202 -0
- fedramp_20x_mcp/prompts/ksi_implementation_priorities.txt +283 -0
- fedramp_20x_mcp/prompts/migration_from_rev5.txt +440 -0
- fedramp_20x_mcp/prompts/quarterly_review_checklist.txt +231 -0
- fedramp_20x_mcp/prompts/significant_change_assessment.txt +50 -0
- fedramp_20x_mcp/prompts/vendor_evaluation.txt +349 -0
- fedramp_20x_mcp/prompts/vulnerability_remediation_timeline.txt +45 -0
- fedramp_20x_mcp/server.py +270 -0
- fedramp_20x_mcp/templates/__init__.py +75 -0
- fedramp_20x_mcp/templates/bicep/afr.txt +33 -0
- fedramp_20x_mcp/templates/bicep/cna.txt +48 -0
- fedramp_20x_mcp/templates/bicep/generic.txt +47 -0
- fedramp_20x_mcp/templates/bicep/iam.txt +211 -0
- fedramp_20x_mcp/templates/bicep/mla.txt +82 -0
- fedramp_20x_mcp/templates/bicep/rpl.txt +44 -0
- fedramp_20x_mcp/templates/bicep/svc.txt +54 -0
- fedramp_20x_mcp/templates/code/generic_csharp.txt +65 -0
- fedramp_20x_mcp/templates/code/generic_powershell.txt +65 -0
- fedramp_20x_mcp/templates/code/generic_python.txt +63 -0
- fedramp_20x_mcp/templates/code/iam_csharp.txt +150 -0
- fedramp_20x_mcp/templates/code/iam_powershell.txt +162 -0
- fedramp_20x_mcp/templates/code/iam_python.txt +224 -0
- fedramp_20x_mcp/templates/code/mla_python.txt +124 -0
- fedramp_20x_mcp/templates/terraform/afr.txt +29 -0
- fedramp_20x_mcp/templates/terraform/cna.txt +50 -0
- fedramp_20x_mcp/templates/terraform/generic.txt +40 -0
- fedramp_20x_mcp/templates/terraform/iam.txt +219 -0
- fedramp_20x_mcp/templates/terraform/mla.txt +29 -0
- fedramp_20x_mcp/templates/terraform/rpl.txt +32 -0
- fedramp_20x_mcp/templates/terraform/svc.txt +46 -0
- fedramp_20x_mcp/tools/__init__.py +167 -0
- fedramp_20x_mcp/tools/definitions.py +154 -0
- fedramp_20x_mcp/tools/documentation.py +155 -0
- fedramp_20x_mcp/tools/enhancements.py +2256 -0
- fedramp_20x_mcp/tools/evidence.py +701 -0
- fedramp_20x_mcp/tools/export.py +753 -0
- fedramp_20x_mcp/tools/ksi.py +90 -0
- fedramp_20x_mcp/tools/requirements.py +163 -0
- fedramp_20x_mcp-0.4.8.dist-info/METADATA +877 -0
- fedramp_20x_mcp-0.4.8.dist-info/RECORD +55 -0
- fedramp_20x_mcp-0.4.8.dist-info/WHEEL +4 -0
- fedramp_20x_mcp-0.4.8.dist-info/entry_points.txt +2 -0
- fedramp_20x_mcp-0.4.8.dist-info/licenses/LICENSE +27 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
## Python Code
|
|
2
|
+
|
|
3
|
+
```python
|
|
4
|
+
#!/usr/bin/env python3
|
|
5
|
+
\"\"\"
|
|
6
|
+
Monitoring, Logging & Analysis Evidence Collector
|
|
7
|
+
Collects log coverage, retention, and SIEM evidence
|
|
8
|
+
\"\"\"
|
|
9
|
+
|
|
10
|
+
import os
|
|
11
|
+
import json
|
|
12
|
+
from datetime import datetime, timedelta
|
|
13
|
+
from azure.identity import DefaultAzureCredential
|
|
14
|
+
from azure.monitor.query import LogsQueryClient
|
|
15
|
+
from azure.storage.blob import BlobServiceClient
|
|
16
|
+
|
|
17
|
+
WORKSPACE_ID = os.environ["LOG_ANALYTICS_WORKSPACE_ID"]
|
|
18
|
+
STORAGE_ACCOUNT = os.environ["EVIDENCE_STORAGE_ACCOUNT"]
|
|
19
|
+
|
|
20
|
+
def collect_log_coverage_evidence():
|
|
21
|
+
\"\"\"Collect evidence of log sources for KSI-MLA-02\"\"\"
|
|
22
|
+
credential = DefaultAzureCredential(
|
|
23
|
+
exclude_environment_credential=False,
|
|
24
|
+
exclude_managed_identity_credential=False,
|
|
25
|
+
exclude_shared_token_cache_credential=True
|
|
26
|
+
)
|
|
27
|
+
logs_client = LogsQueryClient(credential)
|
|
28
|
+
|
|
29
|
+
# Query to find all distinct log sources
|
|
30
|
+
query = \"\"\"
|
|
31
|
+
union *
|
|
32
|
+
| where TimeGenerated > ago(7d)
|
|
33
|
+
| distinct Type
|
|
34
|
+
| summarize LogTypes = make_set(Type)
|
|
35
|
+
\"\"\"
|
|
36
|
+
|
|
37
|
+
response = logs_client.query_workspace(
|
|
38
|
+
workspace_id=WORKSPACE_ID,
|
|
39
|
+
query=query,
|
|
40
|
+
timespan=timedelta(days=7)
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
log_types = []
|
|
44
|
+
for table in response.tables:
|
|
45
|
+
for row in table.rows:
|
|
46
|
+
log_types = row[0]
|
|
47
|
+
|
|
48
|
+
evidence = {
|
|
49
|
+
"collection_date": datetime.utcnow().isoformat(),
|
|
50
|
+
"ksi_id": "KSI-MLA-02",
|
|
51
|
+
"workspace_id": WORKSPACE_ID,
|
|
52
|
+
"log_sources_count": len(log_types),
|
|
53
|
+
"log_sources": log_types,
|
|
54
|
+
"required_sources": [
|
|
55
|
+
"AzureActivity",
|
|
56
|
+
"SigninLogs",
|
|
57
|
+
"AuditLogs",
|
|
58
|
+
"SecurityEvent",
|
|
59
|
+
"Syslog",
|
|
60
|
+
"ContainerLog"
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
# Check coverage
|
|
65
|
+
required = set(evidence["required_sources"])
|
|
66
|
+
actual = set(log_types)
|
|
67
|
+
evidence["missing_sources"] = list(required - actual)
|
|
68
|
+
evidence["coverage_percentage"] = len(actual & required) / len(required) * 100
|
|
69
|
+
|
|
70
|
+
return evidence
|
|
71
|
+
|
|
72
|
+
def collect_retention_evidence():
|
|
73
|
+
\"\"\"Collect log retention configuration evidence\"\"\"
|
|
74
|
+
credential = DefaultAzureCredential()
|
|
75
|
+
|
|
76
|
+
# Query workspace retention settings
|
|
77
|
+
from azure.mgmt.loganalytics import LogAnalyticsManagementClient
|
|
78
|
+
|
|
79
|
+
client = LogAnalyticsManagementClient(credential, os.environ["AZURE_SUBSCRIPTION_ID"])
|
|
80
|
+
workspaces = client.workspaces.list()
|
|
81
|
+
|
|
82
|
+
retention_report = {
|
|
83
|
+
"collection_date": datetime.utcnow().isoformat(),
|
|
84
|
+
"ksi_id": "KSI-MLA-02",
|
|
85
|
+
"workspaces": []
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
for workspace in workspaces:
|
|
89
|
+
retention_report["workspaces"].append({
|
|
90
|
+
"name": workspace.name,
|
|
91
|
+
"retention_days": workspace.retention_in_days,
|
|
92
|
+
"compliant": workspace.retention_in_days >= 365 # FedRAMP minimum
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
return retention_report
|
|
96
|
+
|
|
97
|
+
async def main():
|
|
98
|
+
print("Starting MLA evidence collection")
|
|
99
|
+
|
|
100
|
+
# Collect evidence
|
|
101
|
+
coverage = collect_log_coverage_evidence()
|
|
102
|
+
print(f"Log Coverage: {coverage['coverage_percentage']:.1f}%")
|
|
103
|
+
|
|
104
|
+
retention = collect_retention_evidence()
|
|
105
|
+
print(f"Workspaces checked: {len(retention['workspaces'])}")
|
|
106
|
+
|
|
107
|
+
# Store evidence
|
|
108
|
+
credential = DefaultAzureCredential()
|
|
109
|
+
blob_client = BlobServiceClient(
|
|
110
|
+
account_url=f"https://{STORAGE_ACCOUNT}.blob.core.windows.net",
|
|
111
|
+
credential=credential
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
timestamp = datetime.utcnow().strftime("%Y-%m-%d")
|
|
115
|
+
for evidence_type, evidence_data in [("coverage", coverage), ("retention", retention)]:
|
|
116
|
+
blob_name = f"ksi-mla-02/{evidence_type}-{timestamp}.json"
|
|
117
|
+
blob = blob_client.get_blob_client(container="mla-evidence", blob=blob_name)
|
|
118
|
+
blob.upload_blob(json.dumps(evidence_data, indent=2), overwrite=True)
|
|
119
|
+
print(f"✓ Stored: {blob_name}")
|
|
120
|
+
|
|
121
|
+
if __name__ == "__main__":
|
|
122
|
+
import asyncio
|
|
123
|
+
asyncio.run(main())
|
|
124
|
+
```
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
## Terraform Configuration
|
|
2
|
+
|
|
3
|
+
```hcl
|
|
4
|
+
# main.tf - Authorization Framework Evidence Collection
|
|
5
|
+
resource "azurerm_storage_account" "afr_evidence" {
|
|
6
|
+
name = "stfedrampafrevidence"
|
|
7
|
+
resource_group_name = azurerm_resource_group.evidence.name
|
|
8
|
+
location = var.location
|
|
9
|
+
account_tier = "Standard"
|
|
10
|
+
account_replication_type = "GRS"
|
|
11
|
+
min_tls_version = "TLS1_2"
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
resource "azurerm_container_registry" "vuln_scanning" {
|
|
15
|
+
name = "acrfedrampvuln"
|
|
16
|
+
resource_group_name = azurerm_resource_group.evidence.name
|
|
17
|
+
location = var.location
|
|
18
|
+
sku = "Premium"
|
|
19
|
+
admin_enabled = false
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
output "storage_account_name" {
|
|
23
|
+
value = azurerm_storage_account.afr_evidence.name
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
output "container_registry_name" {
|
|
27
|
+
value = azurerm_container_registry.vuln_scanning.name
|
|
28
|
+
}
|
|
29
|
+
```
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
## Terraform Configuration
|
|
2
|
+
|
|
3
|
+
```hcl
|
|
4
|
+
# main.tf - Cloud Native Architecture Evidence
|
|
5
|
+
resource "azurerm_log_analytics_workspace" "aks" {
|
|
6
|
+
name = "log-fedramp-aks"
|
|
7
|
+
location = var.location
|
|
8
|
+
resource_group_name = azurerm_resource_group.evidence.name
|
|
9
|
+
sku = "PerGB2018"
|
|
10
|
+
retention_in_days = 730
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
resource "azurerm_kubernetes_cluster" "main" {
|
|
14
|
+
name = "aks-fedramp-prod"
|
|
15
|
+
location = var.location
|
|
16
|
+
resource_group_name = azurerm_resource_group.evidence.name
|
|
17
|
+
dns_prefix = "fedramp"
|
|
18
|
+
|
|
19
|
+
identity {
|
|
20
|
+
type = "SystemAssigned"
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
network_profile {
|
|
24
|
+
network_plugin = "azure"
|
|
25
|
+
network_policy = "calico"
|
|
26
|
+
service_cidr = "10.0.0.0/16"
|
|
27
|
+
dns_service_ip = "10.0.0.10"
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
oms_agent {
|
|
31
|
+
log_analytics_workspace_id = azurerm_log_analytics_workspace.aks.id
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
azure_policy_enabled = true
|
|
35
|
+
|
|
36
|
+
default_node_pool {
|
|
37
|
+
name = "default"
|
|
38
|
+
node_count = 3
|
|
39
|
+
vm_size = "Standard_DS2_v2"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
output "aks_cluster_name" {
|
|
44
|
+
value = azurerm_kubernetes_cluster.main.name
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
output "workspace_id" {
|
|
48
|
+
value = azurerm_log_analytics_workspace.aks.id
|
|
49
|
+
}
|
|
50
|
+
```
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
## Terraform Configuration
|
|
2
|
+
|
|
3
|
+
```hcl
|
|
4
|
+
# main.tf - Generic KSI Evidence Collection Infrastructure
|
|
5
|
+
variable "ksi_id" {
|
|
6
|
+
description = "KSI identifier"
|
|
7
|
+
type = string
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
resource "azurerm_log_analytics_workspace" "generic" {
|
|
11
|
+
name = "log-${lower(var.ksi_id)}"
|
|
12
|
+
location = var.location
|
|
13
|
+
resource_group_name = azurerm_resource_group.evidence.name
|
|
14
|
+
sku = "PerGB2018"
|
|
15
|
+
retention_in_days = 730
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
resource "azurerm_storage_account" "evidence" {
|
|
19
|
+
name = "st${lower(replace(var.ksi_id, "-", ""))}evidence"
|
|
20
|
+
resource_group_name = azurerm_resource_group.evidence.name
|
|
21
|
+
location = var.location
|
|
22
|
+
account_tier = "Standard"
|
|
23
|
+
account_replication_type = "GRS"
|
|
24
|
+
min_tls_version = "TLS1_2"
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
resource "azurerm_storage_container" "evidence" {
|
|
28
|
+
name = "evidence"
|
|
29
|
+
storage_account_name = azurerm_storage_account.evidence.name
|
|
30
|
+
container_access_type = "private"
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
output "storage_account_name" {
|
|
34
|
+
value = azurerm_storage_account.evidence.name
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
output "workspace_id" {
|
|
38
|
+
value = azurerm_log_analytics_workspace.generic.workspace_id
|
|
39
|
+
}
|
|
40
|
+
```
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# main.tf - IAM Evidence Collection Infrastructure
|
|
2
|
+
# Follows Azure CAF naming conventions and WAF best practices
|
|
3
|
+
|
|
4
|
+
terraform {
|
|
5
|
+
required_version = ">= 1.0"
|
|
6
|
+
required_providers {
|
|
7
|
+
azurerm = {
|
|
8
|
+
source = "hashicorp/azurerm"
|
|
9
|
+
version = "~> 3.0"
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
provider "azurerm" {
|
|
15
|
+
features {
|
|
16
|
+
key_vault {
|
|
17
|
+
purge_soft_delete_on_destroy = false
|
|
18
|
+
}
|
|
19
|
+
resource_group {
|
|
20
|
+
prevent_deletion_if_contains_resources = true
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
variable "environment_name" {
|
|
26
|
+
description = "Environment name (prod, dev, test)"
|
|
27
|
+
default = "prod"
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
variable "workload_name" {
|
|
31
|
+
description = "Workload name"
|
|
32
|
+
default = "fedramp"
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
variable "location" {
|
|
36
|
+
description = "Azure region"
|
|
37
|
+
default = "eastus"
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
# CAF recommended tags for governance
|
|
41
|
+
locals {
|
|
42
|
+
tags = {
|
|
43
|
+
Environment = var.environment_name
|
|
44
|
+
Workload = var.workload_name
|
|
45
|
+
CostCenter = "Security"
|
|
46
|
+
ManagedBy = "Terraform"
|
|
47
|
+
Compliance = "FedRAMP"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
# Log Analytics Workspace (CAF naming)
|
|
52
|
+
resource "azurerm_log_analytics_workspace" "iam" {
|
|
53
|
+
name = "log-${var.workload_name}-${var.environment_name}-iam"
|
|
54
|
+
location = var.location
|
|
55
|
+
resource_group_name = azurerm_resource_group.evidence.name
|
|
56
|
+
sku = "PerGB2018"
|
|
57
|
+
retention_in_days = 730 # 2 years for FedRAMP
|
|
58
|
+
tags = local.tags
|
|
59
|
+
|
|
60
|
+
# Prevent accidental deletion
|
|
61
|
+
lifecycle {
|
|
62
|
+
prevent_destroy = true
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
# Storage Account for evidence (CAF naming)
|
|
67
|
+
resource "azurerm_storage_account" "iam_evidence" {
|
|
68
|
+
name = "st${var.workload_name}${var.environment_name}iam"
|
|
69
|
+
resource_group_name = azurerm_resource_group.evidence.name
|
|
70
|
+
location = var.location
|
|
71
|
+
account_tier = "Standard"
|
|
72
|
+
account_replication_type = "GRS" # Geo-redundant for WAF Reliability
|
|
73
|
+
min_tls_version = "TLS1_2"
|
|
74
|
+
https_traffic_only = true
|
|
75
|
+
|
|
76
|
+
# WAF Security best practices
|
|
77
|
+
allow_nested_items_to_be_public = false
|
|
78
|
+
public_network_access_enabled = false # Consider private endpoint
|
|
79
|
+
|
|
80
|
+
identity {
|
|
81
|
+
type = "SystemAssigned"
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
blob_properties {
|
|
85
|
+
delete_retention_policy {
|
|
86
|
+
days = 30 # Soft delete for 30 days
|
|
87
|
+
}
|
|
88
|
+
container_delete_retention_policy {
|
|
89
|
+
days = 30
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
network_rules {
|
|
94
|
+
default_action = "Deny"
|
|
95
|
+
bypass = ["AzureServices"]
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
tags = local.tags
|
|
99
|
+
|
|
100
|
+
lifecycle {
|
|
101
|
+
prevent_destroy = true
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
# Blob container
|
|
106
|
+
resource "azurerm_storage_container" "iam_evidence" {
|
|
107
|
+
name = "iam-evidence"
|
|
108
|
+
storage_account_name = azurerm_storage_account.iam_evidence.name
|
|
109
|
+
container_access_type = "private"
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
# Application Insights (CAF naming)
|
|
113
|
+
resource "azurerm_application_insights" "iam" {
|
|
114
|
+
name = "appi-${var.workload_name}-${var.environment_name}-iam"
|
|
115
|
+
location = var.location
|
|
116
|
+
resource_group_name = azurerm_resource_group.evidence.name
|
|
117
|
+
workspace_id = azurerm_log_analytics_workspace.iam.id
|
|
118
|
+
application_type = "web"
|
|
119
|
+
tags = local.tags
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
# Function App Service Plan (CAF naming)
|
|
123
|
+
resource "azurerm_service_plan" "iam" {
|
|
124
|
+
name = "asp-${var.workload_name}-${var.environment_name}-iam"
|
|
125
|
+
location = var.location
|
|
126
|
+
resource_group_name = azurerm_resource_group.evidence.name
|
|
127
|
+
os_type = "Linux"
|
|
128
|
+
sku_name = "Y1" # Consumption plan
|
|
129
|
+
tags = local.tags
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
# Function App (CAF naming)
|
|
133
|
+
resource "azurerm_linux_function_app" "iam" {
|
|
134
|
+
name = "func-${var.workload_name}-${var.environment_name}-iam"
|
|
135
|
+
location = var.location
|
|
136
|
+
resource_group_name = azurerm_resource_group.evidence.name
|
|
137
|
+
service_plan_id = azurerm_service_plan.iam.id
|
|
138
|
+
storage_account_name = azurerm_storage_account.iam_evidence.name
|
|
139
|
+
https_only = true # WAF Security: Force HTTPS
|
|
140
|
+
|
|
141
|
+
identity {
|
|
142
|
+
type = "SystemAssigned" # WAF Security: Use managed identity
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
site_config {
|
|
146
|
+
application_insights_connection_string = azurerm_application_insights.iam.connection_string
|
|
147
|
+
ftps_state = "Disabled" # WAF Security
|
|
148
|
+
minimum_tls_version = "1.2"
|
|
149
|
+
|
|
150
|
+
application_stack {
|
|
151
|
+
dotnet_version = "8.0"
|
|
152
|
+
use_dotnet_isolated_runtime = true
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
app_settings = {
|
|
157
|
+
"FUNCTIONS_WORKER_RUNTIME" = "dotnet-isolated"
|
|
158
|
+
"LOG_ANALYTICS_WORKSPACE_ID" = azurerm_log_analytics_workspace.iam.workspace_id
|
|
159
|
+
"EVIDENCE_STORAGE_ACCOUNT" = azurerm_storage_account.iam_evidence.name
|
|
160
|
+
"AZURE_STORAGE_IDENTITY_CLIENT_ID" = "SystemAssigned" # Use managed identity
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
tags = local.tags
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
# RBAC: Grant Function App Storage Blob Data Contributor role
|
|
167
|
+
resource "azurerm_role_assignment" "function_storage" {
|
|
168
|
+
scope = azurerm_storage_account.iam_evidence.id
|
|
169
|
+
role_definition_name = "Storage Blob Data Contributor"
|
|
170
|
+
principal_id = azurerm_linux_function_app.iam.identity[0].principal_id
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
# Metric alert for function failures (WAF Reliability)
|
|
174
|
+
resource "azurerm_monitor_metric_alert" "function_failures" {
|
|
175
|
+
name = "alert-${var.workload_name}-${var.environment_name}-iam-failures"
|
|
176
|
+
resource_group_name = azurerm_resource_group.evidence.name
|
|
177
|
+
scopes = [azurerm_linux_function_app.iam.id]
|
|
178
|
+
description = "Alert when IAM evidence collection fails"
|
|
179
|
+
severity = 2
|
|
180
|
+
frequency = "PT5M"
|
|
181
|
+
window_size = "PT15M"
|
|
182
|
+
|
|
183
|
+
criteria {
|
|
184
|
+
metric_namespace = "Microsoft.Web/sites"
|
|
185
|
+
metric_name = "FunctionExecutionCount"
|
|
186
|
+
aggregation = "Total"
|
|
187
|
+
operator = "GreaterThan"
|
|
188
|
+
threshold = 5
|
|
189
|
+
|
|
190
|
+
dimension {
|
|
191
|
+
name = "Status"
|
|
192
|
+
operator = "Include"
|
|
193
|
+
values = ["Failed"]
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
tags = local.tags
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
# Outputs
|
|
201
|
+
output "log_analytics_workspace_id" {
|
|
202
|
+
value = azurerm_log_analytics_workspace.iam.workspace_id
|
|
203
|
+
description = "Log Analytics workspace ID"
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
output "evidence_storage_name" {
|
|
207
|
+
value = azurerm_storage_account.iam_evidence.name
|
|
208
|
+
description = "Evidence storage account name"
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
output "function_app_name" {
|
|
212
|
+
value = azurerm_linux_function_app.iam.name
|
|
213
|
+
description = "Function app name"
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
output "function_app_principal_id" {
|
|
217
|
+
value = azurerm_linux_function_app.iam.identity[0].principal_id
|
|
218
|
+
description = "Function app managed identity principal ID"
|
|
219
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
## Terraform Configuration
|
|
2
|
+
|
|
3
|
+
```hcl
|
|
4
|
+
# main.tf - Monitoring, Logging & Analysis Infrastructure
|
|
5
|
+
resource "azurerm_log_analytics_workspace" "sentinel" {
|
|
6
|
+
name = "log-${var.environment_name}-sentinel"
|
|
7
|
+
location = var.location
|
|
8
|
+
resource_group_name = azurerm_resource_group.evidence.name
|
|
9
|
+
sku = "PerGB2018"
|
|
10
|
+
retention_in_days = 730
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
resource "azurerm_sentinel_log_analytics_workspace_onboarding" "sentinel" {
|
|
14
|
+
workspace_id = azurerm_log_analytics_workspace.sentinel.id
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
resource "azurerm_storage_account" "mla_evidence" {
|
|
18
|
+
name = "st${var.environment_name}mlaevidence"
|
|
19
|
+
resource_group_name = azurerm_resource_group.evidence.name
|
|
20
|
+
location = var.location
|
|
21
|
+
account_tier = "Standard"
|
|
22
|
+
account_replication_type = "GRS"
|
|
23
|
+
min_tls_version = "TLS1_2"
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
output "workspace_id" {
|
|
27
|
+
value = azurerm_log_analytics_workspace.sentinel.workspace_id
|
|
28
|
+
}
|
|
29
|
+
```
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
## Terraform Configuration
|
|
2
|
+
|
|
3
|
+
```hcl
|
|
4
|
+
# main.tf - Backup & Recovery Evidence Collection
|
|
5
|
+
resource "azurerm_recovery_services_vault" "backup" {
|
|
6
|
+
name = "rsv-fedramp-backup"
|
|
7
|
+
location = var.location
|
|
8
|
+
resource_group_name = azurerm_resource_group.evidence.name
|
|
9
|
+
sku = "Standard"
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
resource "azurerm_backup_policy_vm" "daily" {
|
|
13
|
+
name = "DailyBackupPolicy"
|
|
14
|
+
resource_group_name = azurerm_resource_group.evidence.name
|
|
15
|
+
recovery_vault_name = azurerm_recovery_services_vault.backup.name
|
|
16
|
+
|
|
17
|
+
instant_restore_retention_days = 5
|
|
18
|
+
|
|
19
|
+
backup {
|
|
20
|
+
frequency = "Daily"
|
|
21
|
+
time = "02:00"
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
retention_daily {
|
|
25
|
+
count = 30
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
output "recovery_vault_name" {
|
|
30
|
+
value = azurerm_recovery_services_vault.backup.name
|
|
31
|
+
}
|
|
32
|
+
```
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
## Terraform Configuration
|
|
2
|
+
|
|
3
|
+
```hcl
|
|
4
|
+
# main.tf - Service Management Evidence Collection
|
|
5
|
+
resource "azurerm_log_analytics_workspace" "keyvault" {
|
|
6
|
+
name = "log-fedramp-keyvault"
|
|
7
|
+
location = var.location
|
|
8
|
+
resource_group_name = azurerm_resource_group.evidence.name
|
|
9
|
+
sku = "PerGB2018"
|
|
10
|
+
retention_in_days = 730
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
resource "azurerm_key_vault" "secrets" {
|
|
14
|
+
name = "kv-fedramp-secrets"
|
|
15
|
+
location = var.location
|
|
16
|
+
resource_group_name = azurerm_resource_group.evidence.name
|
|
17
|
+
tenant_id = data.azurerm_client_config.current.tenant_id
|
|
18
|
+
sku_name = "standard"
|
|
19
|
+
enable_rbac_authorization = true
|
|
20
|
+
soft_delete_retention_days = 90
|
|
21
|
+
purge_protection_enabled = true
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
resource "azurerm_monitor_diagnostic_setting" "keyvault" {
|
|
25
|
+
name = "kv-diagnostics"
|
|
26
|
+
target_resource_id = azurerm_key_vault.secrets.id
|
|
27
|
+
log_analytics_workspace_id = azurerm_log_analytics_workspace.keyvault.id
|
|
28
|
+
|
|
29
|
+
enabled_log {
|
|
30
|
+
category = "AuditEvent"
|
|
31
|
+
|
|
32
|
+
retention_policy {
|
|
33
|
+
enabled = true
|
|
34
|
+
days = 730
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
output "key_vault_name" {
|
|
40
|
+
value = azurerm_key_vault.secrets.name
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
output "workspace_id" {
|
|
44
|
+
value = azurerm_log_analytics_workspace.keyvault.id
|
|
45
|
+
}
|
|
46
|
+
```
|