Microsoft Certified Trainer, a su servicio

Hace unos casi 20 años atrás tuve la oportunidad de conocer una comunidad maravillosa en Bogotá, que se llamaba ItPros-DC, en ese tiempo yo era aún un «sardino» en la universidad,  dicha comunidad maravillosa como comunidad al fin y al cabo, tenía mucho voluntariado, así que con algunos amigos, como Rubén Pinzón, Daniel Vargas, Mi queridísima Yohanna “Yohis” Ramírez, y hasta el coloso Edwin Garzón, empezamos en esa época a enseñar a otros, a dictar clases de sistemas operativos Windows Cliente, Windows server, a networking o incluso hasta Microsoft SQL o Exchange, y enseñando uno aprende, la forma de hacer las cosas, puede que otro las haga de diferentes maneras, y Microsoft sorprendentemente siempre tiene más de una forma de llegar al mismo punto, y enseñar me ha mostrado, que desde la humildad y la sencillez se puede liderar, inspirar, y orientar, que se puede relacionar y estrechar el vínculo con el estudiante,  y lograr una relación más clara de confianza y cercana cuando uno permite al estudiante ser su colega y su amigo.

Ayer estuve en una sesión donde estudiantes del SENA, querían presentar su examen de Azure fundamentos. Mi rol como preparador técnico, o entrenador, fue marcarles la ruta de estudio, indicarles esos tips y la manera de escalar en pequeños pasos su aprendizaje, cual era la mejor manera de fortalecer sus conocimientos y asistir a la cita con una actitud ganadora, confiados en lo que han aprendido y seguros de que un examen simplemente es una manera de evaluar los conocimientos adquiridos y las fortalezas o debilidades a mejorar.

Mi charla básicamente se centró en dirigirlos a Learn.microsoft.com y recomendarles la experiencia basada en puntos y logros, cada pequeña batalla cuenta y varias victorias suman al resultado final. comiencen abriendo una cuenta de Azure para estudiante, con las cuentas de SENA, o de cualquier institución académica deberían poder tener acceso a este beneficio de $100 dólares en créditos de Azure por 12 meses.

Mi recomendacion para ellos, y para todo aquel que lee este post es, que empiecen aprendiendo de a poco, proponganse metas ambiciosas, y hagan un plan de pequenas tareas que los vaya llevando a su objetivo. Recuerden que hay que soñar ser papa, para llegar a sacristan. Soñar no cuesta nada, pero si te quedas en la cama durmiendo, y solo soñando, nunca vas a conseguir nada, asi que lo mejor que puedes hacer, es transformar ese sueño en un proposito, un objetivo, definir tareas y hacer unos compromisos contigo mismo, poniendo fechas y estimando esfuerzo por cada tarea, iras notando el avance y registrando el progreso hacia tu meta.

En mi caso yo empece aprendiendo de sistemas operativos windows, comence con clientes, luego pase a servidores, con cada nuevo episodio venian cientos de capitulos de literatura incluida, es divertido descubrir nuevas caracteristicas y capacidades que los productos como Windows Server tienen para ofrecer, aqui en este punto aprendi algo sobre PowerShell, de ahi pase a aprender de networking, de almacenamiento, de correo, bases de datos y hasta de servidores web, para finalmente aprender sobre Sharepoint. Habiendo hecho todo este track de certificaciones y aprendizaje llegue al punto de querer aprender sobre servicios en nube, tipo SAAS como Office 365. aprendi lo suficiente del producto al punto que fui parte del equipo de soporte GIG_LATAM para Office365.

Nadie nace aprendido, todo se aprende al caminar por la senda del conocimiento, y por eso luego empece a merodear las mieles de Azure y la infraestructura como servicio o IAAS, y aqui es donde queria llegar, porque hoy en dia los examenes de Azure consisten en una gran cantidad de topicos, donde sin ser especialista ni tener un profundo conocimiento en cada tema, si se precisa al menos poder identificar que hacer con cada solucion y producto que nos presenta la nube.

Azure Precisa conocimiento en Hyper-V, para entender que una maquina esta compuesta de recursos de computo, (cpu/memoria Ram), un disco duro en formato VHD, una tarjeta de red (NIC) y en el caso de Azure se precisa de direcciones IP, Network security groups, y otras cosas como etiquetas, permisos RBAC, y configuraciones para alertas, monitoreo, autoescalamiento, y mas.. lo mas importante es que existen unos terminos, caracteristicas y limitantes de los servicios ofrecidos por Azure, donde se enfatiza en la cantidad de nucleos que se pueden asignar por suscripcion, y muchas otras cosas. Ahora bien, hay muchas empresas que nacieron en la nube, que si necesitaron un E-Commerce, lo implementaron directamente en Azure, y esto les permitio la escalabilidad y asegurar las ventas, sin incurrir en los onerosos gastos de OpEx y CapEx que ocasionaba comprar infraestructura local.

Si usted querido lector, quiere profundizar en estos temas, lo invito a una breve mirada de Azure Fundamentals y enterese de que es lo que es esa nube de la que todos hablan, y lo invito a que comparta, y compare, con otros fabricantes, como AWS, o GCP, que tambien tienen sus propias nubes.

DevOps

Muchos de los que trabajamos en el segmento de la tecnología sabemos que nuestro oficio no es como el de los artistas, pintores de obras maestras, que conciben la idea de su próximo cuadro y lo desarrollan con diferentes técnicas, colores, pinceles, y con amor, dedicacion y tiempo, más bien tenemos en tecnología una cierta similitud con los músicos de cámara, donde podemos tener especialidad o preferencia por un tipo de instrumento, viento, cuerdas o percusion, y hay quienes se dedican a componer musicalmente las partituras, quienes tienen la capacidad de interpretar, y quienes magistralmente pueden orquestar o dirigir una gran banda de músicos para que suene de cierta manera, mágica y sorprendente.

En tecnología, y sobre todo gracias a las tecnologías más recientes y a las capacidades del Cloud computing como Azure, GCP, o AWS, tenemos múltiples integraciones e interacciones entre distintas soluciones, las plataformas de bases de datos que Microsoft proporciona con SQL, ahora pueden ser muy diversas soluciones, desde un Oracle, a un MariaDB, un Postgresql con replicación citus para alta disponibilidad o hasta un Cosmos DB.

Cuando consideramos que un músico puede ser compositor e intérprete, al mismo tiempo, admitimos que también se puede ser desarrollador de aplicaciones y administrador de plataformas, lo cual converge en el convenientemente acuñado concepto de DevOps (Developer + Operations).

Si fuéramos un músico, con habilidades para tocar canciones en guitarra acústica, que sacamos al oído, pero no conocemos de partituras, ni conocemos de fundamentación musical o literatura pentagramada, pues no pasa nada, somos intérpretes del instrumento, y eso no se aprende en una noche. Al igual que se desarrollan las habilidades para poder tocar, y se garantiza que un Mi menor no es muy parecido a un Sol Mayor, en la escritura o transcripción musical se registran tiempos, silencios, notas que son más obtusas o más breves. Trabajar en nuestro desarrollo del conocimiento debe ser un apetito diario.

Mi gusto por la programación no nació de mis maestros universitarios, en realidad mi curiosidad en el mundo del Arduino, me ha llevado poco a poco a buscar mas sobre programacion en C++, la Raspberry Pi me ha ido inclinando hacia el oscuro lado de la fuerza y he descubierto Linux, y su vasto universo, y la sumatoria de estos nuevos placeres me han ido encauzando por la programación en Python. Ahora disfruto aprendiendo sobre GIT y GITHUB, sobre JavaScript, CSS y HTML, incluso hasta de WordPress he resultado tomando lecciones.

Ahora, no voy a decir que soy el más experto leyendo código, o interpretando métodos, funciones, variables, y estructuras de control, pero cada dia avanzo de a poco, en fortalecer y formar un mejor constructo mental que me permita llegar a la senda del Red Team, pues siempre he jugado en el lado azul, defendiendo infraestructuras, remediando vulnerabilidades, protegiendo servidores y los recursos Microsoft, los datos, la información, pero ahora que conozco un poco más sobre los mecanismos, técnicas, estrategias y herramientas que se usan para el ataque, puede ser más arriesgado pero más retador, lograr identificar fallos de seguridad que sanearlos.

«La paciencia es amarga, pero su fruto es dulce», me decía sabiamente mi estimado Harold Ordoñez, gerente y CEO de Glup Management group, un partner de Microsoft donde comencé a ver, y a conocer las herramientas de PowerApps, donde con facilidad se pueden crear soluciones y desarrollos a la medida, sin conocer mayormente de desarrollo o lenguajes de programación. Desde estas herramientas pase a conocer en Halliburton sobre Azure Functions y las soluciones ServerLess, que son los pilares de PowerApps. Ahora que he visto el potencial de Contenedores Docker y la capacidad de orquestación de Kubernetes, y de herramientas de gestión como Ansible o Terraform

Maraton de series

Empece hace unos años con mi esposa a maratonear series, el tipico enganchado de las 11:30 p.m. entre semana, y la pregunta, ¿Que… Nos vemos el otro?

La verdad yo siempre he sido un gran consumidor de ese cine hollywodense, de accion, de drama, de fantasia, y en general de poco sentido cultural o social.- las peliculas de suspenso y terror no han sido nunca de mis favoritas, y aun asi he visto muchas, de hecho los que me conocen de hace muchos años, saben que en algun momento de mi vida, no salia de las videotiendas, alquilando peliculas en sitios como blockbuster, betatonio, o los locales de barrio. De hecho, recuerdo gratamente que con mi primo Lucho, teníamos este mismo ritual, sofá comodo, tazón de palomitas, o pote de helado, y plan peliculas todo un domingo… creo que de hecho a el le aprendí el habito de mirar los creditos, y aprenderme los nombres de actores, directores y productores. hoy en día por cierto hago uso de http://www.IMDB.com para consultar las peliculas que se han hecho, y aquellas que vienen en desarrollo, en etapa de pre-producción o incluso en fase de proyecto.

Ahora que todas las plataformas de streaming nos la ponen tan facil, Netflix, Star+, HBO max, Amazon prime, en lugar de ir al cine, disfruto ver las peliculas en la comodidad de mi casa, y que mi esposa me prepare mis palomitas de maiz con mantequilla, o con ricostilla, (las de dulce aun no aprendemos a hacerlas bien…), o con alitas de pollo y en compañia de mi hija y mi esposa, cada una a cada lado, nos adentramos en la pantalla, estando en un arrunchis comodisimo.

