La importancia del CTO. ¿Es realmente importante un CTO para una Startup?

female software engineer coding on computer

En mi rol de mentor e inversionista, es común que me pidan ayuda para encontrar CTO para diferentes startups – lo que ya he realizado en un montón de ocasiones – y cada vez que lo han hecho, me preguntan; “¿Es tan importante tener un CTO?” o “¿Lo necesito para levantar capital?”. Hace un par … Leer más

Sobre la transformación digital desde la mirada de un nativo digital

laptop computers and wires

Hace un par de semanas me invitaron a participar del primer congreso de la Facultad de Ingeniería y Tecnología de la Universidad San Sebastián sobre la industria 4.0, y en esta ocasión, conversamos sobre mi experiencia en temas de transformación digital desde el punto de vista de una empresa B2B nacida digital. Si bien no … Leer más

Filtrar repositorios sin usar en Github

Github API listar repositorios de Organización

Cuando creas una cuenta organizacional en Github y van pasando los años, la probabilidad de que muchas personas tanto internas como externas hayan pasado por tu empresa. Esto mismo pasa con los repositorios, muchos de ellos quedan huerfanos y ya no tiene sentido que existan debido a que su código tampoco está en uso.

Utilizando las APIs de GITHUB es muy sencillo filtrar los repositorios por la última actualización que tuvieron, lo que hace mucho más sencillo el proceso de archivar estos repositorios.

En este mini post mostraré una forma «sencilla» de facilitar la eliminación de los repositorios de tu organización de GitHub sin uso, sin embargo no automatizaremos esta eliminación.

Probando API

En mi caso usaré Postman y como ejemplo una organización que hace tiempo no ocupo para los ejemplos. Recomiendo además leer la documentación original del Api de Github para leer los repositorios de una organización.

Antes que todo, para probar que podamos acceder al API de manera correcta, hagamos una prueba listando todos los repositorios públicos de manera ascendente por fecha de actualización.

curl --location --request GET 'https://api.github.com/orgs/NAITUSEIRL/repos?sort=updated&direction=asc'
Github API listar repositorios de Organización
Github API listar repositorios de Organización

Accediendo a los repositorios privados

En mi caso, y como lo comenté anteriormente, quiero filtrar repositorios en los cuales hayan interactuado personas que ya no trabajan en la empresa, y que además son códigos que no se están utilizando. La mayoría de estos repositorios son privados, por lo que debemos usar nuestras credenciales con permisos de Github para acceder a esta información.

Puedes crear un token nuevo para usar las APIs en la siguiente URL : https://github.com/settings/tokens

Estos tokens funcionan como Bearer Tokens, lo que nos hace muy sencilla la utilización de Postman para consumirlo. En el mismo GET con el que probaron el request anterior, vamos a la pestaña autorización, seleccionamos bearer, y en el nuevo recuerdo de texto ponemos el token de github. En mi caso estoy usando una variable de entorno para hacerlo un poco más seguro y para no tener que editar la imagen :).

Así de sencillo tenemos todos los repositorios, inclusive los privados, de tu organización ordenados por la última fecha de actualización. En caso de que queramos obtener solo los privados, esto lo podemos hacer agregando el parametro a la URL. Quedaría de la siguiente manera ;

curl --location --request GET 'https://api.github.com/orgs/NAITUSEIRL/repos?sort=updated&direction=asc&type=private' \

--header 'Authorization: Bearer MIGITHUBTOKEN'
Filtro repositorios privados Github API
Filtro repositorios privados Github API

TLDR;

En resumen, podemos usar las APIs de Github para ayudarnos a filtrar los repositorios, tanto público como privados, de nuestra organización para luego poder eliminarlos o archivarlos de manera más sencilla. Esto si se puede hacer a mano, pero creo que es mucho más sencillo de esta manera. Éxito en todo !

¡Mantengamos el contacto!

Me encantaría que te mantuvieras al día con el contenido que estoy generando. Recuerda que no es solo el blog, son las redes sociales, libros, y distintos pódcast 😎.

