OCI: Create nodes in Kubernetes nodepool with bastion agent configured - kubernetes

I'm trying to deploy a Kubernetes cluster in Oracle Cloud Infrastructure using Terraform.
I want that every node deployed (in private subnet) has the Bastion agent plugin activate in Cloud Agent.
But I cannot see how to define the details of the instance (setting agent_config in the node pool instances).
My code, until now is:
resource "oci_containerengine_cluster" "generated_oci_containerengine_cluster" {
compartment_id = var.cluster_compartment
endpoint_config {
is_public_ip_enabled = "true"
subnet_id = oci_core_subnet.oke_public_api.id
}
kubernetes_version = var.kubernetes_version
name = "josealbarran_labcloudnative_oke"
options {
kubernetes_network_config {
pods_cidr = "10.244.0.0/16"
services_cidr = "10.96.0.0/16"
}
service_lb_subnet_ids = [oci_core_subnet.oke_public_lb.id]
}
vcn_id = var.cluster_vcn
}
# Check doc: https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/containerengine_node_pool
resource "oci_containerengine_node_pool" "node_pool01" {
cluster_id = "${oci_containerengine_cluster.generated_oci_containerengine_cluster.id}"
compartment_id = var.cluster_compartment
initial_node_labels {
key = "name"
value = "pool01"
}
kubernetes_version = var.kubernetes_version
name = "lab_cloud_native_oke_pool01"
node_config_details {
size = "${length(data.oci_identity_availability_domains.ads.availability_domains)}"
dynamic "placement_configs" {
for_each = data.oci_identity_availability_domains.ads.availability_domains[*].name
content {
availability_domain = placement_configs.value
subnet_id = oci_core_subnet.oke_private_worker.id
}
}
}
node_shape = "VM.Standard.A1.Flex"
node_shape_config {
memory_in_gbs = "16"
ocpus = "1"
}
node_source_details {
image_id = "ocid1.image.oc1.eu-frankfurt-1.aaaaaaaalgodii3qx3mfasp6ai22bja7mabfwsxiwkzxx7lhdfdbbuyqcznq"
source_type = "IMAGE"
}
ssh_public_key = "ssh-rsa AAAAB3xxxxxxxx......."
timeouts {
create = "60m"
delete = "90m"
}
}

You can use the "cloudinit_config" to run the custom script in OKE node pool in OCI.
second_script_template = templatefile("${path.module}/cloudinit/second.template.sh",{})
More scripts like
data "cloudinit_config" "worker" {
gzip = false
base64_encode = true
part {
filename = "worker.sh"
content_type = "text/x-shellscript"
content = local.worker_script_template
}
part {
filename = "second.sh"
content_type = "text/x-shellscript"
content = local.second_script_template
}
part {
filename = "third.sh"
content_type = "text/x-shellscript"
content = local.third_script_template
}
}
Refer : https://github.com/oracle-terraform-modules/terraform-oci-oke/blob/main/docs/instructions.adoc#14-configuring-cloud-init-for-the-nodepools
If you are looking forward to just edit the default script : https://github.com/oracle-terraform-modules/terraform-oci-oke/blob/main/docs/cloudinit.adoc

Related

Terraform import error retrieving Virtual Machine Scale Set created from an image