He visto series supremamente largas, como las de Marvel, Agentes de S.h.i.e.l.d, Luke Cage, Dare devil, Iron fist, que pueden llegar a tener 7 temporadas y hasta 23 episodios de una hora, he visto series de suspenso, crueles, e inesperadas como The Game of Thrones, La Casa de Papel, o the walking dead, donde la naturaleza humana, los valores o las decisiones reflejan unos resultados inesperados y unos giros tremendos en las historias.

He visto series que me han dejado mal de la cabeza como Mr. Robot, o Black Mirror, que dentro de todo lo que proponen, tienen un tinte de certeza, un poco de verdad bajo la trama propuesta, y eso asusta. he visto series de anime, como los caballeros del zodiaco, One Punch Man, o Konosuba, y series que se han entretejido con otras series, como las de Warner, como Flash con Arrow, y a su vez con Super Girl.

Superheroes, ficcion, y aventura son mis favoritas

En todo caso son muchisimos contenidos, almacenados en mi cabeza, seguramente si a eso le sumamos los cuentos, comics, libros, revistas, blogs, video tutoriales, los innumerables contenidos tecnicos, los videos musicales, las peliculas de cine, las telenovelas y reality shows, los noticieros, las mil repeticiones del chavo del 8 y de los cuentos de los hermanos grimm, ya tendria suficientes horas al aire para decir que ya no me caben mas contenidos. Afortunadamente la memoria humana tiene ese proceso en segundo plano que va decantando los recuerdos que se quedan y los que se olvidan, esa limpieza realmente necesaria.

Recientemente con los contenidos de tiras comicas, memes, y toda la literatura de Dungeons and Dragons he dejado de entrenar y dictar cursos para hacer actividades mas ludicas, sin embargo debo reconocer que el contacto y la interaccion social que me proporciona la docencia, ese intercambio de opiniones, los diferentes paradigmas que ofrece cada estudiante desde su propia perspectiva y experiencia, es algo que definitivamente extraño mucho de tiempos pre-pandemia.

Los invito a continuar leyendo, a continuar viendo maratones de series, y consumiendo cine.- son diferentes formas de arte, fotografia, color, sonorizacion o construcciones imaginarias, que definitivamente debemos conservar. Y a todos los productores, directores de contenidos digitales, influencers, y artistas, la invitacion es a continuar generando, creando, e inspirando a otros con sus ideas, y sus puntos de vista.

Seguridad de película? Política o imaginación?

Ayer conversando con unos amigos sobre la situación de seguridad que la alcaldía busca solucionar restringiendo los parrilleros en moto, empezamos a hablar sobre las tendencias e ideas futuristas que pintaron en las películas de antaño, las matrículas de los carros en volver en futuros partidos eran escaneadas como código de barras y teniendo La completa información en tiempo real de su propietario y dónde vivía. Por ejemplo,  y para seguir con películas de los noventas, en el quinto elemento de Bruce Willis, los autos antes de salir a rodar a la calle, tenian que solicitar autorización,  se validaba el estado del vehículo y la vigencia de la licencia del conductor, recuerdo que a Michael Corben le quedaban dos recorridos antes de la revisión del taxi. O en el demoledor de Wesley Snipes y Sly Stallone, vaticinaron con cierta precisión,  los autos eléctricos,  las armas aturdidoras eléctricas, las cámaras en cada esquina y las video llamadas con casi 30 años de anticipación,  y la pandemia de los moviles o tabletas, así como el distanciamiento social. Que habrá sentido Sandra Bullock cuando se hizo realidad esa situación de no contacto, no besos, porque todos esos germenes y virus… en fin… todo esto para volver a la identificación vehicular, los vehículos encendían con comando de voz, y tenían seguimiento satélital.  

Si la alcaldesa quiere hacer un cambio en la movilidad del 20% del país,  el ministerio de transporte,  entidad que regula a la secretaria de movilidad de Bogota,  debería hacer un cambio en la plataforma tecnológica,  que permita con algoritmos de machine learning e inteligencia artificial,  registrar los movimientos de cada vehículo,  cada vez que sea captado por cualquier cámara en la ciudad o su periferia. Para esto podríamos usar placas con QR, o con códigos de barras que rápidamente permitan identificar el automotor, su propietario y su identidad. Todo podría estar en el sistema del gobierno Colombiano,  si está al día en sus pagos de impuestos,  su seguridad social, si tiene asuntos pendientes con la ley… sus cuentas de redes sociales, su perfil sociológico, si es un potencial riesgo para la seguridad nacional.

Visual Studio Code y Azure

En este repositorio exploraremos Visual studio Code, desde una perspectiva dinamica y divertida, es como todas las historias de aventuras de D&D, o del señor de los anillos, estamos todos reunidos en la mayor comodidad, tranquilos disfrutando de la tarde, y el destino nos va a llegar nuevo un «Quest», una busqueda o reto, en este caso vamos a acompañar a este valiente explorador, de abultado vientre, y corta vista, en un terreno poco explorado, como lo es el uso de las diferentes plataformas de administracion de la nube como las lineas de comando y particularmente el vscode para gestionar plantillas ARM.

Instalacion de prerequisitos

Si usted no tiene una suscripcion de Azure haga clic aqui, necesitara un equipo con Windows 10 preferiblemente, y lo invito a que preparemos los pre-requisitos:

  • Primero que todo una enorme taza del café de su preferencia
  • El modulo de Azure para powershell, aunque se puede administrar Azure desde el portal web cual seria la gracia, este modulo AZ se puede instalar iniciando el PowerShell en modo administrador (es decir dando clic derecho sobre el icono de PowerShell), y usando los siguientes comandos:
$PSVersionTable.PSVersion #para verificar que version de Powershell se tiene con version 5.0 o superior podemos hacer uso de

Install-Module -Name Az #Esto tomara un rato, porque son varios modulos, tambien es posible que te solicite confirmacion de que confias en el repositorio de PSGallery antes de continuar.

Para mas informacion consulte aqui

  • El Azure CLI tambien vale la pena tenerlo, vamos a instalarlo desde aqui esta es otra manera de interactuar con Azure desde PowerShell como administrador ejecutaremos
Invoke-WebRequest -Uri https://aka.ms/installazurecliwindows -OutFile .\AzureCLI.msi; Start-Process msiexec.exe -Wait -ArgumentList '/I AzureCLI.msi /quiet'; rm .\AzureCLI.msi
  • Es posible ingresar a la tienda de Microsoft Store, y descargar el Windows Terminal
  • Tambien puedes querer descargar el WSL (Windows Subsystem for Linux) que permite la ejecucion de un linux Ubuntu dentro de tu sistema operativo, para tener acceso por BASH y poder ejecutar herramientas propias de linux, para instalar el WSL
  • Descargue el Visual Studio Code desde aqui el instalador es muy liviano, pesa menos de 100MB. la instalacion es super simple, y vamos a ir complementandola con las extensiones para Azure a lo largo de este workshop
$VSCode = "https://code.visualstudio.com/docs/?dv=win"
New-FileDownload -SourceFile $VSCode

Guia de laboratorio

Visual Studio Code

Empecemos reconociendo el terreno,