Hago todo lo posible para no hacer Spam,

¡MANTENGÁMONOS EN CONTACTO!

Me encantaría que te mantuvieras al día con el contenido que estoy generando. Recuerda que no es solo el blog, son las redes sociales, libros, y distintos pódcast 😎.

Hago todo lo posible para no hacer Spam,

API Privada con Serverless Framework, AWS y VPCs.

Api Gateway Private Endpoint

Generalmente cuando hablamos de APIs pensamos en la forma como otros desarrolladores se pueden conectar a nuestros sistemas, productos, o servicios. Sin embargo, cuando empiezas a desacoplar tus sistemas te das cuenta que el utilizar APIs para el desarrollo interno puede ser igual o más útil para el negocio.

Este ejemplo sencillo muestra como poder crear un API privada usando Serverless Framework y Amazon Web Services. Ojo, pestaña, y ceja, lo que estoy haciendo con este ejemplo no es hacer privada un API a través de autentificación y autorización, eso siempre se puede agregar sobre el API como una capa de seguridad aún mayor, en este caso estamos haciendo privada la conexión para que solo pueda ser accedida desde nuestra VPC a través de un AWS PrivateLink.

Ya han pasado un poco más de dos años desde que AWS lanzó esta  funcionalidad, sin embargo no había tenido la oportunidad y necesidad de utilizarla anteriormente. Pueden leer el Post original de AWS acá : https://aws.amazon.com/blogs/compute/introducing-amazon-api-gateway-private-endpoints/

El código de este ejemplo puede ser encontrado en GitHub : https://github.com/ctala/serverless-private-api-endpoint

Requerimientos

  1. Cuenta en AWS.
  2. Serverless Framework Instalado
  3. AWS CLI Instalado. Esto nos permitirá hacer el deployment de la aplicación de manera directa.
  4. Tener una Red Privada con la cual queramos acceder al servicio (VPC)
  5. Tener una máquina a la que podamos acceder para poder probar el servicio.

Creando el VPC Endpoint

Para generar el endpoint a utilizar, nos dirigimos al menú de VPCs de la consola de AWS, seleccionamos el sub-menú de endpoints en el costado izquierdo, y luego crear uno nuevo. Nos debería aparecer algo como lo que se muestra a continuación.

VPC Endpoint
VPC Endpoint

Si en busqueda escribimos execute-api, nos debería aparecer por defecto la opción que necesitamos para que este endpoint pueda ejecutar la API que crearemos. A continuación seleccionamos el VPC, las subnets, y las security groups correspondientes y damos click en continuar.

El Id de Endpoint resultante lo usaremos en nuestra configuración del Serverless.

Resource Policy

Antes de configurar el serverless, debemos definir quién puede y/o no puede tener acceso a nuestra red privada. En este caso, copiaremos el resource policy de ejemplo de AWS que hace Whitelist de la VPC que puede ejecutarlo (Se puede encontrar bajo Resources Policies en el menú de cualquier API bajo API Gateway.). La idea es que generemos este mismo Resource Policy usando la configuración del Serverless Framework.

Código del Serverless

El siguiente código es el que genera el Resource Policy mostrado anteriormente y levanta un Lamda con su API Gateway respectivo con un endpoint privado, además del endpoint por defecto del Serverless Framework con Hello World.

service: sls-test-private-endpoint
frameworkVersion: '2'

provider:
name: aws
runtime: nodejs12.x
region: us-west-2
stage: dev
endpointType: PRIVATE
vpcEndpointIds:
- vpce-0631ee46a323b75e4

#El Resource Policy que generamos primero bloqueará todo el tráfico que no sea de la/las VPCs listadas a bajo aws:sourceVpc, luego permitimos
# el acceso de todo lo demás.
resourcePolicy:
##Bloqueo de lo que no corresponde al VPC
- Effect: Deny
Principal: "*"
Action: execute-api:Invoke
Resource:
- execute-api:/*/*/*
Condition:
StringNotEquals:
aws:sourceVpc:
- vpc-03602a6783bdefb87
##Permiso a lo demás. Acá también podemos bloquiar por segmento de IP.
- Effect: Allow
Principal: "*"
Action: execute-api:Invoke
Resource:
- execute-api:/*/*/*