I'm trying to import a Linux VM Scale Set that was deployed in the Azure Portal from a custom shared image, also created in the portal. I'm using the following command:
terraform import module.vm_scaleset.azurerm_linux_virtual_machine_scale_set.vmscaleset /subscriptions/00000000-0000-0000-0000-000000000000
/resourceGroups/myrg/providers/Microsoft.Compute/virtualMachineScaleSets/vmss1
Import fails with the following error:
Error: retrieving Virtual Machine Scale Set "vmss1" (Resource Group "myrg"): properties.virtualMachineProfile.osProfile was nil
Below is my VM Scale set module code
data "azurerm_lb" "loadbalancer" {
name = var.lbName
resource_group_name = var.rgName
}
data "azurerm_lb_backend_address_pool" "addresspool" {
loadbalancer_id = data.azurerm_lb.loadbalancer.id
name = var.lbAddressPool
}
data "azurerm_shared_image" "scaleset_image" {
provider = azurerm.ist
name = var.scaleset_image_name
gallery_name = var.scaleset_image_gallery
resource_group_name = var.scaleset_image_rgname
}
resource "azurerm_linux_virtual_machine_scale_set" "vmscaleset" {
name = var.vmssName
resource_group_name = var.rgName
location = var.location
sku = var.vms_sku
instances = var.vm_instances
admin_username = azurerm_key_vault_secret.vmssusername.value
admin_password = azurerm_key_vault_secret.vmsspassword.value
disable_password_authentication = false
zones = var.vmss_zones
source_image_id = data.azurerm_shared_image.scaleset_image.id
tags = module.vmss_tags.tags
os_disk {
storage_account_type = var.vmss_osdisk_storage
caching = "ReadWrite"
create_option = "FromImage"
}
data_disk {
storage_account_type = "StandardSSD_LRS"
caching = "None"
disk_size_gb = 1000
lun = 10
create_option = "FromImage"
}
network_interface {
name = format("nic-%s-001", var.vmssName)
primary = true
enable_accelerated_networking = true
ip_configuration {
name = "internal"
load_balancer_backend_address_pool_ids = [data.azurerm_lb_backend_address_pool.addresspool.id]
primary = true
subnet_id = var.subnet_id
}
}
lifecycle {
ignore_changes = [
tags
]
}
}
The source image was created from a Linux RHEL 8.6 VM that included a custom node.js script.
Examination of the Scale Set in the portal does indeed show that the virtualMachineProfile.osProfile is absent.
I haven't been able to find a solution on any forum. Is there any way to ignore the error and import the Scale Set anyway?

How to get the http_Listener.hostname in azure terraform

Here's my application gateway terraform template:
resource "azurerm_application_gateway" "appgw" {
name = "${var.client_name_prefix}${var.environment_name}${var.location_abr}gw${var.instance}"
resource_group_name = azurerm_resource_group.rg.name
location = var.location
enable_http2 = true
backend_http_settings {
name = "backOfficeAppHttpSetting"
cookie_based_affinity = "Disabled"
port = var.backed_port
protocol = "Http"
probe_name = "nginx-ingress-prob"
request_timeout = var.backend_request_timeout_back_office
pick_host_name_from_backend_address = false
host_name = "local.backoffice.${var.sslcert}"
affinity_cookie_name = "ApplicationGatewayAffinity"
}
http_listener {
name = "backOfficeAppListener"
frontend_ip_configuration_name = local.frontend_ip_configuration_name
frontend_port_name = local.frontend_port_443_name
protocol = "Https"
host_name = "${var.client_name}-${var.environment_name}-admin.${var.sslcert}"
require_sni = true
ssl_certificate_name = var.sslcert
}
http_listener {
name = "frontWebAppListener"
frontend_ip_configuration_name = local.frontend_ip_configuration_name
frontend_port_name = local.frontend_port_443_name
protocol = "Https"
host_name = "${var.client_name}-${var.environment_name}.${var.sslcert}"
require_sni = true
ssl_certificate_name = var.sslcert
}
}
And In key-vault.tf. I want to create to secret in which I want to save the value of first http_listener (HOSTNAME).
BUT, I'm unable to get it. Is there any way to get http_listener.host_name?
I want to know is there any way to get it.
I have tried it but i couldn't get it.

Is there a web redirect method or example using an application gateway using terraform?

