Commit 4e945d03 authored by Arturo Hernandez [EPAM]'s avatar Arturo Hernandez [EPAM]
Browse files

IstioGw + AppGw permission update

parent d97abae3
......@@ -25,7 +25,7 @@ This variable group will be used to hold the common values for infrastructure to
| Variable | Value |
|----------|-------|
| AGENT_IMAGE | ubuntu-18.04 |
| AGENT_IMAGE | ubuntu-20.04 |
| BUILD_ARTIFACT_NAME | infra-templates |
| SERVICE_CONNECTION_NAME | <your_service_connection_name> |
| TF_VAR_elasticsearch_secrets_keyvault_name | osducommon<your_unique>-kv |
......@@ -38,7 +38,7 @@ az pipelines variable-group create \
--name "Infrastructure Pipeline Variables" \
--authorize true \
--variables \
AGENT_IMAGE="ubuntu-18.04" \
AGENT_IMAGE="ubuntu-20.04" \
BUILD_ARTIFACT_NAME="infra-templates" \
TF_VAR_elasticsearch_secrets_keyvault_name=$COMMON_VAULT \
TF_VAR_elasticsearch_secrets_keyvault_resource_group=osdu-common-${UNIQUE} \
......@@ -53,6 +53,8 @@ __Setup and Configure the ADO Library `Infrastructure Pipeline Variables - demo`
This variable group will be used to hold the common values for a specific infrastructure environment to be built. There is an implied naming convention to this Variable group `demo` relates to the environment name. Additionally you can specify and override the region locations here.
__TF_VAR_istio_int_load_balancer_ip__ has been set by default in terraform code, however, if you are on brownfield deployments, to avoid downtime, you may want to setup this in the Variable Group as env var or in your `terraform.tfvars` file to match your environment setup.
| Variable | Value |
|----------|-------|
......@@ -74,6 +76,8 @@ This variable group will be used to hold the common values for a specific infras
| TF_VAR_principal_password | <your_principal_password> |
| TF_VAR_resource_group_location | centralus |
| TF_VAR_deploy_dp_airflow | false |
| TF_VAR_aks_dns_host | <your_dns_host> |
| (Optional) TF_VAR_istio_int_load_balancer_ip | 10.10.255.253 |
| (optional) TF_VAR_secret_kv_enabled | false |
| (optional) TF_VAR_reservoir_ddms | {enabled=false,sku="B_Gen5_1"} |
......@@ -85,6 +89,7 @@ REGION_PAIR="eastus2"
PARTITION_NAME="opendes"
ELASTIC_VERSION="7.11.1"
GIT_REPO=git@ssh.dev.azure.com:v3/${ADO_ORGANIZATION}/${ADO_PROJECT}/k8-gitops-manifests
DNS_HOSTNAME=myhostname.contoso.com # Replace for your hostname to be used
az pipelines variable-group create \
--name "Infrastructure Pipeline Variables - ${ENVIRONMENT}" \
......@@ -110,6 +115,7 @@ az pipelines variable-group create \
TF_VAR_deploy_dp_airflow="false" \
TF_VAR_aad_client_id="$TF_VAR_application_clientid" \
TF_VAR_secret_kv_enabled="false" \
TF_VAR_aks_dns_host=$DNS_HOSTNAME \
-ojson
```
......
......@@ -7,7 +7,7 @@ This variable group will be used to hold the common values for the services to b
| Variable | Value |
|-----------------------------------------------|-------|
| ADMIN_EMAIL | <your_sslcert_admin_email> |
| AGENT_IMAGE | `ubuntu-18.04` |
| AGENT_IMAGE | `ubuntu-20.04` |
| AZURE_AD_GUEST_EMAIL | `$(ad-guest-email)` |
| AZURE_AD_GUEST_OID | `$(ad-guest-oid)` |
| AZURE_AD_OTHER_APP_RESOURCE_ID | `$(osdu-mvp-<your_unique>-application-clientid)` |
......@@ -61,7 +61,7 @@ az pipelines variable-group create \
--authorize true \
--variables \
ADMIN_EMAIL=$ADMIN_EMAIL \
AGENT_IMAGE="ubuntu-18.04" \
AGENT_IMAGE="ubuntu-20.04" \
AZURE_AD_GUEST_EMAIL='$(ad-guest-email)' \
AZURE_AD_GUEST_OID='$(ad-guest-oid)' \
AZURE_AD_OTHER_APP_RESOURCE_ID='$(osdu-mvp-'${UNIQUE}'-application-clientid)' \
......
// Copyright © Microsoft Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
data "azurerm_client_config" "current" {}
data "azurerm_resource_group" "main" {
name = var.resource_group_name
}
locals {
public_ip_name = format("%s-ip", var.name)
gateway_ip_configuration_name = format("%s-config", var.vnet_name)
backend_address_pool_name = format("%s-beap", var.vnet_name)
frontend_port_name = format("%s-feport", var.vnet_name)
frontend_ip_configuration_name = format("%s-feip", var.vnet_name)
backend_http_settings = format("%s-be-htst", var.vnet_name)
listener_name = format("%s-httplstn", var.vnet_name)
request_routing_rule_name = format("%s-rqrt", var.vnet_name)
identity_name = format("%s-identity", var.name)
}
resource "azurerm_public_ip" "main" {
name = local.public_ip_name
resource_group_name = data.azurerm_resource_group.main.name
location = data.azurerm_resource_group.main.location
allocation_method = "Static"
sku = "Standard"
domain_name_label = var.name
tags = var.resource_tags
}
// This Identity is used for accessing Key Vault to retrieve SSL Certificate
resource "azurerm_user_assigned_identity" "main" {
name = local.identity_name
resource_group_name = data.azurerm_resource_group.main.name
location = data.azurerm_resource_group.main.location
tags = var.resource_tags
}
module "app_gw_keyvault_access_policy" {
source = "../keyvault-policy"
vault_id = var.keyvault_id
tenant_id = data.azurerm_client_config.current.tenant_id
object_ids = [
azurerm_user_assigned_identity.main.principal_id
]
key_permissions = []
secret_permissions = ["get"]
certificate_permissions = ["get"]
}
## Reference Configuration: https://docs.microsoft.com/en-us/azure/application-gateway/configuration-overview
resource "azurerm_application_gateway" "main" {
name = var.name
resource_group_name = data.azurerm_resource_group.main.name
location = data.azurerm_resource_group.main.location
tags = var.resource_tags
sku {
name = "WAF_v2"
tier = "WAF_v2"
}
waf_configuration {
enabled = var.tier == "WAF" || var.tier == "WAF_v2" ? true : false
firewall_mode = var.waf_config_firewall_mode
rule_set_type = "OWASP"
rule_set_version = "3.1"
}
identity {
type = "UserAssigned"
identity_ids = [azurerm_user_assigned_identity.main.id]
}
autoscale_configuration {
min_capacity = var.min_capacity
max_capacity = var.max_capacity
}
gateway_ip_configuration {
name = local.gateway_ip_configuration_name
subnet_id = var.vnet_subnet_id
}
frontend_ip_configuration {
name = local.frontend_ip_configuration_name
public_ip_address_id = azurerm_public_ip.main.id
}
########
### Listener 1 http://mygateway.com
########
dynamic "http_listener" {
for_each = var.http_enabled ? [1] : []
content {
name = format("http-%s", local.listener_name)
frontend_ip_configuration_name = local.frontend_ip_configuration_name
frontend_port_name = format("http-%s", local.frontend_port_name)
protocol = "Http"
}
}
dynamic "frontend_port" {
for_each = var.http_enabled ? [1] : []
content {
name = format("http-%s", local.frontend_port_name)
port = 80
}
}
dynamic "request_routing_rule" {
for_each = var.http_enabled ? [1] : []
content {
name = format("http-%s", local.request_routing_rule_name)
rule_type = "Basic"
http_listener_name = format("http-%s", local.listener_name)
backend_address_pool_name = format("http-%s", local.backend_address_pool_name)
backend_http_settings_name = format("http-%s", local.backend_http_settings)
}
}
dynamic "backend_http_settings" {
for_each = var.http_enabled ? [1] : []
content {
name = format("http-%s", local.backend_http_settings)
cookie_based_affinity = "Disabled"
port = 80
protocol = "Http"
request_timeout = var.request_timeout
}
}
dynamic "backend_address_pool" {
for_each = var.http_enabled ? [1] : []
content {
name = format("http-%s", local.backend_address_pool_name)
fqdns = length(var.backend_address_pool_fqdns) == 0 ? null : var.backend_address_pool_fqdns
ip_addresses = length(var.backend_address_pool_ips) == 0 ? null : var.backend_address_pool_ips
}
}
########
### Listener 2 https://mygateway.com
########
http_listener {
name = format("https-%s", local.listener_name)
frontend_ip_configuration_name = local.frontend_ip_configuration_name
frontend_port_name = format("https-%s", local.frontend_port_name)
protocol = "Https"
ssl_certificate_name = var.ssl_certificate_name
}
frontend_port {
name = format("https-%s", local.frontend_port_name)
port = 443
}
ssl_certificate {
name = var.ssl_certificate_name
key_vault_secret_id = var.keyvault_secret_id
}
request_routing_rule {
name = format("https-%s", local.request_routing_rule_name)
rule_type = "Basic"
http_listener_name = format("https-%s", local.listener_name)
backend_address_pool_name = format("https-%s", local.backend_address_pool_name)
backend_http_settings_name = format("https-%s", local.backend_http_settings)
}
backend_http_settings {
name = format("https-%s", local.backend_http_settings)
cookie_based_affinity = "Disabled"
port = 443
protocol = "Https"
request_timeout = var.request_timeout
host_name = length(var.host_name) == 0 ? null : var.host_name
}
backend_address_pool {
name = format("https-%s", local.backend_address_pool_name)
fqdns = length(var.backend_address_pool_fqdns) == 0 ? null : var.backend_address_pool_fqdns
ip_addresses = length(var.backend_address_pool_ips) == 0 ? null : var.backend_address_pool_ips
}
ssl_policy {
policy_type = var.ssl_policy_type
cipher_suites = var.ssl_policy_cipher_suites
min_protocol_version = var.ssl_policy_min_protocol_version
}
zones = var.gateway_zones
lifecycle {
ignore_changes = [
ssl_certificate,
url_path_map,
# Properties that must be modified when using istio:
# Possibly use only with -target flag
]
}
}
// Copyright © Microsoft Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
output "name" {
description = "The name of the Application Gateway created"
value = azurerm_application_gateway.main.name
}
output "id" {
description = "The resource id of the Application Gateway created"
value = azurerm_application_gateway.main.id
}
output "ipconfig" {
description = "The Application Gateway IP Configuration"
value = azurerm_application_gateway.main.gateway_ip_configuration
}
output "frontend_ip_configuration" {
description = "The Application Gateway Frontend IP Configuration"
value = azurerm_application_gateway.main.frontend_ip_configuration
}
output "managed_identity_resource_id" {
description = "The resource id of the managed user identity"
value = azurerm_user_assigned_identity.main.id
}
output "managed_identity_principal_id" {
description = "The resource id of the managed user identity"
value = azurerm_user_assigned_identity.main.principal_id
}
output "appgw_public_ip_address" {
description = "The public IP address of Application Gateway."
value = azurerm_public_ip.main.ip_address
}
// Copyright © Microsoft Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
provider "azurerm" {
features {}
}
locals {
ssl_cert_name = "test-ssl"
location = "eastus2"
}
module "resource_group" {
source = "../../resource-group"
name = "osdu-module"
location = local.location
}
module "keyvault" {
source = "../../keyvault"
depends_on = [module.resource_group]
keyvault_name = substr("osdu-module-kv-${module.resource_group.random}", 0, 24)
resource_group_name = module.resource_group.name
}
resource "azurerm_key_vault_certificate" "test" {
name = local.ssl_cert_name
key_vault_id = module.keyvault.keyvault_id
certificate_policy {
issuer_parameters {
name = "Self"
}
key_properties {
exportable = true
key_size = 2048
key_type = "RSA"
reuse_key = true
}
lifetime_action {
action {
action_type = "AutoRenew"
}
trigger {
days_before_expiry = 30
}
}
secret_properties {
content_type = "application/x-pkcs12"
}
x509_certificate_properties {
# Server Authentication = 1.3.6.1.5.5.7.3.1
# Client Authentication = 1.3.6.1.5.5.7.3.2
extended_key_usage = ["1.3.6.1.5.5.7.3.1"]
key_usage = [
"cRLSign",
"dataEncipherment",
"digitalSignature",
"keyAgreement",
"keyCertSign",
"keyEncipherment",
]
subject_alternative_names {
dns_names = ["internal.contoso.com", "osdu-module-gw-${module.resource_group.random}.${local.location}.cloudapp.azure.com"]
}
subject = "CN=*.contoso.com"
validity_in_months = 12
}
}
}
module "network" {
source = "../../network"
depends_on = [module.resource_group]
name = "osdu-module-vnet-${module.resource_group.random}"
resource_group_name = module.resource_group.name
address_space = "10.10.0.0/16"
dns_servers = ["8.8.8.8"]
subnet_prefixes = ["10.10.1.0/24", "10.10.2.0/24"]
subnet_names = ["frontend", "backend"]
# Tags
resource_tags = {
osdu = "module"
}
}
module "appgateway" {
source = "../"
depends_on = [module.resource_group]
name = "osdu-module-gw-${module.resource_group.random}"
resource_group_name = module.resource_group.name
vnet_name = module.network.name
vnet_subnet_id = module.network.subnets[1]
keyvault_id = module.keyvault.keyvault_id
keyvault_secret_id = azurerm_key_vault_certificate.test.secret_id
ssl_certificate_name = local.ssl_cert_name
# Tags
resource_tags = {
osdu = "module"
}
}
// Copyright © Microsoft Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package test
import (
"encoding/json"
"testing"
"github.com/gruntwork-io/terratest/modules/random"
"github.com/gruntwork-io/terratest/modules/terraform"
"github.com/microsoft/cobalt/test-harness/infratests"
)
var name = "cluster-"
var location = "eastus"
var count = 17
var tfOptions = &terraform.Options{
TerraformDir: "./",
Upgrade: true,
}
func asMap(t *testing.T, jsonString string) map[string]interface{} {
var theMap map[string]interface{}
if err := json.Unmarshal([]byte(jsonString), &theMap); err != nil {
t.Fatal(err)
}
return theMap
}
func TestTemplate(t *testing.T) {
ipExpectedResult := asMap(t, `{
"sku": "Standard",
"allocation_method": "Static"
}`)
gatewayExpectedResult := asMap(t, `{
"autoscale_configuration": [{
"min_capacity": 2
}],
"identity": [{
"type": "UserAssigned"
}],
"request_routing_rule": [{
"rule_type": "Basic"
}]
}`)
testFixture := infratests.UnitTestFixture{
GoTest: t,
TfOptions: tfOptions,
Workspace: name + random.UniqueId(),
PlanAssertions: nil,
ExpectedResourceCount: count,
ExpectedResourceAttributeValues: infratests.ResourceDescription{
"module.appgateway.azurerm_public_ip.main": ipExpectedResult,
"module.appgateway.azurerm_application_gateway.main": gatewayExpectedResult,
},
}
infratests.RunUnitTests(&testFixture)
}
// Copyright © Microsoft Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package integration
import (
"os"
"testing"
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2019-02-01/network"
"github.com/microsoft/cobalt/test-harness/infratests"
"github.com/microsoft/cobalt/test-harness/terratest-extensions/modules/azure"
"github.com/stretchr/testify/require"
)
var subscription = os.Getenv("ARM_SUBSCRIPTION_ID")
func checkMinCapactiy(t *testing.T, appGatewayProperties *network.ApplicationGatewayPropertiesFormat) {
minCapacity := appGatewayProperties.AutoscaleConfiguration.MinCapacity
// There should be a minimum of 2 instances. If client decides to change the number of min instances, the value will be greater than 2
require.LessOrEqual(t, int32(2), *minCapacity)
}
func checkOWASPRuleset(t *testing.T, appGatewayProperties *network.ApplicationGatewayPropertiesFormat) {
firewallRulesetType := appGatewayProperties.WebApplicationFirewallConfiguration.RuleSetType
firewallRulesetVersion := appGatewayProperties.WebApplicationFirewallConfiguration.RuleSetVersion
require.Equal(t, "OWASP", *firewallRulesetType, "Firewall ruleset type is incorrect")
require.Equal(t, "3.1", *firewallRulesetVersion, "Firewall ruleset version is incorrect")
}
func checkAvailablePorts(t *testing.T, appGatewayProperties *network.ApplicationGatewayPropertiesFormat) {
foundPort := false
frontendPorts := appGatewayProperties.FrontendPorts
for _, frontend := range *frontendPorts {
if *frontend.Port == int32(443) {
foundPort = true