Aprend铆 estas 6 lecciones de trabajar con la formaci贸n en la nube para toda la vida.

Empec茅 a trabajar con la formaci贸n en la nube hace 4 a帽os. Desde entonces, he roto muchas infraestructuras, incluso aquellas que ya estaban en producci贸n. Pero cada vez que estropeaba algo, aprend铆a cosas nuevas. Gracias a esta experiencia, compartir茅 algunas de las lecciones m谩s importantes que he aprendido.

imagen

Lecci贸n 1: Verifique los cambios antes de implementar


Aprend铆 esta lecci贸n poco despu茅s de comenzar a trabajar con la formaci贸n en la nube . No recuerdo lo que romp铆 entonces, pero recuerdo exactamente que us茅 el comando de actualizaci贸n aws cloudformation . Este comando simplemente despliega la plantilla sin ninguna verificaci贸n de los cambios que se implementar谩n. No creo que se requieran explicaciones, para lo cual es necesario verificar todos los cambios antes de implementarlos.

Despu茅s de esta falla, cambi茅 inmediatamente la canalizaci贸n de implementaci贸n , reemplazando el comando de actualizaci贸n con el comando create-change-set

# OPERATION is either "UPDATE" or "CREATE" changeset_id=$(aws cloudformation create-change-set \ --change-set-name "$CHANGE_SET_NAME" \ --stack-name "$STACK_NAME" \ --template-body "$TPL_PATH" \ --change-set-type "$OPERATION" \ --parameters "$PARAMETERS" \ --output text \ --query Id) aws cloudformation wait \ change-set-create-complete --change-set-name "$changeset_id" 

Cuando se crea un conjunto de cambios, no afecta a la pila existente. A diferencia del comando de actualizaci贸n, el enfoque de conjunto de cambios no se implementa realmente. En cambio, crea una lista de cambios que puede revisar antes de la implementaci贸n. Puede ver los cambios en la interfaz de la consola aws. Pero si prefiere automatizar todo lo que sea posible, verif铆quelo en la CLI:

 # this command is presented only for demonstrational purposes. # the real command should take pagination into account aws cloudformation describe-change-set \ --change-set-name "$changeset_id" \ --query 'Changes[*].ResourceChange.{Action:Action,Resource:ResourceType,ResourceId:LogicalResourceId,ReplacementNeeded:Replacement}' \ --output table 

Este comando deber铆a producir una salida similar a la siguiente:

 -------------------------------------------------------------------- | DescribeChangeSet | +---------+--------------------+----------------------+------------+ | Action | ReplacementNeeded | Resource | ResourceId | +---------+--------------------+----------------------+------------+ | Modify | True | AWS::ECS::Cluster | MyCluster | | Replace| True | AWS::RDS::DBInstance| MyDB | | Add | None | AWS::SNS::Topic | MyTopic | +---------+--------------------+----------------------+------------+ 

Preste especial atenci贸n a los cambios en los que Acci贸n es Reemplazar , Eliminar o donde Reemplazo necesario es verdadero . Estos son los cambios m谩s peligrosos y generalmente conducen a la p茅rdida de informaci贸n.

Cuando se ven los cambios, se pueden expandir

 aws cloudformation execute-change-set --change-set-name "$changeset_id" operation_lowercase=$(echo "$OPERATION" | tr '[:upper:]' '[:lower:]') aws cloudformation wait "stack-${operation_lowercase}-complete" \ --stack-name "$STACK_NAME" 

Lecci贸n 2: use la pol铆tica de pila para evitar el reemplazo o la eliminaci贸n de recursos con estado


A veces, solo mirar los cambios no es suficiente. Todos somos humanos y todos cometemos errores. Poco despu茅s de comenzar a usar conjuntos de cambios, mi compa帽ero de equipo realiz贸 una implementaci贸n sin saberlo, lo que condujo a una actualizaci贸n de la base de datos. No pas贸 nada terrible, porque era un entorno de prueba.

A pesar de que nuestros scripts mostraban una lista de cambios y ped铆an confirmaci贸n, se omiti贸 el cambio de Reemplazar porque la lista de cambios era tan grande que no cab铆a en la pantalla. Y como se trataba de una actualizaci贸n peri贸dica en el entorno de prueba, no se prest贸 mucha atenci贸n a los cambios.

Hay recursos que nunca querr谩s reemplazar o eliminar. Estos son servicios con estado, como una instancia de una base de datos RDS o un cl煤ster elastichsearch, etc. Ser铆a bueno que aws se negara autom谩ticamente a desplegarse, si la operaci贸n que se realiza requerir铆a la eliminaci贸n de dicho recurso. Afortunadamente, la formaci贸n en la nube tiene una forma integrada de hacer esto. Esto se llama la pol铆tica de pila, y puede leer m谩s sobre esto en la documentaci贸n :

 STACK_NAME=$1 RESOURCE_ID=$2 POLICY_JSON=$(cat <<EOF { "Statement" : [{ "Effect" : "Deny", "Action" : [ "Update:Replace", "Update:Delete" ], "Principal": "*", "Resource" : "LogicalResourceId/$RESOURCE_ID" }] } EOF ) aws cloudformation set-stack-policy --stack-name "$STACK_NAME" \ --stack-policy-body "$POLICY_JSON" 

Lecci贸n 3: use UsePreviousValue al actualizar una pila con par谩metros secretos


Cuando crea una entidad RDS, mysql AWS requiere que proporcione MasterUsername y MasterUserPassword. Dado que es mejor no guardar secretos en el c贸digo fuente, y quer铆a automatizar absolutamente todo, implement茅 un "mecanismo inteligente" en el que se obtienen las credenciales de s3 antes de la implementaci贸n, y si no se encuentran credenciales, se generan y almacenan nuevas credenciales en s3 .