functions:
hello:
handler: handler.hello
events:
- http:
path: /
method: get

 

Probando la conexión.

 

Acá queremos hacer dos cosas, la primera es revisar que no podamos acceder a la URL desde nuestros computadores. Ya que el endpoint es un GET simplemente probamos utilizando la URL resultante del deployment, por ejemplo : https://80nyvq2u70.execute-api.us-west-2.amazonaws.com/dev/ . Si bien la URL mostrada es la original, no puede ser accedida debido a que está dentro de una API privada.

Para probar realmente que podemos acceder a esta API desde la VPC, lo que tenemos que hacer es llamarla desde una máquina que esté en esta. En este caso un simple comando Curl nos puede ayudar desde la consola de la máquina virtual.

curl -v https://80nyvq2u70.execute-api.us-west-2.amazonaws.com/dev/

En este caso, si todo salió según lo esperado, obtendremos la respuesta del serverless incluyendo todos los headers agregados desde AWS.

curl -v https://80nyvq2u70.execute-api.us-west-2.amazonaws.com/dev/
* Trying 10.0.16.153:443...
* TCP_NODELAY set
* Connected to 80nyvq2u70.execute-api.us-west-2.amazonaws.com (10.0.16.153) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server did not agree to a protocol
* Server certificate:
* subject: CN=*.execute-api.us-west-2.amazonaws.com
* start date: Apr 29 00:00:00 2020 GMT
* expire date: Apr 13 12:00:00 2021 GMT
* subjectAltName: host "80nyvq2u70.execute-api.us-west-2.amazonaws.com" matched cert's "*.execute-api.us-west-2.amazonaws.com"
* issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon
* SSL certificate verify ok.
> GET /dev/ HTTP/1.1
> Host: 80nyvq2u70.execute-api.us-west-2.amazonaws.com
> User-Agent: curl/7.68.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: Server
< Date: Wed, 23 Sep 2020 23:13:15 GMT
< Content-Type: application/json
< Content-Length: 2402
< Connection: keep-alive
< x-amzn-RequestId: e247cbde-523a-4867-89be-9588d3654b70
< x-amz-apigw-id: TV51yHB-PHcF2Mg=
< X-Amzn-Trace-Id: Root=1-5f6bd68b-2ef4b5a7424ef64695dd27cd;Sampled=0
< 
{
"message": "Go Serverless v1.0! Your function executed successfully!",
"input": {
"resource": "/",
"path": "/",
"httpMethod": "GET",
"headers": {
"Accept": "*/*",
"Host": "80nyvq2u70.execute-api.us-west-2.amazonaws.com",
"User-Agent": "curl/7.68.0",
"x-amzn-cipher-suite": "ECDHE-RSA-AES128-GCM-SHA256",
"x-amzn-tls-version": "TLSv1.2",
"x-amzn-vpc-id": "vpc-03602a6783bdefb87",
"x-amzn-vpce-config": "1",
"x-amzn-vpce-id": "vpce-0631ee46a323b75e4",
"X-Forwarded-For": "10.0.3.28"
},
"multiValueHeaders": {
"Accept": [
"*/*"
],
"Host": [
"80nyvq2u70.execute-api.us-west-2.amazonaws.com"
],
"User-Agent": [
"curl/7.68.0"
],
"x-amzn-cipher-suite": [
"ECDHE-RSA-AES128-GCM-SHA256"
],
"x-amzn-tls-version": [
"TLSv1.2"
],
"x-amzn-vpc-id": [
"vpc-03602a6783bdefb87"
],
"x-amzn-vpce-config": [
"1"
],
"x-amzn-vpce-id": [
"vpce-0631ee46a323b75e4"
],
"X-Forwarded-For": [
"10.0.3.28"
]
},
"queryStringParameters": null,
"multiValueQueryStringParameters": null,
"pathParameters": null,
"stageVariables": null,
"requestContext": {
"resourceId": "2qf3us2l93",
"resourcePath": "/",
"httpMethod": "GET",
"extendedRequestId": "TV51yHB-PHcF2Mg=",
"requestTime": "23/Sep/2020:23:13:15 +0000",
"path": "/dev/",
"accountId": "607613765343",
"protocol": "HTTP/1.1",
"stage": "dev",
"domainPrefix": "80nyvq2u70",
"requestTimeEpoch": 1600902795396,
"requestId": "e247cbde-523a-4867-89be-9588d3654b70",
"identity": {
"cognitoIdentityPoolId": null,
"cognitoIdentityId": null,
"vpceId": "vpce-0631ee46a323b75e4",
"principalOrgId": null,
"cognitoAuthenticationType": null,
"userArn": null,
"userAgent": "curl/7.68.0",
"accountId": null,
"caller": null,
"sourceIp": "10.0.3.28",
"accessKey": null,
"vpcId": "vpc-03602a6783bdefb87",
"cognitoAuthenticationProvider": null,
"user": null
},
"domainName": "80nyvq2u70.execute-api.us-west-2.amazonaws.com",
"apiId": "80nyvq2u70"
},
"body": null,
"isBase64Encoded": false
}
* Connection #0 to host 80nyvq2u70.execute-api.us-west-2.amazonaws.com left intact
}

