Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove SAS dependency for Data Protection blob access #555

Merged
merged 7 commits into from
Apr 17, 2024
Merged
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
4 changes: 2 additions & 2 deletions Dfe.Academies.External.Web/Dfe.Academies.External.Web.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@

<ItemGroup>
<PackageReference Include="AutoMapper" Version="13.0.1" />
<PackageReference Include="Azure.Extensions.AspNetCore.DataProtection.Blobs" Version="1.3.3" />
<PackageReference Include="Azure.Storage.Blobs" Version="12.19.1" />
<PackageReference Include="Azure.Extensions.AspNetCore.DataProtection.Keys" Version="1.2.3" />
<PackageReference Include="Azure.Identity" Version="1.11.0" />
<PackageReference Include="Dfe.Academies.Contracts" Version="1.0.10" />
<PackageReference Include="Dfe.Academisation.CorrelationIdMiddleware" Version="2.0.2" />
<PackageReference Include="FluentValidation" Version="11.9.0" />
Expand Down
25 changes: 16 additions & 9 deletions Dfe.Academies.External.Web/Program.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using System.Globalization;
using Azure.Storage.Blobs;
using Azure.Identity;
using Dfe.Academies.External.Web.AutoMapper;
using Dfe.Academies.External.Web.Extensions;
using Dfe.Academies.External.Web.Factories;
Expand Down Expand Up @@ -28,7 +28,7 @@
var builder = WebApplication.CreateBuilder(args);
ConfigurationManager configuration = builder.Configuration;

//https://github.com/gunndabad/govuk-frontend-aspnetcore
//https://github.com/gunndabad/govuk-frontend-aspnetcore
builder.Services.AddGovUkFrontend();

builder.Services
Expand Down Expand Up @@ -206,7 +206,7 @@ static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy()
options.DefaultRequestCulture = new RequestCulture("en-GB");
// By default the below will be set to whatever the server culture is.
options.SupportedCultures = supportedCultures;
// Supported cultures is a list of cultures that your web app will be able to run under. By default this is set to a the culture of the machine.
// Supported cultures is a list of cultures that your web app will be able to run under. By default this is set to a the culture of the machine.
options.SupportedUICultures = supportedCultures;
});

Expand All @@ -230,13 +230,20 @@ static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy()
var localDevelopment = builder.Configuration.GetValue<bool>("local_development");
if (!localDevelopment)
{
string blobName = "keys.xml";
BlobContainerClient container = new BlobContainerClient(new Uri(builder.Configuration["ConnectionStrings:BlobStorage"]));
// Setup basic Data Protection and persist keys.xml to local file system
var dp = builder.Services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo(@"/srv/app/storage"));

BlobClient blobClient = container.GetBlobClient(blobName);

builder.Services.AddDataProtection()
.PersistKeysToAzureBlobStorage(blobClient);
// If a Key Vault Key URI is defined, expect to encrypt the keys.xml
string? kvProtectionKeyUri = builder.Configuration.GetValue<string>("DataProtection:KeyVaultKey");
if (!string.IsNullOrEmpty(kvProtectionKeyUri))
{
var credentials = new DefaultAzureCredential();
dp.ProtectKeysWithAzureKeyVault(
new Uri(kvProtectionKeyUri),
credentials
);
}
}

builder.Services.AddQuartz(q => { q.UseMicrosoftDependencyInjectionJobFactory(); });
Expand Down
7 changes: 5 additions & 2 deletions Dfe.Academies.External.Web/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"SupportEmail": "[email protected]",
"TestMode": true
},