«VS Code viene con un diseño simple e intuitivo que maximiza el espacio provisto para el editor mientras deja un amplio espacio para navegar y acceder al contexto completo de su carpeta o proyecto. La IU se divide en cinco áreas:

  • Editor: el área principal para editar sus archivos. Puede abrir tantos editores como desee, uno al lado del otro, vertical y horizontalmente.
  • Barra lateral: contiene diferentes vistas como el Explorador para ayudarlo mientras trabaja en su proyecto.
  • Barra de estado: información sobre el proyecto abierto y los archivos que edita.
  • Barra de actividad: ubicada en el extremo izquierdo, le permite cambiar de vista y le brinda indicadores adicionales específicos del contexto, como la cantidad de cambios salientes cuando Git está habilitado.
  • Paneles: puede mostrar diferentes paneles debajo de la región del editor para obtener información de salida o depuración, errores y advertencias, o un terminal integrado. El panel también se puede mover hacia la derecha para obtener más espacio vertical.» tomado de:(https://code.visualstudio.com/docs/getstarted/userinterface#_basic-layout)

ahora el Tiki-tiki

Para empezar a probar que todo nos este funcionando, usaremos la barra lateral, para crear un nuevo archivo. Quiero que lo llamemos test.ps1, esta extension hara que el Visual Studio Code identifique que estas intentando crear un Script de PowerShell, por lo que en el modulo de Extensiones te solicitara la instalacion de la extension de PowerShell, en mi escenario utilice la de «PowerShell preview»-

vamos a abrir la consola de PowerShell dentro del vscode, en la seccion inferior aparecen cuatro pestañas, «Problemas», «Salidas», «Consola de Depuracion», y «Terminal» esta ultima es la que me interesa, y vamos a validar que en la parte de la derecha aparece indicando que esta en modo PowerShell, porque tambien puede que esta consola nos funcione para bash.-

Connect-AzAccount #Aqui te pedira iniciar sesion sobre el portal de https://microsoft.com/devicelogin 
get-azresource |ft

PowerShell en 5 minutos

Write-Host #"Powershell tiene una estructura sencilla, es una composicion de un verbo en infinitivo, un guion al medio y un sustantivo singular" -ForegroundColor Yellow
Write-Host #"Por ejemplo podemos encontrar un Get-Command, un Get-Help, o un Get-Service en mas de 800 cmd-lets" -ForegroundColor Yellow
Get-Command
Write-host #"Si queremos saber que esta haciendo nuestro equipo, hacemos un get-process" -ForegroundColor Yellow
Get-process
Write-Host #"Si la informacion es muy extensa, como en este caso, podemos ordenarla" -ForegroundColor Yellow
Update-Help
get-help Get-Process
get-help Get-Process -full
get-help Get-Process -detailed
get-help Get-Process -examples
get-help Get-Process -Online
Get-Service
Get-Service -Name Spooler |Stop-Service
Get-Service M* |Format-List

Command-lets y Parametros

Get-Service M* |Format-Custom
Get-Service M* |Where-Object {$_.Status -eq "Running"}
Get-Service M* |Where-Object {$_.Status -eq "Stopped"}
Get-Service | Sort-Object Status
Get-Service | Sort-Object Status |Format-Table -GroupBy Status Name, DisplayName
Get-Service |Get-Member
Get-Process |Get-Member
Get-Service Spooler |Select-Object ServicesDependedOn
Show-Command Get-Service
Stop-Service M* -WhatIf
Stop-Service M* -Confirm

Pasando resultados con el Pipe o Piping

Get-Process |sort CPU -Descending
Get-EventLog -LogName System -EntryType Error -Newest 10
Get-EventLog -LogName System -EntryType Error -Newest 10 |fl
Get-EventLog -LogName System -EntryType Error -Newest 10 |ogv

Variables y Scripts

$var = "Hola DevOps2020"
$var
Write-host "$var" -ForegroundColor Yellow
Get-Variable 
#podemos manejar strings
$num = 123
$num
#Podemos contener listas o arrays tambien
$num = 1,2,3
$num
$var.GetType().FullName
$var.Length
$var[1]
[int[]] $var = (1,2,3)
$var[2] = "1234"
$var[2]
$v1 = "Hello "
$v2 = "world"
$v1+$v2
($var1+$var2).Length
#Comparar con -eq -ne -gt -lt -ge -le
"Juan Perez" -eq "Ramon Valdez"
#formatos
"{0:f2}" -f 12.4
"|{0,10:C}|" -f 12.4
"{0:hh:mm}" -f (get-date)
#Scripting
Get-ExecutionPolicy
Set-ExecutionPolicy Unrestricted
Get-ExecutionPolicy
runas /user:username PowerShell
##Mas info sobre seguridad en PoSh http://technet.microsoft.com/en-us/magazine/2007.09.powershell.aspx
#------------------------
#test.ps1
#Show Hello and time
"" #Blank line
"Hello"+$Env:USERNAME +"!"
"Time is" + "{0:HH}:{0:mm}" -f (get-Date)
"" #blank line
#------------------------
#Funciones
function get-soup (
    [switch] $please,
    [String] $soup = "chicken noodle"
    )
{
    if ($please){
        "Here's your $soup soup"
    }
    else {
        "No soup for you!"
    }
}
#------------------------

Entornos y modulos

#---------
$User = "fabian.campo@MiDominio.com"
$Pass = ConvertTo-SecureString "AzurePa55w.rd" -AsPlainText -Force
$Cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, $Pass
Import-Module MSOnline
Connect-msolservice -Credential $Cred
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell/ -Credential $Cred -Authentication Basic -AllowRedirection
Import-PSSession $Session
Import-Module LyncOnlineConnector
import-module microsoft.online.sharepoint.powershell
$Session = New-CsOnlinesession -Credential $Cred
Import-PSSession $Session
[string]$tenant = get-msoldomain | where {$_.name -like "*.onmicrosoft.com" -and -not($_.name -like "*mail.onmicrosoft.com")} | select name
$tenant
$tenant3 = $tenant -split("=")
[string]$tenant4 = $tenant3[1]
$tenant4
$tenant5 = $tenant4 -split(".on")
[string]$tenant6 = $tenant5[0]
$url = "https://" + $tenant6 + "-admin.sharepoint.com"
Connect-SPOService -Url $url -credential $Cred  
#---------

Registro, Certificados y otros almacenes

Get-psprovider
Get-psDrive
New-PsDrive -Name HKCS -PSProvider Registry -Root "HKEY_CLASSES_ROOT"
cd HKCS:
dir .ht*
$process = Get-WmiObject -Class win32_Process
$item.name
foreach ($item in $process)
{
    $item.name
}

Creando Maquinas virtuales en Azure

Connect-AzAccount
Get-AZSubscription | Sort SubscriptionName | Select SubscriptionName
$subscrName="Plataformas de MSDN"
Select-AzSubscription -SubscriptionName $subscrName
$rgName="Devops2020_rg"
$locName="eastus"
New-AZResourceGroup -Name $rgName -Location $locName
Get-AZStorageAccountNameAvailability "campoh1473"
$rgName="Devops2020_rg"
$saName="campoh1473"
$locName=(Get-AZResourceGroup -Name $rgName).Location
New-AZStorageAccount -Name $saName -ResourceGroupName $rgName -Type Standard_LRS -Location $locName
$rgName="Devops2020_rg"
$locName=(Get-AZResourceGroup -Name $rgName).Location
$vnetName="Vnet01"
$SubnetName="Subnet01"
$Subnet=New-AZVirtualNetworkSubnetConfig -Name $SubnetName -AddressPrefix 10.0.0.0/27
New-AZVirtualNetwork -Name $vnetName -ResourceGroupName $rgName -Location $locName -AddressPrefix 10.0.0.0/24 -Subnet $Subnet -DNSServer 10.0.0.4
$rule1 = New-AZNetworkSecurityRuleConfig -Name "RDPTraffic" -Description "Allow RDP to all VMs on the subnet" -Access Allow -Protocol Tcp -Direction Inbound -Priority 100 -SourceAddressPrefix Internet -SourcePortRange * -DestinationAddressPrefix * -DestinationPortRange 3389
$rule2 = New-AZNetworkSecurityRuleConfig -Name "ExchangeSecureWebTraffic" -Description "Allow HTTPS to the Exchange server" -Access Allow -Protocol Tcp -Direction Inbound -Priority 101 -SourceAddressPrefix Internet -SourcePortRange * -DestinationAddressPrefix "10.0.0.5/32" -DestinationPortRange 443
$rule3 = New-AZNetworkSecurityRuleConfig -Name "SharePointSecureWebTraffic" -Description "Allow HTTPS to the SharePoint server" -Access Allow -Protocol Tcp -Direction Inbound -Priority 102 -SourceAddressPrefix Internet -SourcePortRange * -DestinationAddressPrefix "10.0.0.7/32" -DestinationPortRange 80
New-AZNetworkSecurityGroup -Name $SubnetName -ResourceGroupName $rgName -Location $locName -SecurityRules $rule1, $rule2, $rule3
$vnet=Get-AZVirtualNetwork -ResourceGroupName $rgName -Name $vnetName
$nsg=Get-AZNetworkSecurityGroup -Name $SubnetName -ResourceGroupName $rgName
Set-AZVirtualNetworkSubnetConfig -VirtualNetwork $vnet -Name $SubnetName -AddressPrefix "10.0.0.0/27" -NetworkSecurityGroup $nsg
$vnet | Set-AzVirtualNetwork
$rgName="Devops2020_rg"
# Create an availability set for domain controller virtual machines
New-AZAvailabilitySet -ResourceGroupName $rgName -Name dcAvailabilitySet -Location $locName -Sku Aligned  -PlatformUpdateDomainCount 5 -PlatformFaultDomainCount 2
# Create the domain controller virtual machine
$vmName="adVM"
$vmSize="Standard_D1_v2"
$vnet=Get-AZVirtualNetwork -Name $vnetName -ResourceGroupName $rgName
$pip = New-AZPublicIpAddress -Name ($vmName + "-PIP") -ResourceGroupName $rgName -Location $locName -AllocationMethod Dynamic
$nic = New-AZNetworkInterface -Name ($vmName + "-NIC") -ResourceGroupName $rgName -Location $locName -SubnetId $vnet.Subnets[0].Id -PublicIpAddressId $pip.Id -PrivateIpAddress 10.0.0.4
$avSet=Get-AZAvailabilitySet -Name dcAvailabilitySet -ResourceGroupName $rgName
$vm=New-AZVMConfig -VMName $vmName -VMSize $vmSize -AvailabilitySetId $avSet.Id
$vm=Set-AZVMOSDisk -VM $vm -Name ($vmName +"-OS") -DiskSizeInGB 128 -CreateOption FromImage -StorageAccountType "Standard_LRS"
$diskConfig=New-AZDiskConfig -AccountType "Standard_LRS" -Location $locName -CreateOption Empty -DiskSizeGB 20
$dataDisk1=New-AZDisk -DiskName ($vmName + "-DataDisk1") -Disk $diskConfig -ResourceGroupName $rgName
$vm=Add-AZVMDataDisk -VM $vm -Name ($vmName + "-DataDisk1") -CreateOption Attach -ManagedDiskId $dataDisk1.Id -Lun 1
$cred=Get-Credential -Message "Type the name and password of the local administrator account for adVM."
$vm=Set-AZVMOperatingSystem -VM $vm -Windows -ComputerName adVM -Credential $cred -ProvisionVMAgent -EnableAutoUpdate
$vm=Set-AZVMSourceImage -VM $vm -PublisherName MicrosoftWindowsServer -Offer WindowsServer -Skus 2012-R2-Datacenter -Version "latest"
$vm=Add-AZVMNetworkInterface -VM $vm -Id $nic.Id
New-AZVM -ResourceGroupName $rgName -Location $locName -VM $vm
## conecte al adVM y ejecute
$disk=Get-Disk | where {$_.PartitionStyle -eq "RAW"}
$diskNumber=$disk.Number
Initialize-Disk -Number $diskNumber
New-Partition -DiskNumber $diskNumber -UseMaximumSize -AssignDriveLetter
Format-Volume -DriveLetter F
Install-WindowsFeature AD-Domain-Services -IncludeManagementTools
Install-ADDSForest -DomainName campoh.lab -DatabasePath "F:\NTDS" -SysvolPath "F:\SYSVOL" -LogPath "F:\Logs"
Add-WindowsFeature RSAT-ADDS-Tools
New-ADUser -SamAccountName sp_farm_db -AccountPassword (read-host "Set user password" -assecurestring) -name "sp_farm_db" -enabled $true -PasswordNeverExpires $true -ChangePasswordAtLogon $false
New-ADUser -Name EXCHSVC -GivenName EXCHSVC -UserPrincipalName EXCHSVC -ChangePasswordAtLogon $false -AccountPassword (ConvertTo-SecureString -AsPlainText "p@ssw0rd" -Force) -Enabled $true
New-ADUser -Name SYSADMIN -GivenName EXCHADMIN -UserPrincipalName EXCHADMIN -ChangePasswordAtLogon $false -AccountPassword (ConvertTo-SecureString -AsPlainText "p@ssw0rd" -Force) -Enabled $true
New-ADUser -Name EFlores -GivenName "Maria Elena" -surname "Flores" -UserPrincipalName EFlores -EmailAddress EFlores@campoh.lab -ChangePasswordAtLogon $false -AccountPassword (ConvertTo-SecureString -AsPlainText "p@ssw0rd" -Force) -Enabled $true
New-ADUser -Name Vgarcia -GivenName "Victor" -surname "Garcia" -UserPrincipalName Vgarcia -EmailAddress Vgarcia@campoh.lab -ChangePasswordAtLogon $false -AccountPassword (ConvertTo-SecureString -AsPlainText "p@ssw0rd" -Force) -Enabled $true
New-ADUser -Name LRodriguez -GivenName "Lourdes" -surname "Rodriguez" -UserPrincipalName LRodriguez -EmailAddress LRodriguez@campoh.lab -ChangePasswordAtLogon $false -AccountPassword (ConvertTo-SecureString -AsPlainText "p@ssw0rd" -Force) -Enabled $true
New-ADUser -Name JLSanchez -GivenName "Jorge Luis" -surname "Sanchez" -UserPrincipalName JLSanchez -EmailAddress JLSanchez@campoh.lab -ChangePasswordAtLogon $false -AccountPassword (ConvertTo-SecureString -AsPlainText "p@ssw0rd" -Force) -Enabled $true
New-ADUser -Name CZambrano -GivenName "Cecilia" -surname "Zambrano" -UserPrincipalName CZambrano -EmailAddress CZambrano@campoh.lab -ChangePasswordAtLogon $false -AccountPassword (ConvertTo-SecureString -AsPlainText "p@ssw0rd" -Force) -Enabled $true
New-ADUser -Name MSalazar -GivenName "Mariana " -surname "Salazar" -UserPrincipalName MSalazar -EmailAddress MSalazar@campoh.lab -ChangePasswordAtLogon $false -AccountPassword (ConvertTo-SecureString -AsPlainText "p@ssw0rd" -Force) -Enabled $true
New-ADUser -Name JCTorres -GivenName "Juan Carlos" -surname "Torres" -UserPrincipalName JCTorres -EmailAddress JCTorres@campoh.lab -ChangePasswordAtLogon $false -AccountPassword (ConvertTo-SecureString -AsPlainText "p@ssw0rd" -Force) -Enabled $true
New-ADUser -Name ALAndrade -GivenName "Ana Lucia" -surname "Andrade" -UserPrincipalName ALAndrade -EmailAddress ALAndrade@campoh.lab -ChangePasswordAtLogon $false -AccountPassword (ConvertTo-SecureString -AsPlainText "p@ssw0rd" -Force) -Enabled $true
New-ADUser -Name MVera -GivenName "Miguel Angel" -surname "Vera" -UserPrincipalName MVera -EmailAddress MVera@campoh.lab -ChangePasswordAtLogon $false -AccountPassword (ConvertTo-SecureString -AsPlainText "p@ssw0rd" -Force) -Enabled $true
## Fase 2- Creamos ahora la maquina de Exchange
$vmDNSName="mail2393"
$rgName="Devops2020_rg"
$locName=(Get-AZResourceGroup -Name $rgName).Location
Test-AZDnsAvailability -DomainQualifiedName $vmDNSName -Location $locName
# Set up key variables
$subscrName="Plataformas de MSDN"
$rgName="Devops2020_rg"
$vmDNSName="mail2393"
# Set the Azure subscription
Select-AzSubscription -SubscriptionName $subscrName
# Get the Azure location and storage account names
$locName=(Get-AZResourceGroup -Name $rgName).Location
$saName=(Get-AZStorageaccount | Where {$_.ResourceGroupName -eq $rgName}).StorageAccountName
# Create an availability set for Exchange virtual machines
New-AZAvailabilitySet -ResourceGroupName $rgName -Name exAvailabilitySet -Location $locName -Sku Aligned  -PlatformUpdateDomainCount 5 -PlatformFaultDomainCount 2
# Specify the virtual machine name and size
$vmName="exVM"
$vmSize="Standard_D3_v2"
$vnet=Get-AZVirtualNetwork -Name $vnetName -ResourceGroupName $rgName
$avSet=Get-AZAvailabilitySet -Name exAvailabilitySet -ResourceGroupName $rgName
$vm=New-AZVMConfig -VMName $vmName -VMSize $vmSize -AvailabilitySetId $avSet.Id
# Create the NIC for the virtual machine
$nicName=$vmName + "-NIC"
$pipName=$vmName + "-PublicIP"
$pip=New-AZPublicIpAddress -Name $pipName -ResourceGroupName $rgName -DomainNameLabel $vmDNSName -Location $locName -AllocationMethod Dynamic
$nic=New-AZNetworkInterface -Name $nicName -ResourceGroupName $rgName -Location $locName -SubnetId $vnet.Subnets[0].Id -PublicIpAddressId $pip.Id -PrivateIpAddress "10.0.0.5"
# Create and configure the virtual machine
$cred=Get-Credential -Message "Type the name and password of the local administrator account for exVM."
$vm=Set-AZVMOSDisk -VM $vm -Name ($vmName +"-OS") -DiskSizeInGB 128 -CreateOption FromImage -StorageAccountType "Standard_LRS"
$vm=Set-AZVMOperatingSystem -VM $vm -Windows -ComputerName $vmName -Credential $cred -ProvisionVMAgent -EnableAutoUpdate
$vm=Set-AZVMSourceImage -VM $vm -PublisherName MicrosoftWindowsServer -Offer WindowsServer -Skus 2012-R2-Datacenter -Version "latest"
$vm=Add-AZVMNetworkInterface -VM $vm -Id $nic.Id
New-AZVM -ResourceGroupName $rgName -Location $locName -VM $vm
## Conectese a exVM y ejecute
Add-Computer -DomainName "campoh.lab"
Install-WindowsFeature AS-HTTP-Activation, Server-Media-Foundation, NET-Framework-45-Features, RPC-over-HTTP-proxy, RSAT-Clustering, RSAT-Clustering-CmdInterface, RSAT-Clustering-Mgmt, RSAT-Clustering-PowerShell, WAS-Process-Model, Web-Asp-Net45, Web-Basic-Auth, Web-Client-Auth, Web-Digest-Auth, Web-Dir-Browsing, Web-Dyn-Compression, Web-Http-Errors, Web-Http-Logging, Web-Http-Redirect, Web-Http-Tracing, Web-ISAPI-Ext, Web-ISAPI-Filter, Web-Lgcy-Mgmt-Console, Web-Metabase, Web-Mgmt-Console, Web-Mgmt-Service, Web-Net-Ext45, Web-Request-Monitor, Web-Server, Web-Stat-Compression, Web-Static-Content, Web-Windows-Auth, Web-WMI, Windows-Identity-Foundation, RSAT-ADDS
Restart-Computer
## Configurar el Exchange
Write-Host (Get-AZPublicIpaddress -Name "40.84.58.22" -ResourceGroup $rgName).DnsSettings.Fqdn
## Desde exVM
## descarga los pre-requisitos, 
## https://go.microsoft.com/fwlink/p/?linkid=863265 ".NET Framework 4.7.2 "
## https://go.microsoft.com/fwlink/?linkid=327788 "Paquete redistribuible de Visual C++ para Visual Studio 2012"
## https://go.microsoft.com/fwlink/?linkid=2002913 "Paquete redistribuible de Visual C++ para Visual Studio 2013"
## https://go.microsoft.com/fwlink/p/?linkId=258269 "API administrada de comunicaciones unificadas de Microsoft 4.0, Core Runtime (64 bits)" 
## descarga el ISO de Exchange con el ultimo CU
e:
.\setup.exe /prepareSchema /IacceptExchangeServerLicenseTerms
.\setup.exe /prepareAD /OrganizationName:LandonHotel /IacceptExchangeServerLicenseTerms
.\setup.exe /mode:Install /role:Mailbox /OrganizationName:LandonHotel /IacceptExchangeServerLicenseTerms
Restart-Computer
$dnsName="mail1473.eastus2.cloudapp.azure.com"
$user1Name="chris@" + $dnsName
$user2Name="janet@" + $dnsName
$db=Get-MailboxDatabase
$dbName=$db.Name
$password = Read-Host "Enter password" -AsSecureString
New-Mailbox -UserPrincipalName $user1Name -Alias chris -Database $dbName -Name ChrisAshton -OrganizationalUnit Users -Password $password -FirstName Chris -LastName Ashton -DisplayName "Chris Ashton"
New-Mailbox -UserPrincipalName $user2Name -Alias janet -Database $dbName -Name JanetSchorr -OrganizationalUnit Users -Password $password -FirstName Janet -LastName Schorr -DisplayName "Janet Schorr"
## Fase 3- Creamos ahora la maquina de SQL Server
# Log in to Azure
Connect-AzAccount
# Set up key variables
$subscrName="Plataformas de MSDN"
$rgName="Devops2020_rg"
# Set the Azure subscription and location
Select-AzSubscription -SubscriptionName $subscrName
$locName=(Get-AzResourceGroup -Name $rgName).Location
# Create an availability set for SQL Server virtual machines
New-AzAvailabilitySet -ResourceGroupName $rgName -Name sqlAvailabilitySet -Location $locName -Sku Aligned  -PlatformUpdateDomainCount 5 -PlatformFaultDomainCount 2
# Create the SQL Server virtual machine
$vmName="sqlVM"
$vmSize="Standard_D3_V2"
$vnetName="Vnet01"
$vnet=Get-AzVirtualNetwork -Name $vnetName -ResourceGroupName $rgName
$pip=New-AzPublicIpAddress -Name ($vmName + "-PIP") -ResourceGroupName $rgName -Location $locName -AllocationMethod Dynamic
$nic=New-AzNetworkInterface -Name ($vmName + "-NIC") -ResourceGroupName $rgName -Location $locName -SubnetId $vnet.Subnets[0].Id -PublicIpAddressId $pip.Id -PrivateIpAddress "10.0.0.6"
$avSet=Get-AzAvailabilitySet -Name sqlAvailabilitySet -ResourceGroupName $rgName 
$vm=New-AzVMConfig -VMName $vmName -VMSize $vmSize -AvailabilitySetId $avSet.Id
$vm=Set-AzVMOSDisk -VM $vm -Name ($vmName +"-OS") -DiskSizeInGB 128 -CreateOption FromImage -StorageAccountType "Standard_LRS"
$diskSize=100
$diskConfig=New-AzDiskConfig -AccountType "Standard_LRS" -Location $locName -CreateOption Empty -DiskSizeGB $diskSize
$dataDisk1=New-AzDisk -DiskName ($vmName + "-SQLData") -Disk $diskConfig -ResourceGroupName $rgName
$vm=Add-AzVMDataDisk -VM $vm -Name ($vmName + "-SQLData") -CreateOption Attach -ManagedDiskId $dataDisk1.Id -Lun 1
$cred=Get-Credential -Message "Type the name and password of the local administrator account of the SQL Server computer." 
$vm=Set-AzVMOperatingSystem -VM $vm -Windows -ComputerName $vmName -Credential $cred -ProvisionVMAgent -EnableAutoUpdate
$vm=Set-AzVMSourceImage -VM $vm -PublisherName MicrosoftSQLServer -Offer SQL2017-WS2016 -Skus Standard -Version "latest"
$vm=Add-AzVMNetworkInterface -VM $vm -Id $nic.Id
New-AzVM -ResourceGroupName $rgName -Location $locName -VM $vm
## Connect sqlVM 
Add-Computer -DomainName "campoh.lab"
Restart-Computer
Get-Disk | Where PartitionStyle -eq "RAW" | Initialize-Disk -PartitionStyle GPT -PassThru | New-Partition -AssignDriveLetter -UseMaximumSize | Format-Volume -FileSystem NTFS -NewFileSystemLabel "SQL Data"
md f:\Data
md f:\Log
md f:\Backup
New-NetFirewallRule -DisplayName "SQL Server ports 1433, 1434, and 5022" -Direction Inbound -Protocol TCP -LocalPort 1433,1434,5022 -Action Allow
## Fase 4- Creamos ahora la maquina de SP Server
# Set up key variables
$subscrName="Plataformas de MSDN"
$rgName="Devops2020_rg"
$dnsName="campoh1473"
# Set the Azure subscription
Select-AzSubscription -SubscriptionName $subscrName
# Get the location
$locName=(Get-AzResourceGroup -Name $rgName).Location
# Create an availability set for SharePoint virtual machines
New-AzAvailabilitySet -ResourceGroupName $rgName -Name spAvailabilitySet -Location $locName -Sku Aligned  -PlatformUpdateDomainCount 5 -PlatformFaultDomainCount 2
# Create the spVM virtual machine
$vmName="spVM"
$vmSize="Standard_D3_V2"
$vnetName="Vnet01"
$vm=New-AzVMConfig -VMName $vmName -VMSize $vmSize
$pip=New-AzPublicIpAddress -Name ($vmName + "-PIP") -ResourceGroupName $rgName -DomainNameLabel $dnsName -Location $locName -AllocationMethod Dynamic
$vnet=Get-AzVirtualNetwork -Name $vnetName -ResourceGroupName $rgName
$nic=New-AzNetworkInterface -Name ($vmName + "-NIC") -ResourceGroupName $rgName -Location $locName -SubnetId $vnet.Subnets[0].Id -PublicIpAddressId $pip.Id -PrivateIpAddress "10.0.0.7"
$avSet=Get-AzAvailabilitySet -Name spAvailabilitySet -ResourceGroupName $rgName 
$vm=New-AzVMConfig -VMName $vmName -VMSize $vmSize -AvailabilitySetId $avSet.Id
$vm=Set-AzVMOSDisk -VM $vm -Name ($vmName +"-OS") -DiskSizeInGB 128 -CreateOption FromImage -StorageAccountType "Standard_LRS"
$cred=Get-Credential -Message "Type the name and password of the local administrator account."
$vm=Set-AzVMOperatingSystem -VM $vm -Windows -ComputerName $vmName -Credential $cred -ProvisionVMAgent -EnableAutoUpdate
$vm=Set-AzVMSourceImage -VM $vm -PublisherName "MicrosoftSharePoint" -Offer "MicrosoftSharePointServer" -Skus "2019" -Version "latest"
$vm=Add-AzVMNetworkInterface -VM $vm -Id $nic.Id
New-AzVM -ResourceGroupName $rgName -Location $locName -VM $vm
## Connect spVM 
Add-Computer -DomainName "campoh.lab"
Restart-Computer
New-NetFirewallRule -DisplayName "SQL Server ports 1433, 1434, and 5022" -Direction Inbound -Protocol TCP -LocalPort 1433,1434,5022 -Action Allow
Write-Host (Get-AzPublicIpaddress -Name "13.77.127.118" -ResourceGroup $rgName).DnsSettings.Fqdn
##Desplegar un cliente
$rgName="Devops2020_rg"
$locName=(Get-AzResourceGroup -Name $rgName).Location
$vnet=Get-AzVirtualNetwork -Name $vnetName -ResourceGroupName $rgName
$pip=New-AzPublicIpAddress -Name CLIENT1-PIP -ResourceGroupName $rgName -Location $locName -AllocationMethod Dynamic
$nic=New-AzNetworkInterface -Name CLIENT1-NIC -ResourceGroupName $rgName -Location $locName -SubnetId $vnet.Subnets[0].Id -PublicIpAddressId $pip.Id
$vm=New-AzVMConfig -VMName CLIENT1 -VMSize Standard_A1
$cred=Get-Credential -Message "Type the name and password of the local administrator account for CLIENT1."
$vm=Set-AzVMOperatingSystem -VM $vm -Windows -ComputerName CLIENT1 -Credential $cred -ProvisionVMAgent -EnableAutoUpdate
$vm=Set-AzVMSourceImage -VM $vm -PublisherName MicrosoftWindowsServer -Offer WindowsServer -Skus 2016-Datacenter -Version "latest"
$vm=Add-AzVMNetworkInterface -VM $vm -Id $nic.Id
$vm=Set-AzVMOSDisk -VM $vm -Name "CLIENT1-OS" -DiskSizeInGB 128 -CreateOption FromImage -StorageAccountType "Standard_LRS"
New-AzVM -ResourceGroupName $rgName -Location $locName -VM $vm
## Detener / Iniciar las maquinas virtuales
$rgName="Devops2020_rg"
Stop-AZVM -Name Client1 -ResourceGroupName $rgName -Force
Stop-AZVM -Name exVM -ResourceGroupName $rgName -Force
Stop-AzVM -Name spVM -ResourceGroupName $rgName -Force
Stop-AzVM -Name sqlVM -ResourceGroupName $rgName -Force
Stop-AZVM -Name adVM -ResourceGroupName $rgName -Force
$rgName="Devops2020_rg"
Start-AZVM -Name adVM -ResourceGroupName $rgName
Start-AZVM -Name exVM -ResourceGroupName $rgName
Start-AzVM -Name sqlVM -ResourceGroupName $rgName
Start-AzVM -Name spVM -ResourceGroupName $rgName
Start-AZVM -Name Client1 -ResourceGroupName $rgName

az-vm-parameters.json

{
«$schema»: «https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#»,
«contentVersion»: «1.0.0.0»,
«parameters»: {
«vmSize»: {
«value»: «Standard_D2s_v3»
},
«adminUsername»: {
«value»: «sysadmin»
},
«adminPassword»: {
«value»: «AzurePa55w.rd»
}
}
}

az-vm-template.json

{
«$schema»: «https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#»,
«contentVersion»: «1.0.0.0»,
«parameters»: {
«vmSize»: {
«type»: «string»,
«defaultValue»: «Standard_D2s_v3»,
«metadata»: {
«description»: «Virtual machine size»
}
},
«nameSuffix»: {
«type»: «string»,
«allowedValues»: [
«2»,
«3»
],
«metadata»: {
«description»: «Naming suffix»
}
},
«adminUsername»: {
«type»: «string»,
«metadata»: {
«description»: «Admin username»
}
},
«adminPassword»: {
«type»: «securestring»,
«metadata»: {
«description»: «Admin password»
}
}
},
«variables»: {
«vmName»: «[concat(‘az-vm’,parameters(‘nameSuffix’))]»,
«vmExtensionName»: «customScriptExtension»,
«nicName»: «[concat(‘az-nic’,parameters(‘nameSuffix’))]»,
«virtualNetworkName»: «[concat(‘az-vnet’,parameters(‘nameSuffix’))]»,
«nsgName»: «[concat(‘az-nsg’,parameters(‘nameSuffix’))]»,
«vnetIpPrefix»: «[concat(‘10.6’,parameters(‘nameSuffix’),’.0.0/22′)]»,
«subnetIpPrefix»: «[concat(‘10.6’,parameters(‘nameSuffix’),’.0.0/24′)]»,
«subnetName»: «subnet0»,
«subnetRef»: «[resourceId(‘Microsoft.Network/virtualNetworks/subnets’, variables(‘virtualNetworkName’), variables(‘subnetName’))]»,
«computeApiVersion»: «2019-04-01»,
«networkApiVersion»: «2019-04-01»
},
«resources»: [
{
«name»: «[variables(‘vmName’)]»,
«type»: «Microsoft.Compute/virtualMachines»,
«apiVersion»: «[variables(‘computeApiVersion’)]»,
«location»: «[resourceGroup().location]»,
«dependsOn»: [
«[variables(‘nicName’)]»
],
«properties»: {
«osProfile»: {
«computerName»: «[variables(‘vmName’)]»,
«adminUsername»: «[parameters(‘adminUsername’)]»,
«adminPassword»: «[parameters(‘adminPassword’)]»,
«windowsConfiguration»: {
«provisionVmAgent»: «true»
}
},
«hardwareProfile»: {
«vmSize»: «[parameters(‘vmSize’)]»
},
«storageProfile»: {
«imageReference»: {
«publisher»: «MicrosoftWindowsServer»,
«offer»: «WindowsServer»,
«sku»: «2019-Datacenter»,
«version»: «latest»
},
«osDisk»: {
«createOption»: «fromImage»
},
«dataDisks»: []
},
«networkProfile»: {
«networkInterfaces»: [
{
«properties»: {
«primary»: true
},
«id»: «[resourceId(‘Microsoft.Network/networkInterfaces’, variables(‘nicName’))]»
}
]
}
}
},
{
«type»: «Microsoft.Compute/virtualMachines/extensions»,
«name»: «[concat(variables(‘vmName’), ‘/’, variables(‘vmExtensionName’))]»,
«apiVersion»: «[variables(‘computeApiVersion’)]»,
«location»: «[resourceGroup().location]»,
«dependsOn»: [
«[concat(‘Microsoft.Compute/virtualMachines/’, variables(‘vmName’))]»
],
«properties»: {
«publisher»: «Microsoft.Compute»,
«type»: «CustomScriptExtension»,
«typeHandlerVersion»: «1.7»,
«autoUpgradeMinorVersion»: true,
«settings»: {
«commandToExecute»: «powershell.exe Install-WindowsFeature -name Web-Server -IncludeManagementTools && powershell.exe remove-item ‘C:\\inetpub\\wwwroot\\iisstart.htm’ && powershell.exe Add-Content -Path ‘C:\\inetpub\\wwwroot\\iisstart.htm’ -Value $(‘Hello World from ‘ + $env:computername)»
}
}
},
{
«type»: «Microsoft.Network/virtualNetworks»,
«name»: «[variables(‘virtualNetworkName’)]»,
«apiVersion»: «[variables(‘networkApiVersion’)]»,
«location»: «[resourceGroup().location]»,
«comments»: «Virtual Network»,
«properties»: {
«addressSpace»: {
«addressPrefixes»: [
«[variables(‘vnetIpPrefix’)]»
]
},
«subnets»: [
{
«name»: «[variables(‘subnetName’)]»,
«properties»: {
«addressPrefix»: «[variables(‘subnetIpPrefix’)]»
}
}
]
}
},
{
«name»: «[variables(‘nicName’)]»,
«type»: «Microsoft.Network/networkInterfaces»,
«apiVersion»: «[variables(‘networkApiVersion’)]»,
«location»: «[resourceGroup().location]»,
«comments»: «Primary NIC»,
«dependsOn»: [
«[variables(‘nsgName’)]»,
«[variables(‘virtualNetworkName’)]»
],
«properties»: {
«ipConfigurations»: [
{
«name»: «ipconfig1»,
«properties»: {
«subnet»: {
«id»: «[variables(‘subnetRef’)]»
},
«privateIPAllocationMethod»: «Dynamic»
}
}
],
«networkSecurityGroup»: {
«id»: «[resourceId(‘Microsoft.Network/networkSecurityGroups’, variables(‘nsgName’))]»
}
}
},
{
«name»: «[variables(‘nsgName’)]»,
«type»: «Microsoft.Network/networkSecurityGroups»,
«apiVersion»: «[variables(‘networkApiVersion’)]»,
«location»: «[resourceGroup().location]»,
«comments»: «Network Security Group (NSG) for Primary NIC»,
«properties»: {
«securityRules»: [
{
«name»: «default-allow-rdp»,
«properties»: {
«priority»: 1000,
«sourceAddressPrefix»: «*»,
«protocol»: «Tcp»,
«destinationPortRange»: «3389»,
«access»: «Allow»,
«direction»: «Inbound»,
«sourcePortRange»: «*»,
«destinationAddressPrefix»: «*»
}
},
{
«name»: «default-allow-http»,
«properties»: {
«priority»: 1100,
«sourceAddressPrefix»: «*»,
«protocol»: «Tcp»,
«destinationPortRange»: «80»,
«access»: «Allow»,
«direction»: «Inbound»,
«sourcePortRange»: «*»,
«destinationAddressPrefix»: «*»
}
}
]
}
}
],
«outputs»: {}
}

az-vms-template.json

{
«$schema»: «https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#»,
«contentVersion»: «1.0.0.0»,
«parameters»: {
«vmSize»: {
«type»: «string»,
«defaultValue»: «Standard_D2s_v3»,
«metadata»: {
«description»: «VM size»
}
},
«vm0Name»: {
«type»: «string»,
«defaultValue»: «az-vm0»,
«metadata»: {
«description»: «VM0 name»
}
},
«vm1Name»: {
«type»: «string»,
«defaultValue»: «az-vm1»,
«metadata»: {
«description»: «VM1 name»
}
},
«adminUsername»: {
«type»: «string»,
«metadata»: {
«description»: «Admin username»
}
},
«adminPassword»: {
«type»: «securestring»,
«metadata»: {
«description»: «Admin password»
}
},
«virtualNetworkName»: {
«type»: «string»,
«defaultValue»: «az-vnet01»,
«metadata»: {
«description»: «Virtual network name»
}
}
},
«variables»: {
«vm0Name»: «[parameters(‘vm0Name’)]»,
«vm1Name»: «[parameters(‘vm1Name’)]»,
«vmExtensionName»: «customScriptExtension»,
«nic0»: «az-nic0»,
«nic1»: «az-nic1»,
«virtualNetworkName»: «[parameters(‘virtualNetworkName’)]»,
«nsgName»: «az-nsg01»,
«subnet0Name»: «subnet0»,
«subnet1Name»: «subnet1»,
«subnet1Ref»: «[resourceId(‘Microsoft.Network/virtualNetworks/subnets’, variables(‘virtualNetworkName’), variables(‘subnet0Name’))]»,
«subnet2Ref»: «[resourceId(‘Microsoft.Network/virtualNetworks/subnets’, variables(‘virtualNetworkName’), variables(‘subnet1Name’))]»,
«computeApiVersion»: «2019-04-01»,
«networkApiVersion»: «2019-04-01»
},
«resources»: [
{
«name»: «[variables(‘vm0Name’)]»,
«type»: «Microsoft.Compute/virtualMachines»,
«apiVersion»: «[variables(‘computeApiVersion’)]»,
«location»: «[resourceGroup().location]»,
«comments»: «The first VM»,
«dependsOn»: [
«[variables(‘nic0’)]»
],
«properties»: {
«osProfile»: {
«computerName»: «[variables(‘vm0Name’)]»,
«adminUsername»: «[parameters(‘adminUsername’)]»,
«adminPassword»: «[parameters(‘adminPassword’)]»,
«windowsConfiguration»: {
«provisionVmAgent»: «true»
}
},
«hardwareProfile»: {
«vmSize»: «[parameters(‘vmSize’)]»
},
«storageProfile»: {
«imageReference»: {
«publisher»: «MicrosoftWindowsServer»,
«offer»: «WindowsServer»,
«sku»: «2019-Datacenter»,
«version»: «latest»
},
«osDisk»: {
«createOption»: «fromImage»
},
«dataDisks»: []
},
«networkProfile»: {
«networkInterfaces»: [
{
«properties»: {
«primary»: true
},
«id»: «[resourceId(‘Microsoft.Network/networkInterfaces’, variables(‘nic0’))]»
}
]
}
}
},
{
«type»: «Microsoft.Compute/virtualMachines/extensions»,
«name»: «[concat(variables(‘vm0Name’), ‘/’, variables(‘vmExtensionName’))]»,
«apiVersion»: «[variables(‘computeApiVersion’)]»,
«location»: «[resourceGroup().location]»,
«dependsOn»: [
«[concat(‘Microsoft.Compute/virtualMachines/’, variables(‘vm0Name’))]»
],
«properties»: {
«publisher»: «Microsoft.Compute»,
«type»: «CustomScriptExtension»,
«typeHandlerVersion»: «1.7»,
«autoUpgradeMinorVersion»: true,
«settings»: {
«commandToExecute»: «powershell.exe Install-WindowsFeature -name Web-Server -IncludeManagementTools && powershell.exe remove-item ‘C:\\inetpub\\wwwroot\\iisstart.htm’ && powershell.exe Add-Content -Path ‘C:\\inetpub\\wwwroot\\iisstart.htm’ -Value $(‘Hello World from ‘ + $env:computername)»
}
}
},
{
«name»: «[variables(‘vm1Name’)]»,
«type»: «Microsoft.Compute/virtualMachines»,
«apiVersion»: «[variables(‘computeApiVersion’)]»,
«location»: «[resourceGroup().location]»,
«comments»: «The second VM»,
«dependsOn»: [
«[variables(‘nic1’)]»
],
«properties»: {
«osProfile»: {
«computerName»: «[variables(‘vm1Name’)]»,
«adminUsername»: «[parameters(‘adminUsername’)]»,
«adminPassword»: «[parameters(‘adminPassword’)]»,
«windowsConfiguration»: {
«provisionVmAgent»: «true»
}
},
«hardwareProfile»: {
«vmSize»: «[parameters(‘vmSize’)]»
},
«storageProfile»: {
«imageReference»: {
«publisher»: «MicrosoftWindowsServer»,
«offer»: «WindowsServer»,
«sku»: «2019-Datacenter»,
«version»: «latest»
},
«osDisk»: {
«createOption»: «fromImage»
},
«dataDisks»: []
},
«networkProfile»: {
«networkInterfaces»: [
{
«properties»: {
«primary»: true
},
«id»: «[resourceId(‘Microsoft.Network/networkInterfaces’, variables(‘nic1’))]»
}
]
}
}
},
{
«type»: «Microsoft.Compute/virtualMachines/extensions»,
«name»: «[concat(variables(‘vm1Name’), ‘/’, variables(‘vmExtensionName’))]»,
«apiVersion»: «[variables(‘computeApiVersion’)]»,
«location»: «[resourceGroup().location]»,
«dependsOn»: [
«[concat(‘Microsoft.Compute/virtualMachines/’, variables(‘vm1Name’))]»
],
«properties»: {
«publisher»: «Microsoft.Compute»,
«type»: «CustomScriptExtension»,
«typeHandlerVersion»: «1.7»,
«autoUpgradeMinorVersion»: true,
«settings»: {
«commandToExecute»: «powershell.exe Install-WindowsFeature -name Web-Server -IncludeManagementTools && powershell.exe remove-item ‘C:\\inetpub\\wwwroot\\iisstart.htm’ && powershell.exe Add-Content -Path ‘C:\\inetpub\\wwwroot\\iisstart.htm’ -Value $(‘Hello World from ‘ + $env:computername)»
}
}
},
{
«type»: «Microsoft.Network/virtualNetworks»,
«name»: «[variables(‘virtualNetworkName’)]»,
«apiVersion»: «[variables(‘networkApiVersion’)]»,
«location»: «[resourceGroup().location]»,
«comments»: «Virtual Network»,
«properties»: {
«addressSpace»: {
«addressPrefixes»: [
«10.60.0.0/22»
]
},
«subnets»: [
{
«name»: «[variables(‘subnet0Name’)]»,
«properties»: {
«addressPrefix»: «10.60.0.0/24»
}
},
{
«name»: «[variables(‘subnet1Name’)]»,
«properties»: {
«addressPrefix»: «10.60.1.0/24»
}
}
]
}
},
{
«name»: «[variables(‘nic0’)]»,
«type»: «Microsoft.Network/networkInterfaces»,
«apiVersion»: «[variables(‘networkApiVersion’)]»,
«location»: «[resourceGroup().location]»,
«comments»: «Primary NIC»,
«dependsOn»: [
«[variables(‘nsgName’)]»,
«[concat(‘Microsoft.Network/virtualNetworks/’, variables(‘virtualNetworkName’))]»
],
«properties»: {
«ipConfigurations»: [
{
«name»: «ipconfig1»,
«properties»: {
«subnet»: {
«id»: «[variables(‘subnet1Ref’)]»
},
«privateIPAllocationMethod»: «Dynamic»
}
}
],
«networkSecurityGroup»: {
«id»: «[resourceId(‘Microsoft.Network/networkSecurityGroups’, variables(‘nsgName’))]»
}
}
},
{
«name»: «[variables(‘nic1’)]»,
«type»: «Microsoft.Network/networkInterfaces»,
«apiVersion»: «[variables(‘networkApiVersion’)]»,
«location»: «[resourceGroup().location]»,
«comments»: «Primary NIC»,
«dependsOn»: [
«[variables(‘nsgName’)]»,
«[concat(‘Microsoft.Network/virtualNetworks/’, variables(‘virtualNetworkName’))]»
],
«properties»: {
«ipConfigurations»: [
{
«name»: «ipconfig1»,
«properties»: {
«subnet»: {
«id»: «[variables(‘subnet2Ref’)]»
},
«privateIPAllocationMethod»: «Dynamic»
}
}
],
«networkSecurityGroup»: {
«id»: «[resourceId(‘Microsoft.Network/networkSecurityGroups’, variables(‘nsgName’))]»
}
}
},
{
«name»: «[variables(‘nsgName’)]»,
«type»: «Microsoft.Network/networkSecurityGroups»,
«apiVersion»: «[variables(‘networkApiVersion’)]»,
«location»: «[resourceGroup().location]»,
«comments»: «Network Security Group (NSG) for Primary NIC»,
«properties»: {
«securityRules»: [
{
«name»: «default-allow-rdp»,
«properties»: {
«priority»: 1000,
«sourceAddressPrefix»: «*»,
«protocol»: «Tcp»,
«destinationPortRange»: «3389»,
«access»: «Allow»,
«direction»: «Inbound»,
«sourcePortRange»: «*»,
«destinationAddressPrefix»: «*»
}
},
{
«name»: «default-allow-http»,
«properties»: {
«priority»: 1100,
«sourceAddressPrefix»: «*»,
«protocol»: «Tcp»,
«destinationPortRange»: «80»,
«access»: «Allow»,
«direction»: «Inbound»,
«sourcePortRange»: «*»,
«destinationAddressPrefix»: «*»
}
}
]
}
}
],
«outputs»: {}
}

Plantillas ARM

$location = 'eastus'
$rgName = 'az-rg1'
New-AzResourceGroup -Name $rgName -Location $location
New-AzResourceGroupDeployment `
   -ResourceGroupName $rgName `
   -TemplateFile $HOME/az-vms-template.json `
   -TemplateParameterFile $HOME/az-vm-parameters.json `
   -AsJob

$rgName = 'az-rg2'
New-AzResourceGroup -Name $rgName -Location $location

New-AzResourceGroupDeployment `
   -ResourceGroupName $rgName `
   -TemplateFile $HOME/az-vm-template.json `
   -TemplateParameterFile $HOME/az-vm-parameters.json `
   -nameSuffix 2 `
   -AsJob

$rgName = 'az-rg3'
New-AzResourceGroup -Name $rgName -Location $location

New-AzResourceGroupDeployment `
   -ResourceGroupName $rgName `
   -TemplateFile $HOME/az-vm-template.json `
   -TemplateParameterFile $HOME/az-vm-parameters.json `
   -nameSuffix 3 `
   -AsJob

$virtualNetwork1 =az-vnet01
$virtualNetwork2 =az-vnet02
$virtualNetwork3 =az-vnet03

Add-AzVirtualNetworkPeering `
  -Name myVirtualNetwork1-myVirtualNetwork2 `
  -VirtualNetwork $virtualNetwork1 `
  -RemoteVirtualNetworkId $virtualNetwork2.Id

Add-AzVirtualNetworkPeering `
  -Name myVirtualNetwork2-myVirtualNetwork1 `
  -VirtualNetwork $virtualNetwork2 `
  -RemoteVirtualNetworkId $virtualNetwork1.Id

Get-AzVirtualNetworkPeering `
  -ResourceGroupName myResourceGroup `
  -VirtualNetworkName myVirtualNetwork1 `
  | Select PeeringState

Add-AzVirtualNetworkPeering `
  -Name myVirtualNetwork2-myVirtualNetwork3 `
  -VirtualNetwork $virtualNetwork2 `
  -RemoteVirtualNetworkId $virtualNetwork3.Id

Add-AzVirtualNetworkPeering `
  -Name myVirtualNetwork3-myVirtualNetwork2 `
  -VirtualNetwork $virtualNetwork3 `
  -RemoteVirtualNetworkId $virtualNetwork2.Id

Get-AzVirtualNetworkPeering `
  -ResourceGroupName myResourceGroup `
  -VirtualNetworkName myVirtualNetwork2 `
  | Select PeeringState

$PIP=Get-AzPublicIpAddress `
  -Name az-vm0 `
  -ResourceGroupName myResourceGroup | Select IpAddress

mstsc /v:$PIP

New-NetFirewallRule –DisplayName "Allow ICMPv4-In" –Protocol ICMPv4

mstsc /v:10.1.0.4
ping 10.0.0.4

Install-WindowsFeature RemoteAccess -IncludeManagementTools
Install-WindowsFeature -Name Routing -IncludeManagementTools -IncludeAllSubFeature
Install-WindowsFeature -Name "RSAT-RemoteAccess-Powershell"
Install-RemoteAccess -VpnType RoutingOnly
Get-NetAdapter | Set-NetIPInterface -Forwarding Enabled

Contribuciones

Las solicitudes de extracción son bienvenidas. Para cambios importantes, abra primero un problema para discutir qué le gustaría cambiar.

Asegúrese de actualizar las pruebas según corresponda.

Fabian Alberto Campo Microsoft Most Valuable Professional 2018-2020 Microsoft Certified Trainer /LinkedIn Learning Author Website: [www.campohenriquez.com] LinkedIn: [https://www.linkedin.com/in/fcampo/] Twitter: [https://twitter.com/fcampo] Youtube: [https://www.youtube.com/channel/UC5_-RLpII-4R_xyF6R4CZ2Q?view_as=subscriber]

Dungeons and Dragons

Hace muchos años ya, cuando trabajabamos para Synapsis con mi querido amigo Juan Ramon Lugo, pasamos casi a diario por la Libreria Francesa en el norte de Bogota (Calle 94 como con 19), yo alguna vez habia escuchado sobre un juego denominado Calabozos y dragones (Dungeons and dragons), pero no tenia ni la mas minima idea de como era el modelo de juego, me imaginaba que era algo como un monopoly, rummy-q o como el Sabelotodo, o incluso como el Risk donde tienes combates con los dados, para mantener un territorio, pero realmente es un juego que te lleva al reino de la imaginacion, a interpretar como un rol teatral, a un personaje imaginario, de una raza diferente {entre elfos, enanos, medianos, draconoides, semi-orcos, tabaxis}, de una clase como exploradores, guerreros, nobles, cartografos, hechiceros, aldeanos, picaros, bardos, entre muchos otros y tomar decisiones, para representar un papel dentro de una historia que se va hilando, y por eso se denomina de ROL, supongamos que existe un mundo como el mundo de fantasia que habitas es tipo «El señor de los anillos» de Tolkien, o como en westeros en «Game of thrones», un mundo donde existe la magia, los dragones, las espadas son la ley, y tu puedes representar a un oscuro hechicero, o a un mago de magia blanca, que tiene la mision de detectar las amenazas hacia la humanidad y las otras criaturas de la existencia. adicionalmente puede haber criaturas y seres titanicos, o mitologicos como unicornios, minotauros, tarantulas gigantescas o pegasos, la imaginacion es el limite-

En realidad yo no lograba entender como entrar a este mundo de fantasia y rol, pero una vez que decides como sera tu personaje, tienes 6 caracteristicas que determinan la fuerza, constitucion, destreza, inteligencia, carisma y sabiduria de tu personaje, estos atributos se calculan lanzando 7 veces 3 dados de 6 caras, y asignando 6 de esos resultados a cada uno de estos razgos, adicionalmente hay bonificadores, dependiendo del puntaje obtenido, y de acuerdo a que raza escojas tendras tambien beneficios, cual sera su oficio, su personalidad que puede ser caotica, neutral o legal, su vocacion y su motivacion, todo empieza realmente en el juego de imaginar que decision tomaria este personaje si fueras tu, y el unico objetivo del juego es divertirse interpretando al personaje. A veces puedes morirte en una mala decision, pero pues simplemente deberas empezar la campaña nuevamente con un nuevo personaje, o contar con alguno de tus compañeros de juego que se sepa un encantamiento de curacion, o que cuente con un botiquin medico y te quiera ayudar (puede que lo guarde para el mismo…)-

D&D Es un juego desarrollado por TSR hace mas de 30 años

Adicionalmente se usan dados poliedricos de 4, 6, 8, 10 y 20 caras para definir muchas de las caracteristicas de tu personaje, y para ver el resultado de algunas acciones, como por ejemplo si tu personaje saca su espada, para enfrentar a un troll, e intenta el ataque, deberas lanzar un dado de 20 caras, y obtener un puntaje por encima de 12 para que tu ataque sea efectivo, si obtienes un 17 por ejemplo, entonces lanzas el dado de 8 caras y obtienes el resultado del daño ocasionado.- el adversario caera cuando pierda todos sus puntos de vida, y el Dungeon master juega los papeles de todos los adversarios, y todos los retos que ofrece la expedicion. De una buena narrativa y de mantener a los jugadores conectados a la trama, se logra una buena aventura, y no es un juego donde siempre ganas, de hecho tus personajes pueden morir en una aventura, pero lo poderoso e importante de este juego es que es un juego para divertirse y pasarla bien. siempre puedes hacer un nuevo personaje-

Para estas fechas de pandemia, de encierro, han aparecido muchas apps que facilitan la adopcion de D&D, como Roll20.net que ofrece la posibilidad de jugarlo en sesiones de video llamada, compartiendo el tablero digitalmente entre todos los participantes. es muy buena app pues incorpora todo lo que puedes requerir, la hora de personaje, los dados, incluso video llamadas, es realmente muy completa. Otro tool interesante es MRPG que es como un whatsapp, donde por medio del chat se puede jugar una campaña, con la capacidad de incorporar los dados a la conversacion del chat, y recuerden que una campaña idealmente debe contar con 3 a 9 participantes, y se juega por turnos, entonces usar una herramienta asi, hace muy divertido el tema.- en conclusion mi invitacion es a que conozcan sobre este mundillo de nerds, de fantasia y dados, en estos tiempos donde la imaginacion no se cultiva mucho con la lectura, sino que todo son contenidos audiovisuales y personajes CGI.

Les deseo una buena aventura, y que embarcarse en esta exploracion les resulte en muchas horas de lectura, y compartir risas con sus mas cercanos amigos.- Les dejo este video con Vin Diesel jugando con su personaje Kaulder del «cazador de brujas» https://www.youtube.com/watch?v=yLEMb_RIZ3o

Clouds para mi Claus

Tengo la suerte y la fortuna de que mi esposa no es ingeniera de sistemas, ni tiene plena comprensión de mi lenguaje técnico, y todo ese argot, esa jerga que usamos en informática nerd, de hecho ella no tiene una idea exacta de los mis pensamientos digitales ni de mi mundo basado en bits bytes y qubits para almacenar información o del procesamiento de pixeles para representarlos en algún tipo de modelos 3D, y digo la suerte, porque disruptivamente mi vida hace diariamente un alto en el camino, cuando paso tiempo con ella, seguramente si fuese ingeniera mantendríamos surfeando en internet buscando resolver juntos cada cosa que me llama la atención, o cada problema que se nos presentara lo buscaríamos resolver de una manera muy ingeniosa.- por el contrario, como no es ingeniera, nuestras charlas y conversaciones nunca o casi nunca giran en torno a los scripts, las líneas de código o para hacer conexión con la idea de este post, con las nubes.

Sin embargo conversando en estos días durante un café, ella me manifestó que se sentía interesada en comprender de una manera sencilla sobre todos esos temas de cloud que nos apasionan a todos nosotros los informáticos, así que he decidido escribir este post para personas, no para ingenieros.

La nube es la nueva frontera para los devops y los sysadmins

Y es que seguramente si le preguntas a mis padres o a mis hijas, que es lo que hace Fabián, seguramente miraran hacia los lados, lo pensaran un poco haciendo esa mirada para el techo, y finalmente no lo saben a detalle tampoco… muy por encima dirán, ¡” Es ingeniero!»… como si eso mágicamente lo explicará todo. Tal vez solo explica mis prominentes y abultados cachetes… jajaja.

En esencia «la ingeniería de sistemas se propone por medio de procedimientos, rutinas y algoritmos, el resolver necesidades específicas que faciliten la vida de las personas.», desde una óptica académica, o una comparativa profesional, los psicólogos tratan de entender el comportamiento humano, los filósofos se cuestionan si la historia y los métodos fueron éticos, apropiados, y dadas las circunstancias la mejor opción, bueno por algoritmos vamos a decir que son métodos o funciones, que deducimos pensando en optimizar, mejorar, o facilitar, pero ese primer ejercicio de pensar como hallar una solución es lo que realmente le da valor que no solo por medio de código podemos realizar, realmente lo que se busca es ofrecer recomendaciones que permitan flujos, aprobaciones, o crear software que ayude a las personas a facilitar sus tareas diarias. Insisto, no todo lo que vemos los ingenieros de sistemas son bits, bytes y qubits, a veces el hecho de como registrar contablemente, es un procedimiento más manual que sistémico. Muchas de las soluciones actuales son más incluyentes y permiten que personas con limitaciones o acceso reducido, puedan aprovechar el potencial de la informática.

Sin embargo, no voy a idealizar que los sistemas informáticos no hayan transformado nuestra capacidad de memorizar y de retener en nuestros propios pensamientos alguna información importante. Como muchas personas de mi generación, a veces lográbamos memorizar los números de identidad, de cuentas bancarias o los números de teléfono de nuestros propios familiares, ahora que existen libretas digitales y post-it virtuales,  ya nadie recuerda ni por ejercicio ninguna información. Simplemente le piden a Alexa, Siri, Bixbi o Google que les recuerde la hora de la novela…

Bueno, volveré al tema de este post, sin cuestionar los efectos colaterales de la informática moderna, y los asistentes digitales y mi mala memoria, la evolución oficinista, administrativa y de secretaria artificial, que ha ofrecido Microsoft Office, no tiene comparación, y recuerdo con cierta nostalgia cuando de pequeño acompañante iba a la oficina de mi mamá quien era asistente- secretaria de gerencia. Ella tenía que organizar carpetas en archivadores, con cientos de documentos que mecanografiaba en su flamante máquina de escribir. Ahora le hacemos dictados por voz y la información es almacenada e indexada para facilidad de búsqueda.

Hoy en día todos hablan de Cloud computing peeero… eso en términos claros, ¿eso que es? – bueno vamos a decir simplemente que en tiempos de antaño cuando Windows server 2003 existía, teníamos capacidades de virtualizar máquinas usando un aplicativo llamado virtual PC. Virtualizar una máquina consiste en crear un espacio de ejecución donde asignamos una cantidad de memoria y un número de procesadores para instalar un sistema operativo sobre un archivo que llamamos un disco duro virtual, sobre este se puede instalar según convenga un Linux o un Windows. Este hipervisor hacia la administración de recursos del sistema operativo del host para permitir que una máquina imaginaria (virtual), se ejecutará dentro de la máquina física.  Ciertamente esto propone en ese momento un paradigma nuevo y disruptivo que permite aprovechar más el uso de los recursos como procesadores o memoria, el uso de cableado, alimentación eléctrica y de refrigeración. Pero sobre todo dinamiza increíblemente el tiempo de despliegue e instalación de nuevos proyectos se reduce a horas… que digo horas, minutos tal vez.

Sin embargo, decimos que es una nube, porque es borroso, lograr identificar en que servidor (físico) se están ejecutando nuestras cargas de máquinas virtuales, y dado que pueden estar ejecutándose en muchas maquinas físicas, no precisamente en el mismo centro de datos, por eso decimos que estamos en una nube. Por referirme puntualmente al caso de Microsoft, al momento de escribir este post Azure cuenta con más de 60 centros de datos a nivel mundial, centros de datos que tienen el tamaño de 20 campos de futbol americano, es decir que son lotes enormes, con diferentes edificios, con alimentación eléctrica redundante, y diferentes salas llenas de miles y miles de racks donde están organizados miles o cientos de miles de servidores físicos.

Porque gracias a la virtualizacion, podemos simular redes internas o externas, podemos manejar distintos sistemas operativos y montar fácilmente todo un escenario de laboratorio con varias máquinas virtuales sobre un solo servidor físico. 😉

Microsoft pudo transformar esta aplicación de virtual PC a un concepto llamado hipervisor o Hyper-v donde se podía hacer una mejor administración de recursos gracias a una integración nativa a nivel de kernel.  Paralelamente otros fabricantes como VMware o Virtual Box también presentaron sus funciones de hipervisor, y en el mundillo Linux hubo buenos competidores también.  Sin embargo, aprendimos que para el host se precisan 2GB de RAM al menos, y por cada máquina virtual para su propio sistema operativo 2 GB más lo que precisa el rol que la máquina virtual ejecutará. El mundo de los centros de datos llenos de servidores ruidosos, calurosos y monotarea rápidamente fueron cambiando a modelos de virtualización de máquinas, las cuales podían migrar entre diferentes hosts y esto aumentaba significativamente los índices de disponibilidad para estos equipos. Claramente vivimos una gran optimización de uso de recursos, de redes y de espacios.

Para una empresa emergente o startup era difícil invertir unos $15.000 dólares para comprar sus propios servidores, entonces muchos empezaron a alquilar un espacio compartido, un co-hosting con otras empresas sobre los mismos servidores, así pagando entre varios el alquiler era como compartir los costos de la renta de un departamento entre varios. Sin embargo, la actividad de poder aplicar hotfix a los diferentes sistemas operativos, y mantener un monitoreo constante sobre el uso de recursos y de las alertas de disponibilidad, podía precisar de un sistema adicional como System Center Operations Manager o Nagios. Entonces aquellos centros de datos que permitían al cliente autogestión, escalabilidad y alta disponibilidad fue lo que denominamos una nube privada, o en inglés un private Cloud. Grandes corporaciones como AWS, Google o Azure de Microsoft, implementaron enormes centros de datos, como si fueran complejos hoteleros, donde puedes escoger la talla de la máquina virtual que quieres alquilar, de acuerdo con el tamaño de la suite así mismo tienes que pagar.

En la nube publica entonces puedes contratar diferentes tipos de servicio, desde un flamante Windows Server 2022, con 64 VCPU y 512 terabytes de RAM, a un modesto Linux de un VCPU y media giga de RAM. Nos podemos montar en una maquina muy sencilla y en la medida que nuestro negocio prospere, o el servicio se haga más popular y utilizado podemos o agrandar en capacidades la máquina o ampliar el número de equipos que realizan el mismo rol. Estas nubes públicas son flexibles en cuanto a contratos y pagos así que puedes usar tu tarjeta de crédito y pagar de acuerdo con tus consumos, o aprovisionar un saldo del cual ir descontando cada mes como un modelo prepagado

Ahora bien, si he sido claro hasta este punto, quiero que se imaginen la nueva realidad donde ya no ocupamos sistemas operativos independientes por cada instancia de máquina virtual, sino que ocupamos un «sandbox» que es un espacio de ejecución aislado, donde podemos ejecutar los Pods de Docker, estas instancias ocupan menos recursos pues funcionan con la misma mecánica que un rol instalado a un sistema operativo, ocupando las librerías DLL y los binarios para ejecutar su aplicación. La idea de usar estos microservicios está revolucionando todas las arquitecturas, porque es como si tuvieras varios módulos que se pudieran añadir a tu habitación del Hotel… quieres con Jacuzzi, ¡¡bam!! Ahí está, quieres otra habitación, ¡¡bam!! Desplegada… en cuestión de segundos, necesitas otro baño, igualmente… así mismo hay pods basados en Linux Alpine que pesan solamente 5MB, y que tras instalar un NGINX que equivale a un apache o un IIS, nos permite publicar un web site.

A veces nuestras conversaciones entre ingenieros pueden ser realmente complicadas si no tienes el contexto…

Ahora bien, la invitación a todos ustedes es que exploren un poco más esta nueva visión que está revolucionando la forma de ejecutar aplicaciones registrándose en https://hub.docker.com ejecuten docker, usen el https://labs.play-with-docker.com/, también y porque no, que aprendan de Linux, de administración de soluciones de almacenamiento, así como de bases de datos, de seguridad informática, firewalls y de cómo funcionan las redes de comunicaciones, DHCP, enrutamiento, y resolución de nombres por DNS, aunque sea un poco, pero estas cosas crecen tan rápido como un incendio, y como son de comunidades, es muy fácil quedarse atrás del lote. cuando empezamos los primeros a explorar las configuraciones de soluciones en nube teníamos que al menos como una referencia, conocer de todos estos aspectos.

En este caso los microservicios componen toda tu arquitectura, esto es gracioso pues si necesitas un pod de base de datos, y dos o tres que hagan web front end es posible sin más que especificar el archivo de manifiesto. Vamos a aumentar el número de pods, simplemente modificamos el manifiesto y este desplegara tantas máquinas como hagan falta. Los pods como ya no ejecutan un sistema operativo ahora ocupan muy poca memoria, y reiniciar un pod es cuestión de segundos. Si tenemos que administrar algunos pods es sencillo, pero cuando estamos monitoreando algunos cientos de ellos, es necesario valernos de utilidades como Kubernetes para poder gestionarlos sin mayor problema.

Es fácil quedarse cuando no vamos pedaleando al igual.

Muchas grandes compañías como Netflix se apalancan en sus plataformas gracias a los microservicios y esto permite que un microservicio maneje el inicio de sesión mientras que otro lleve estadísticas de tus preferencias y de la parrilla que te ofrece en consecuencia a tus últimas visualizaciones, estos algoritmos se ejecutan sobre algunos pods. En el caso de estos pods podemos tener batallones de pequeños pods haciendo cálculos ejecución de firmas, análisis de datos y transformación de datos… con el poder de los microservicios.

Los quiero ver a todos pedaleando en Powershell, explorando los comandos de Docker, desplegando kubernetes y utilizando los archivos de manifiesto JSON para sus despliegues automatizados en la nube. Hasta la proxima amigos.