Y eso sería todo. Con estos pasos sencillos podemos tener nuestra API privada funcionando para ser accedida desde los recursos que estén dentro de nuestra VPC.

¡Mantengamos el contacto!

Me encantaría que te mantuvieras al día con el contenido que estoy generando. Recuerda que no es solo el blog, son las redes sociales, libros, y distintos pódcast 😎.

Hago todo lo posible para no hacer Spam,

¡MANTENGÁMONOS EN CONTACTO!

Me encantaría que te mantuvieras al día con el contenido que estoy generando. Recuerda que no es solo el blog, son las redes sociales, libros, y distintos pódcast 😎.

Hago todo lo posible para no hacer Spam,

Tutorial : Full RESTfull API con AWS, Terraform, y Serverless Framework

Hace ya algunos años que he querido hacer un tutorial como este, en dónde de manera sencilla pueda explicar los distintos pasos de la creación de un API REST, o al menos como lo he aprendido a hacer basado en experiencia y errores.

Una de las razones del por qué nunca comencé con este proyecto es debido a que crear un API puede ser tan complejo como uno quiera, y nunca encontré el tiempo para realizarlo, por lo que decidí lanzar este tutorial por partes e iré publicando las distintas partes a medida que las vaya realizando.

En este tutorial crearemos un Full RESTfull API con seguridad basada en tokens utilizando AWS, Swagger, Terraform, DynamoDB, SSM, y Serverless Framework quién generará los recursos del API Gateway y Lambdas.

 

Estado Proyecto En Progreso
Fecha Inicio 17/05/2020
Fecha Actualización 17/05/2020
Fecha de Término
Capítulos listos 2/10
Link Youtube Playlist https://www.youtube.com/playlist?list=PLCjIDwuXOgwR64ScpUf6WLnW6j2jdkREX

 

Indice

  1. Entendiedo la necesidad. API de manejo de datos de usuarios y los datos requeridos.
  2. Conociendo las herramientas que se utilizarán y el por qué las usaremos.
  3. Diseñando la API utilizando Swagger. Antes de crear el API debemos saber que información recibirá y que información retornará.
  4. Generando la base de datos DynamoDB, y el recurso relacionado de SSM utilizando Terraform.
  5. Generando los endpoints utilizando Serverless Framework.
  6. Generando el CRUD de la aplicación. – Create, Read, Update, Delete –
  7. Asegurando nuestra API.

Extra

  1. Bloqueo de recursos en Terraform para impedir eliminaciones accidentales.
  2. Endpoint que lista los usuarios con paginación.
  3. Sincronizando DynamoDB con Redshift para realizar operaciones analiticas.

Leer más

Share to...