Estas credenciales se pasar谩n como par谩metros al comando create-change-set de cloudformation. Durante los experimentos con el script, sucedi贸 que se perdi贸 la conexi贸n con s3, y mi "mecanismo inteligente" lo consider贸 como una se帽al para generar nuevas credenciales.

Si comenc茅 a usar este script en un entorno de producci贸n, y el problema de conexi贸n surgi贸 nuevamente, actualizar铆a la pila con nuevas credenciales. En este caso particular, no pasar谩 nada malo. Sin embargo, abandon茅 este enfoque y comenc茅 a usar otro, proporcionando credenciales solo una vez, al crear la pila. Y m谩s tarde, cuando la pila requiere actualizaci贸n, en lugar de especificar el valor secreto del par谩metro, simplemente usar铆a UsePreviousValue = true :

 aws cloudformation create-change-set \ --change-set-name "$CHANGE_SET_NAME" \ --stack-name "$STACK_NAME" \ --template-body "$TPL_PATH" \ --change-set-type "UPDATE" \ --parameters "ParameterKey=MasterUserPassword,UsePreviousValue=true" 

Lecci贸n 4: usar la configuraci贸n de reversi贸n


Otro equipo con el que trabaj茅 estaba usando una funci贸n de formaci贸n en la nube llamada configuraci贸n de reversi贸n . No la hab铆a visto antes y r谩pidamente me di cuenta de que esto har铆a que desplegar mis pilas fuera a煤n mejor. Ahora uso cada vez que implemento mi c贸digo en lambda o ECS usando la formaci贸n en la nube.

C贸mo funciona: usted especifica la alarma de CloudWatch en el par谩metro --rollback-configuration cuando crea el conjunto de cambios. M谩s tarde, cuando complete el conjunto de cambios, aws sigue la alarma durante al menos un minuto. Revierte el despliegue si durante este tiempo la alarma cambia de estado a ALARMA.

El siguiente es un ejemplo de un extracto de la plantilla de formaci贸n de nubes en el que creo una alarma de vigilancia de nubes que rastrea la m茅trica de la nube del usuario como el n煤mero de errores en los registros de la nube (la m茅trica se crea a trav茅s de MetricFilter ):

 Resources: # this metric tracks number of errors in the cloudwatch logs. In this # particular case it's assumed logs are in json format and the error logs are # identified by level "error". See FilterPattern ErrorMetricFilter: Type: AWS::Logs::MetricFilter Properties: LogGroupName: !Ref LogGroup FilterPattern: !Sub '{$.level = "error"}' MetricTransformations: - MetricNamespace: !Sub "${AWS::StackName}-log-errors" MetricName: Errors MetricValue: 1 DefaultValue: 0 ErrorAlarm: Type: AWS::CloudWatch::Alarm Properties: AlarmName: !Sub "${AWS::StackName}-errors" Namespace: !Sub "${AWS::StackName}-log-errors" MetricName: Errors Statistic: Maximum ComparisonOperator: GreaterThanThreshold Period: 1 # 1 minute EvaluationPeriods: 1 Threshold: 0 TreatMissingData: notBreaching ActionsEnabled: yes 

Ahora la alarma se puede usar como un desencadenante de reversi贸n al ejecutar un conjunto de herramientas:

 ALARM_ARN=$1 ROLLBACK_TRIGGER=$(cat <<EOF { "RollbackTriggers": [ { "Arn": "$ALARM_ARN", "Type": "AWS::CloudWatch::Alarm" } ], "MonitoringTimeInMinutes": 1 } EOF ) aws cloudformation create-change-set \ --change-set-name "$CHANGE_SET_NAME" \ --stack-name "$STACK_NAME" \ --template-body "$TPL_PATH" \ --change-set-type "UPDATE" \ --rollback-configuration "$ROLLBACK_TRIGGER" 

Lecci贸n 5: Aseg煤rese de implementar la 煤ltima versi贸n de la plantilla


No es f谩cil implementar la 煤ltima versi贸n de la plantilla de formaci贸n en la nube, pero causar谩 mucho da帽o. Una vez que estuvo con nosotros: el desarrollador no envi贸 los 煤ltimos cambios desde Git y despleg贸 sin saberlo la versi贸n anterior de la pila. Esto condujo a una aplicaci贸n simple que usaba esta pila.

Algo simple, como agregar una verificaci贸n para ver si una rama es relevante antes de la implementaci贸n, estar铆a bien (suponiendo que git es su herramienta de control de versiones):
 git fetch HEADHASH=$(git rev-parse HEAD) UPSTREAMHASH=$(git rev-parse master@{upstream}) if [[ "$HEADHASH" != "$UPSTREAMHASH" ]] ; then echo "Branch is not up to date with origin. Aborting" exit 1 fi 

Lecci贸n 6: no reinventes la rueda


Implementar con formaci贸n en la nube puede parecer f谩cil. Solo necesita un mont贸n de scripts de bash que ejecutan comandos aws cli.

Hace 4 a帽os, comenc茅 con scripts simples llamados aws cloudformation create-stack command. Pronto, el gui贸n ya no era simple. Cada lecci贸n aprendida hizo el gui贸n cada vez m谩s complejo. No solo fue dif铆cil, sino tambi茅n con un mont贸n de errores.

Ahora trabajo en un peque帽o departamento de TI. La experiencia ha demostrado que cada equipo tiene su propia forma de implementar pilas de informaci贸n en la nube. Y esto es malo. Ser铆a mejor si todos usaran un solo enfoque. Afortunadamente, hay muchas herramientas que lo ayudan a implementar y configurar pilas de informaci贸n en la nube.

Estas lecciones te ayudar谩n a evitar errores.

Source: https://habr.com/ru/post/446918/


All Articles