"Sharepoint": {
"ApiUrl": "",
"ClientId": "",
Expand All @@ -46,6 +46,9 @@
"BlobStorage": "",
"RedisCache": ""
},
"DataProtection": {
"KeyVaultKey": ""
},
"Google": {
"AnalyticsKey": "UA-140729870-2",
"TagManagerId": "GTM-59S3WZ4",
Expand All @@ -71,5 +74,5 @@
}
},
"MaintenanceMode" : false

}
3 changes: 3 additions & 0 deletions terraform/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ No providers.
|------|--------|---------|
| <a name="module_azure_container_apps_hosting"></a> [azure\_container\_apps\_hosting](#module\_azure\_container\_apps\_hosting) | github.com/DFE-Digital/terraform-azurerm-container-apps-hosting | v1.6.1 |
| <a name="module_azurerm_key_vault"></a> [azurerm\_key\_vault](#module\_azurerm\_key\_vault) | github.com/DFE-Digital/terraform-azurerm-key-vault-tfvars | v0.4.1 |
| <a name="module_data_protection"></a> [data\_protection](#module\_data\_protection) | github.com/DFE-Digital/terraform-azurerm-aspnet-data-protection | v1.0.0 |
| <a name="module_statuscake-tls-monitor"></a> [statuscake-tls-monitor](#module\_statuscake-tls-monitor) | github.com/dfe-digital/terraform-statuscake-tls-monitor | v0.1.3 |

## Resources
Expand All @@ -157,6 +158,7 @@ No resources.
| <a name="input_cdn_frontdoor_origin_fqdn_override"></a> [cdn\_frontdoor\_origin\_fqdn\_override](#input\_cdn\_frontdoor\_origin\_fqdn\_override) | Manually specify the hostname that the CDN Front Door should target. Defaults to the Container App FQDN | `string` | `""` | no |
| <a name="input_cdn_frontdoor_origin_host_header_override"></a> [cdn\_frontdoor\_origin\_host\_header\_override](#input\_cdn\_frontdoor\_origin\_host\_header\_override) | Manually specify the host header that the CDN sends to the target. Defaults to the recieved host header. Set to null to set it to the host\_name (`cdn_frontdoor_origin_fqdn_override`) | `string` | `""` | no |
| <a name="input_cdn_frontdoor_rate_limiting_threshold"></a> [cdn\_frontdoor\_rate\_limiting\_threshold](#input\_cdn\_frontdoor\_rate\_limiting\_threshold) | Maximum number of concurrent requests per minute threshold before rate limiting is applied | `number` | n/a | yes |
| <a name="input_container_app_file_share_mount_path"></a> [container\_app\_file\_share\_mount\_path](#input\_container\_app\_file\_share\_mount\_path) | A path inside your container where the File Share will be mounted to | `string` | `"/srv/app/storage"` | no |
| <a name="input_container_apps_allow_ips_inbound"></a> [container\_apps\_allow\_ips\_inbound](#input\_container\_apps\_allow\_ips\_inbound) | Restricts access to the Container Apps by creating a network security group rule that only allow inbound traffic from the provided list of IPs | `list(string)` | `[]` | no |
| <a name="input_container_command"></a> [container\_command](#input\_container\_command) | Container command | `list(any)` | n/a | yes |
| <a name="input_container_max_replicas"></a> [container\_max\_replicas](#input\_container\_max\_replicas) | Container max replicas | `number` | `2` | no |
Expand All @@ -169,6 +171,7 @@ No resources.
| <a name="input_enable_cdn_frontdoor"></a> [enable\_cdn\_frontdoor](#input\_enable\_cdn\_frontdoor) | Enable Azure CDN Front Door. This will use the Container Apps endpoint as the origin. | `bool` | n/a | yes |
| <a name="input_enable_cdn_frontdoor_health_probe"></a> [enable\_cdn\_frontdoor\_health\_probe](#input\_enable\_cdn\_frontdoor\_health\_probe) | Enable CDN Front Door health probe | `bool` | `false` | no |
| <a name="input_enable_container_app_blob_storage"></a> [enable\_container\_app\_blob\_storage](#input\_enable\_container\_app\_blob\_storage) | Create an Azure Storage Account and Storage Container to be accessed by the Container App | `bool` | n/a | yes |
| <a name="input_enable_container_app_file_share"></a> [enable\_container\_app\_file\_share](#input\_enable\_container\_app\_file\_share) | Create an Azure Storage Account and File Share to be mounted to the Container Apps | `bool` | n/a | yes |
| <a name="input_enable_container_health_probe"></a> [enable\_container\_health\_probe](#input\_enable\_container\_health\_probe) | Enable liveness probes for the Container | `bool` | `true` | no |
| <a name="input_enable_container_registry"></a> [enable\_container\_registry](#input\_enable\_container\_registry) | Set to true to create a container registry | `bool` | n/a | yes |
| <a name="input_enable_dns_zone"></a> [enable\_dns\_zone](#input\_enable\_dns\_zone) | Conditionally create a DNS zone | `bool` | n/a | yes |
Expand Down
2 changes: 2 additions & 0 deletions terraform/container-apps-hosting.tf
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ module "azure_container_apps_hosting" {
enable_container_health_probe = local.enable_container_health_probe

enable_container_app_blob_storage = local.enable_container_app_blob_storage
enable_container_app_file_share = local.enable_container_app_file_share
container_app_file_share_mount_path = local.container_app_file_share_mount_path
storage_account_ipv4_allow_list = local.storage_account_ipv4_allow_list
storage_account_public_access_enabled = local.storage_account_public_access_enabled

Expand Down
11 changes: 11 additions & 0 deletions terraform/data-protection.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module "data_protection" {
source = "github.com/DFE-Digital/terraform-azurerm-aspnet-data-protection?ref=v1.0.0"

data_protection_key_vault_assign_role = false
data_protection_key_vault_subnet_prefix = "172.16.100.0/28"
data_protection_key_vault_access_ipv4 = local.key_vault_access_ipv4
data_protection_resource_prefix = "${local.environment}${local.project_name}"
data_protection_azure_location = local.azure_location
data_protection_tags = local.tags
data_protection_resource_group_name = module.azure_container_apps_hosting.azurerm_resource_group_default.name
}
2 changes: 2 additions & 0 deletions terraform/locals.tf
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ locals {
monitor_email_receivers = var.monitor_email_receivers
existing_logic_app_workflow = var.existing_logic_app_workflow
enable_container_app_blob_storage = var.enable_container_app_blob_storage
enable_container_app_file_share = var.enable_container_app_file_share
container_app_file_share_mount_path = var.container_app_file_share_mount_path
storage_account_ipv4_allow_list = var.storage_account_ipv4_allow_list
storage_account_public_access_enabled = var.storage_account_public_access_enabled
existing_network_watcher_name = var.existing_network_watcher_name
Expand Down
11 changes: 11 additions & 0 deletions terraform/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,17 @@ variable "enable_container_app_blob_storage" {
type = bool
}

variable "enable_container_app_file_share" {
description = "Create an Azure Storage Account and File Share to be mounted to the Container Apps"
type = bool
}

variable "container_app_file_share_mount_path" {
description = "A path inside your container where the File Share will be mounted to"
type = string
default = "/srv/app/storage"
}

variable "storage_account_ipv4_allow_list" {
description = "A list of public IPv4 address to grant access to the Blob Storage Account"
type = list(string)
Expand Down
Loading