im trying to create a service for web redirect through the application gateway using terraform.
I would like to authenticate the application gateway sl with the free certified (azurm_app_service_managed_certified) of the azure app service plan, is there an example?
Currently, thinking about the composition as follows. However, azurem_application_gateway is demanding ssl certification, so I don't know how to work.
Please let me know if there's a way to solve the problem in that way or in another way.
The problem with the script below is that if you want to use https in the application gateway, you have to use certificate, and I want to make and use free certificated in the service plan.
resource "azurerm_application_gateway" "app_gateway" {
provider = azurerm.generic
name = "${local.service_name}-app-gateway"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
enable_http2 = true
sku {
name = "Standard_Small"
tier = "Standard" # v1
capacity = 2
}
gateway_ip_configuration {
name = "${local.service_name}-ip-config"
subnet_id = azurerm_subnet.front_subnet.id
}
frontend_port {
name = local.frontend_port_name
port = 80
}
frontend_port {
name = local.backend_port_name
port = 443
}
frontend_ip_configuration {
name = local.frontend_ip_configuration_name
public_ip_address_id = azurerm_public_ip.pub_ip.id
}
backend_address_pool {
name = "${azurerm_virtual_network.vn.name}-beap"
fqdns = [local.host_name]
}
backend_http_settings {
name = local.http_setting_name
cookie_based_affinity = "Disabled"
port = 443
protocol = "Https"
request_timeout = 60
host_name = local.host_name
}
http_listener {
name = "${local.listener_name}-http"
frontend_ip_configuration_name = local.frontend_ip_configuration_name
frontend_port_name = local.frontend_port_name
protocol = "Http"
}
http_listener {
name = "${local.listener_name}-https"
frontend_ip_configuration_name = local.frontend_ip_configuration_name
frontend_port_name = local.backend_port_name
protocol = "Https"
}
request_routing_rule {
name = "${local.request_routing_rule_name}-http"
rule_type = "Basic"
http_listener_name = "${local.listener_name}-http"
backend_address_pool_name = local.backend_address_pool_name
backend_http_settings_name = local.http_setting_name
}
redirect_configuration {
name = local.redirect_configuration_name
redirect_type = "Permanent"
include_path = false
include_query_string = false
target_listener_name = "${local.listener_name}-https"
}
request_routing_rule {
name = "${local.request_routing_rule_name}-https"
rule_type = "Basic"
http_listener_name = "${local.listener_name}-https"
redirect_configuration_name = local.redirect_configuration_name
}
lifecycle {
ignore_changes = [
backend_address_pool,
backend_http_settings,
frontend_port,
http_listener,
request_routing_rule,
ssl_certificate,
redirect_configuration
]
}
}
resource "azurerm_dns_zone" "zone" {
provider = azurerm.generic
for_each = toset(local.dns_zone_names)
name = each.key
resource_group_name = azurerm_resource_group.rg.name
}
resource "azurerm_app_service_plan" "service_plan" {
provider = azurerm.generic
name = "${local.service_name}-service-plan"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
sku {
tier = "Basic"
size = "B1"
}
}
resource "azurerm_app_service" "service" {
provider = azurerm.generic
name = "${local.service_name}-service"
app_service_plan_id = azurerm_app_service_plan.service_plan.id
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
}
resource "azurerm_app_service_custom_hostname_binding" "service_host_bind" {
provider = azurerm.generic
count = length(local.dns_zone_names)
hostname = "${local.dns_zone_names[count.index]}"
app_service_name = azurerm_app_service.service.name
resource_group_name = azurerm_resource_group.rg.name
lifecycle {
ignore_changes = [ssl_state, thumbprint]
}
depends_on = [
azurerm_app_service.service,
azurerm_resource_group.rg
]
}
resource "azurerm_app_service_managed_certificate" "service_manage_cert" {
provider = azurerm.generic
count = length(local.dns_zone_names)
custom_hostname_binding_id = azurerm_app_service_custom_hostname_binding.service_host_bind[count.index].id
}
resource "azurerm_app_service_certificate_binding" "service_certi_bind" {
provider = azurerm.generic
count = length(local.dns_zone_names)
hostname_binding_id = azurerm_app_service_custom_hostname_binding.service_host_bind[count.index].id
certificate_id = azurerm_app_service_managed_certificate.service_manage_cert[count.index].id
ssl_state = "SniEnabled"
}
i want a service that simply directs to another website through dns using terraform, and if there is any other way, please let us know. (include http to https)
To protect and prevent website abuse, we would like to redirect multiple domains to one website.
ex : (adomain.net -> www.target.com, adomain.tv -> www.target.com, bdomain.net -> www.target.com)
Fist of all there is no support for app services managed certificate with application gateway as of now.
Yes, you can do redirection from multiple domains to one domain using system.webserver rewrite rule either inside app services web.config file or application gateway rewrite rule.

Terraform Cosmosdb multiple subnet

