Estoy tratando de ejecutar un repositorio privado en la plataforma aws-ecs-fargate-1.4.0.
Para la autenticación de repositorio privado, seguí los documentos y funcionó bien.
De alguna manera, después de actualizar el servicio existente muchas veces, falla al ejecutar la tarea y se queja del error como
ResourceInitializationError: unable to pull secrets or registry auth: execution resource retrieval failed: unable to get registry auth from asm: service call has been retried 1 time(s): asm fetching secret from the service for <secretname>: RequestError: ... No he cambiado el ecsTaskExecutionRole y contiene todas las políticas requeridas para obtener el valor secreto.
Cómo hacer "Ejecutar tareas en una subred privada que tiene una tabla de enrutamiento de VPC configurada para enrutar el tráfico saliente a través de una puerta de enlace NAT en una subred pública. De esta manera, la puerta de enlace NAT puede abrir una conexión a ECR en nombre de la tarea":
Supuestos de esta solución:
Solución:
Tuve este problema y finalmente lo resolví.
Mi solución a continuación es:
Publique mi código CDK aquí como referencia. Pegué algunos enlaces de documentación en los comentarios de la función para que entiendas mejor su propósito.
Este es el EcsStack:
export class EcsStack extends Stack { constructor(scope: cdk.App, id: string, props: EcsStackProps) { super(scope, id, props); this.createOrderServiceCluster(props.vpc); } private createOrderServiceCluster(serviceVpc:ec2.IVpc) { const ecsClusterName = "EcsClusterOfOrderService"; const OrderServiceCluster = new ecs.Cluster(this, ecsClusterName, { vpc: serviceVpc, clusterName: ecsClusterName }); // Now ApplicationLoadBalancedFargateService just pick a randeom private subnet. // https://github.com/aws/aws-cdk/issues/8621 new ecs_patterns.ApplicationLoadBalancedFargateService(this, "FargateOfOrderService", { cluster: OrderServiceCluster, // Required cpu: 512, // Default is 256 desiredCount: 1, // Default is 1 taskImageOptions: { image: ecs.ContainerImage.fromRegistry("12345.dkr.ecr.us-east-1.amazonaws.com/comics:user-service"), taskRole: this.createEcsTaskRole(), executionRole: this.createEcsExecutionRole(), containerPort: 8080 }, memoryLimitMiB: 2048, // Default is 512 // creates a public-facing load balancer that we will be able to call // from curl or our web browser. This load balancer will forward calls // to our container on port 8080 running inside of our ECS service. publicLoadBalancer: true // Default is false }); } /** * This IAM role is the set of permissions provided to the ECS Service Team to execute ECS Tasks on your behalf. * It is NOT the permissions your application will have while executing. * https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_execution_IAM_role.html * @private */ private createEcsExecutionRole() : iam.IRole { const ecsExecutionRole = new iam.Role(this, 'EcsExecutionRole', { //assumedBy: new iam.ServicePrincipal(ecsTasksServicePrincipal), assumedBy: new iam.ServicePrincipal("ecs-tasks.amazonaws.com"), roleName: "EcsExecutionRole", }); ecsExecutionRole.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonEC2ContainerRegistryReadOnly')); ecsExecutionRole.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName('CloudWatchLogsFullAccess')); return ecsExecutionRole; } /** * Creates the IAM role (with all the required permissions) which will be used by the ECS tasks. * https://docs.aws.amazon.com/AmazonECS/latest/developerguide/instance_IAM_role.html * @private */ private createEcsTaskRole(): iam.IRole { const ecsTaskRole = new iam.Role(this, 'OrderServiceEcsTaskRole', { //assumedBy: new iam.ServicePrincipal(ecsTasksServicePrincipal), assumedBy: new iam.ServicePrincipal("ecs-tasks.amazonaws.com"), roleName: "OrderServiceEcsTaskRole", }); ecsTaskRole.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonEC2ContainerRegistryReadOnly')); ecsTaskRole.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName('CloudWatchLogsFullAccess')); ecsTaskRole.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonS3ReadOnlyAccess')); return ecsTaskRole; } }Este es un fragmento de código de VpcStack:
export class VpcStack extends Stack { readonly coreVpc : ec2.Vpc; constructor(scope: cdk.App, id: string) { super(scope, id); this.coreVpc = new ec2.Vpc(this, "CoreVpc", { cidr: '10.0.0.0/16', natGateways: 1, enableDnsHostnames: true, enableDnsSupport: true, maxAzs: 3, subnetConfiguration: [ { cidrMask: 28, name: 'Public', subnetType: ec2.SubnetType.PUBLIC, }, { cidrMask: 24, name: 'Private', subnetType: ec2.SubnetType.PRIVATE, } ] }); this.setupInterfaceVpcEndpoints(); } /** * Builds VPC endpoints to access AWS services without using NAT Gateway. * @private */ private setupInterfaceVpcEndpoints(): void { // Allow ECS to pull Docker images without using NAT Gateway // https://docs.aws.amazon.com/AmazonECR/latest/userguide/vpc-endpoints.html this.addInterfaceEndpoint("ECRDockerEndpoint", ec2.InterfaceVpcEndpointAwsService.ECR_DOCKER); this.addInterfaceEndpoint("ECREndpoint", ec2.InterfaceVpcEndpointAwsService.ECR); this.addInterfaceEndpoint("SecretManagerEndpoint", ec2.InterfaceVpcEndpointAwsService.SECRETS_MANAGER); this.addInterfaceEndpoint("CloudWatchEndpoint", ec2.InterfaceVpcEndpointAwsService.CLOUDWATCH); this.addInterfaceEndpoint("CloudWatchLogsEndpoint", ec2.InterfaceVpcEndpointAwsService.CLOUDWATCH_LOGS); this.addInterfaceEndpoint("CloudWatchEventsEndpoint", ec2.InterfaceVpcEndpointAwsService.CLOUDWATCH_EVENTS); this.addInterfaceEndpoint("SSMEndpoint", ec2.InterfaceVpcEndpointAwsService.SSM); } private addInterfaceEndpoint(name: string, awsService: ec2.InterfaceVpcEndpointAwsService): void { const endpoint: ec2.InterfaceVpcEndpoint = this.coreVpc.addInterfaceEndpoint(`${name}`, { service: awsService }); endpoint.connections.allowFrom(ec2.Peer.ipv4(this.coreVpc.vpcCidrBlock), endpoint.connections.defaultPort!); } }Tuve este problema después de traducir mi archivo de Cloudformation a un archivo de Terraform.
Después de luchar, descubrí que me faltaba una regla de salida en mi grupo de seguridad de Fargate. De hecho, AWS crea automáticamente una regla "PERMITIR TODO", pero terraform la desactiva. Debe agregar a su aws_security_group :
resource "aws_security_group" "example" { # ... other configuration ... egress = [ { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] ipv6_cidr_blocks = ["::/0"] } ] }Puedes consultar el documento aquí .
Vaya a Definiciones de tareas > Actualizar definición de tareas. En el menú desplegable Función de tarea, seleccione ecsTaskExecutionRole .
Debe modificar este ecsTaskExecutionRole en la configuración de IAM para incluir los siguientes permisos:
Luego cree su nueva definición de tarea y debería funcionar.
Referencia: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/specifying-sensitive-data-parameters.html
Si coloca las tareas en una subred privada, es posible que deba agregar reglas de entrada y salida para permitir el tráfico a la ACL asociada.
En la ecsTaskExecutionRole => ECS-SecretsManager-Permission policy asegúrese de que su secreto específico de la región se agregue con el nivel de acceso correcto. A veces, si está trabajando en una configuración de varias regiones con el secreto creado en una región y luego lo clonó en otra región , aún debe agregarlo a ecsTaskExecutionRole => ECS-SecretsManager-Permission para que sea accesible para su ECS regional.
Para mí, eran ARN secretos incorrectos a los que se hace referencia en mi rol de tarea.
Tuve que autoasignar una IP pública.
Para hacerlo desde la consola, al ejecutar la tarea,... 
... Tuve que seleccionar "HABILITADO" para "Asignar IP pública automáticamente".
El grupo de seguridad del servicio necesita acceso saliente en el puerto 443 (el acceso saliente en todos los puertos funcionará para esto). Sin esto, no puede acceder a Secrets Manager
para mí fue una combinación de no tener la política de lectura y escritura de secretsmanager adjunta a mi rol de IAM (gracias Jinkko); Y no tener una IP pública habilitada en la instancia informática (para acceder al repositorio de ECR)
Esto me ha quemado lo suficiente hoy que pensé en compartir mi experiencia, ya que difiere de la mayoría de las anteriores (la respuesta del empleado de AWS lo cubre técnicamente, pero no explica el problema).
Si todo lo siguiente es cierto:
Y en consecuencia, tiene puntos finales para todas las cosas, entonces lo siguiente también debe ser cierto:
Para colmo de males, la poca información de error que obtiene de Fargate en realidad no indica que tenga un problema de DNS y, naturalmente, sus CloudTrails tampoco mostrarán nada, ya que nada termina llegando a la API para comenzar. con.
Acabo de tener este problema y la razón por la que lo recibí fue porque olvidé agregar reglas de entrada y salida al grupo de seguridad asociado con mi servicio. (agregado entrante desde mi ALB y saliente *)
Si está utilizando una subred pública y selecciona "No asignar dirección pública" , este error puede ocurrir.
Lo mismo se aplica si tiene una subred privada y no tiene una puerta de enlace de Internet o una puerta de enlace NAT en su VPC. Necesita una ruta a Internet.
Este es el mismo comportamiento en todo el ecosistema de AWS. Sería genial si AWS pudiera mostrar un gran banner de advertencia en tales casos.
Si su Fargate se está ejecutando en una subred privada sin acceso a Internet, técnicamente dentro de su vpc ya debería tener un punto final dkr vpc en su lugar para que su Fargate (ver 1.3 e inferior) pueda llegar a ese punto final y hacer girar el contenedor. Para la versión 1.4 de Fargate, solo necesita un punto final adicional de api ecr.
https://aws.amazon.com/blogs/containers/aws-fargate-launches-platform-version-1-4/
Empleado de AWS aquí.
Lo que está viendo se debe a un cambio en el funcionamiento de las redes entre la versión 1.3.0 de la plataforma Fargate y la versión 1.4.0 de la plataforma Fargate. Como parte del cambio de usar Docker a usar containerd, también hicimos algunos cambios en el funcionamiento de las redes. En la versión 1.3.0 y anteriores, cada tarea de Fargate tenía dos interfaces de red:
Sin embargo, esta interfaz de red secundaria tenía algunas desventajas. Este tráfico secundario no apareció en sus registros de flujo de VPC. Además, aunque la mayor parte del tráfico permaneció en la VPC del cliente, la interfaz de red secundaria enviaba tráfico fuera de su VPC. Varios clientes se quejaron de que no tenían la capacidad de especificar controles de nivel de red en esta interfaz de red secundaria y a qué podía conectarse.
Para hacer que el modelo de redes sea menos confuso y dar a los clientes más control, cambiamos en la versión 1.4.0 de la plataforma Fargate para usar una sola interfaz de red y mantener todo el tráfico dentro de su VPC, incluso el tráfico de la plataforma Fargate. El tráfico de la plataforma Fargate para obtener la autenticación ECR y los secretos de tareas ahora utiliza la misma interfaz de red de tareas que el resto del tráfico de tareas, y puede observar este tráfico en los registros de flujo de VPC y controlar este tráfico mediante la tabla de enrutamiento en su propia VPC de AWS. .
Sin embargo, con esta mayor capacidad para observar y controlar la red de la plataforma Fargate, también se vuelve responsable de garantizar que realmente haya una ruta de red configurada en su VPC que permita que la tarea se comunique con ECR y AWS Secrets Manager.
Hay algunas maneras de resolver esto:
Puede leer más sobre este cambio en esta publicación de blog oficial, en la sección "La interfaz de red elástica de tareas (ENI) ahora ejecuta flujos de tráfico adicionales"
https://aws.amazon.com/blogs/containers/aws-fargate-launches-platform-version-1-4/
Dado que el agente de ECS en FARGATE versión 1.4.0 utiliza la tarea ENI para recuperar información, la solicitud al Secret Manager pasará por este eni.
Debe asegurarse de que el tráfico a la API de Secret Manager (secretsmanager.{region}.amazonaws.com) esté 'abierto':
si su tarea es privada, debe tener un punto final vpc (com.amazonaws.{región}.secretsmanager) o una puerta de enlace NAT y el grupo de seguridad de la tarea ENI debe permitir el tráfico saliente https.
si su tarea es pública, el grupo de seguridad debe permitir el tráfico de salida https al exterior (o cidrs públicos de AWS).
No estoy completamente seguro de su configuración, pero después de desactivar NAT-Gateways para ahorrar algo de dinero, recibí un mensaje de error muy similar en la plataforma aws-ecs-fargate-1.4.0:
Stopped reason: ResourceInitializationError: unable to pull secrets or registry auth: execution resource retrieval failed: unable to retrieve ecr registry auth: service call has been retried 1 time(s): RequestError: send request failed caused by: Post https://api.ecr....Resultó que tenía que crear puntos de conexión de la VPC para estos nombres de servicio:
Y tuve que cambiar a la plataforma aws-ecs-fargate-1.3.0. Después de la degradación, las imágenes de Docker se pudieron extraer de ECR y las implementaciones volvieron a tener éxito.
Si está utilizando el administrador de secretos sin NAT-Gateway, es posible que deba crear un Punto de enlace de la VPC para com.amazonaws.REGION.secretsmanager .
Resolví un problema similar al actualizar las reglas en el grupo de seguridad de ECS Service. A continuación, la configuración de las reglas.
Inbound Rules: * HTTP TCP 80 0.0.0.0/0 Outbound Rules: * All traffic All All 0.0.0.0/0Este error ocurre cuando el agente de Fargate no puede crear o iniciar los recursos necesarios para iniciar el contenedor o la tarea a la que pertenece. Este error solo ocurre si usa la versión 1.4 o posterior de la plataforma, probablemente porque la versión 1.4 usa Task ENI (que está en su VPC) en lugar de Fargate ENI (que está en AWS's VPC). Creo que esto podría deberse a alguna necesidad de permisos de IAM adicionales necesarios para extraer la imagen de ECR. ¿Estás usando algún enlace privado? En caso afirmativo, es posible que desee echar un vistazo a las políticas para el punto final de ECR.
Intentaré replicarlo, pero sugeriría abrir un ticket de soporte con AWS si puede, para que puedan observar más de cerca sus recursos y sugerir mejor.
Asegúrese de que la conectividad a Internet sea a través IGW o NAT y asegúrese de que la IP pública esté habilitada, si es IGW en la configuración de red de Fargate Task/Service.
{ "awsvpcConfiguration": { "subnets": ["string", ...], "securityGroups": ["string", ...], "assignPublicIp": "ENABLED"|"DISABLED" } }Estaba teniendo exactamente el mismo problema al usar Fargate como tipo de lanzamiento con la versión 1.4.0 de la plataforma. Al final, dado que estaba usando subredes públicas, todo lo que tenía que hacer era habilitar la asignación de ip pública a las tareas para permitir que la tarea tenga acceso a la red de salida para extraer la imagen.
Recibí la sugerencia para resolverlo cuando traté de crear el servicio usando la plataforma versión 1.3.0 y la creación de la tarea falló con un error similar pero afortunadamente documentado .