Terraform Cosmosdb multiple subnet
Getting error when add additional subnet for cosmosdb
Terraform Error:
Error: Invalid value for module argument
on manifests/backend.tf line 289, in module "cosmosdb_1":
289: vnet_subnet_id = ["azurerm_subnet.backend.id", "azurerm_subnet.application.id", "azurerm_subnet.frontend.id"]
The given value is not suitable for child module variable "vnet_subnet_id"
defined at modules/cosmosdb/variable.tf:26,1-26: element 0: object required.
Configuration for main.tf defined variable for subnets
dynamic "virtual_network_rule" {
for_each = var.virtual_network_rule != null ? toset(var.virtual_network_rule) : []
content {
id = [var.vnet_subnet_id]
ignore_missing_vnet_service_endpoint = virtual_network_rule.value.ignore_missing_vnet_service_endpoint
}
}
variable.tf file define variable type
variable "vnet_subnet_id" {
type = list(object({
id = string,
ignore_missing_vnet_service_endpoint = bool
}))
}
main configuration for vnet subnet defined in backend.tf
module "cosmosdb_1" {
depends_on = [module.vnet]
source = "./../modules/cosmosdb"
cosmodb_account_name = "${var.env}${var.cosmodb_account_name_1}"
resource_group_name = "${var.env}-bsai"
ip_range_filter = var.ip_range_filter
location = "${var.region}"
cosmosdb_name = var.cosmosdb_name_1
enable_automatic_failover = var.enable_automatic_failover
failover_location_secondary = var.failover_location_secondary
failover_priority_secondary = var.failover_priority_secondary
vnet_subnet_id = ["azurerm_subnet.backend.id", "azurerm_subnet.application.id", "azurerm_subnet.frontend.id"]
}
Solution:
Module: main.tf
dynamic "virtual_network_rule" {
for_each = var.vnet_subnet_id
content {
id = virtual_network_rule.value.id
ignore_missing_vnet_service_endpoint = true
}
}
variable.tf
variable "vnet_subnet_id" {
description = "List of subnets to be used in Cosmosdb."
type = list(object({
id = string
}))
}
Backend.tf
vnet_subnet_id = [{id = azurerm_subnet.backend.id}, {id = azurerm_subnet.application.id}, {id = azurerm_subnet.frontend.id}]

Tags format on Packer ec2-ami deployment

I'm trying out to create an amazon ec2 ami for the 1st time using Hashicorp Packer, however getting this failure on the tag creation, I already tried some retries on trial and error test for the format but still unlucky
[ec2-boy-oh-boy#ip-172-168-99-23 pogi]$ packer init .
Error: Missing item separator
on variables.pkr.hcl line 28, in variable "tags":
27: default = [
28: "environment" : "testing"
Expected a comma to mark the beginning of the next item.
My code ec2.pkr.hcl looks like this:
[ec2-boy-oh-boy#ip-172-168-99-23 pogi]$ cat ec2.pkr.hcl
packer {
required_plugins {
amazon = {
version = ">= 0.0.2"
source = "github.com/hashicorp/amazon"
}
}
}
source "amazon-ebs" "ec2" {
ami_name = "${var.ami_prefix}-${local.timestamp}"
instance_type = "t2.micro"
region = "us-east-1"
vpc_id = "${var.vpc}"
subnet_id = "${var.subnet}"
security_group_ids = ["${var.sg}"]
ssh_username = "ec2-boy-oh-boy"
source_ami_filter {
filters = {
name = "amzn2-ami-hvm-2.0*"
root-device-type = "ebs"
virtualization-type = "hvm"
}
most_recent = true
owners = ["12345567896"]
}
launch_block_device_mappings = [
{
"device_name": "/dev/xvda",
"delete_on_termination": true
"volume_size": 10
"volume_type": "gp2"
}
]
run_tags = "${var.tags}"
run_volume_tags = "${var.tags}"
}
build {
sources = [
"source.amazon-ebs.ec2"
]
}
[ec2-boy-oh-boy#ip-172-168-99-23 pogi]$
Then my code variables.pkr.hcl looks like this:
[ec2-boy-oh-boy#ip-172-168-99-23 pogi]$ cat variables.pkr.hcl
locals {
timestamp = regex_replace(timestamp(), "[- TZ:]", "")
}
variable "ami_prefix" {
type = string
default = "ec2-boy-oh-boy"
}
variable "vpc" {
type = string
default = "vpc-asd957d"
}
variable "subnet" {
type = string
default = "subnet-asd957d"
}
variable "sg" {
type = string
default = "sg-asd957d"
}
variable "tags" {
type = map
default = [
environment = "testing"
type = "none"
production = "later"
]
}
Your default value for the tags variable is of type list(string). Both the run_tags and run_volume_tags directives expect type map[string]string.
I was able to make the following changes to your variables file and run packer init successfully:
variable "tags" {
default = {
environment = "testing"
type = "none"
production = "later"
}
type = map(string)
}