Timeout Issue Creating AWS ECS Fargate Service with Pulumi

35 Views Asked by At

Problem Description:

  • I am facing a timeout issue while creating an AWS ECS Fargate service using Pulumi. The service creation process seems to be timing out, and I'm seeking guidance on how to troubleshoot and resolve this issue.

Specifics of the Issue:

Timeout Error:

  • I am encountering a timeout error during the creation of the Fargate service. The error message mentions waiting for the service to reach the tfSTABLE state.

Configuration Details:

  • I have provided the VPC, subnets, security groups, and other necessary configurations.

import * as aws from "@pulumi/aws";
import * as awsx from "@pulumi/awsx";
import * as pulumi from "@pulumi/pulumi";
import { lambda } from "@pulumi/aws/types/output";

const config = new pulumi.Config();
const containerPort = config.getNumber("containerPort") || 80;
const cpu = config.getNumber("cpu") || 512;
const memory = config.getNumber("memory") || 1024;

// Create a new VPC for ECS Fargate
const vpc = new aws.ec2.Vpc("myVpc", {
    cidrBlock: "10.0.0.0/16",
    enableDnsHostnames: true,
    enableDnsSupport: true,
    tags: {
        Name: "network-vpc",
    },
});

// Create public subnets for the VPC
const publicSubnet1 = new aws.ec2.Subnet("publicSubnet1", {
    vpcId: vpc.id,
    cidrBlock: "10.0.1.0/24",
    availabilityZone: "us-west-1a",
    mapPublicIpOnLaunch: true,
    tags: {
        Name: "publicSubnet1",
    },
});

const publicSubnet2 = new aws.ec2.Subnet("publicSubnet2", {
    vpcId: vpc.id,
    cidrBlock: "10.0.2.0/24",
    availabilityZone: "us-west-1c",
    mapPublicIpOnLaunch: true,
    tags: {
        Name: "publicSubnet2",
    },
});

// Create an Internet Gateway for the VPC
const igw = new aws.ec2.InternetGateway("igw", {
    vpcId: vpc.id,
    tags: {
        Name: "network-vpc-igw",
    },
});

// Create a route table for public subnets with a default route to the Internet Gateway
const publicRouteTable = new aws.ec2.RouteTable("publicRouteTable", {
    vpcId: vpc.id,
    routes: [
        {
            cidrBlock: "0.0.0.0/0",
            gatewayId: igw.id,
        },
    ],
    tags: {
        Name: "publicRouteTable",
    },
});

// Associate public subnets with the route table
const publicSubnet1RouteTableAssociation = new aws.ec2.RouteTableAssociation("publicSubnet1RouteTableAssociation", {
    subnetId: publicSubnet1.id,
    routeTableId: publicRouteTable.id,
});

const publicSubnet2RouteTableAssociation = new aws.ec2.RouteTableAssociation("publicSubnet2RouteTableAssociation", {
    subnetId: publicSubnet2.id,
    routeTableId: publicRouteTable.id,
});

// Output the VPC and subnet IDs
export const vpcId = vpc.id;
export const publicSubnetIds = [publicSubnet1.id, publicSubnet2.id];

// Create a security group for Fargate containers
const securityGroup = new aws.ec2.SecurityGroup("laravel-security-group", {
    vpcId: vpc.id,
    ingress: [
        {
            protocol: "tcp",
            fromPort: 80,
            toPort: 80,
            cidrBlocks: ["0.0.0.0/0"],
        },
    ],
});

// Create MySQL RDS instance
const subnetGroup = new aws.rds.SubnetGroup("my-subnet-group", {
    subnetIds: publicSubnetIds,
    tags: {
        Name: "my-subnet-group",
    },
});

// Create a security group for the RDS instance
const rdsSecurityGroup = new aws.ec2.SecurityGroup("laravel-db-instance", {
    vpcId: vpc.id,
    description: "Allow inbound traffic",
    ingress: [
        { protocol: "tcp", fromPort: 3306, toPort: 3306, cidrBlocks: ["0.0.0.0/0"] },
    ],
    tags: {
        Name: "my-rds-sg",
    },
});

// Create a MySQL RDS instance
const rdsInstance = new aws.rds.Instance("my-rds-instance", {
    instanceClass: aws.rds.InstanceTypes.T3_Medium, // Choose the instance type that suits your needs
    engine: "mysql",
    engineVersion: "8.0",
    allocatedStorage: 20,
    dbName: "mydb",
    username: "admin",
    password: "mysecurepassword",
    vpcSecurityGroupIds: [rdsSecurityGroup.id],
    dbSubnetGroupName: subnetGroup.name,
    skipFinalSnapshot: true,
    tags: {
        Name: "my-mysql-instance",
    },
});

// Export the RDS instance endpoint
export const rdsInstanceEndpoint = rdsInstance.endpoint;

// An ECS cluster to deploy into
const cluster = new aws.ecs.Cluster("cluster", {});

const loadbalancer = new awsx.lb.ApplicationLoadBalancer("loadbalancer", {
    internal: false,
    subnetIds: publicSubnetIds,
    securityGroups: [securityGroup.id],
});

// An ECR repository to store our application's container image
const repo = new awsx.ecr.Repository("repo", {
    forceDelete: true,
});

// Build and publish our application's container image from ./app to the ECR repository
const adminImage = new awsx.ecr.Image("adminImage", {
    repositoryUrl: repo.url,
    context: "./admin",
    platform: "linux/amd64",
});

const ecsServiceRole = new aws.iam.Role("ecsServiceRole", {
    assumeRolePolicy: JSON.stringify({
        Version: "2012-10-17",
        Statement: [{
            Action: "sts:AssumeRole",
            Effect: "Allow",
            Principal: {
                Service: "ecs.amazonaws.com",
            },
        }],
    }),
});

// Attach the Amazon ECS service role policy to the IAM role
const ecsServiceRolePolicyAttachment = new aws.iam.RolePolicyAttachment("ecsServiceRolePolicyAttachment", {
    role: ecsServiceRole.name,
    policyArn: "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy",
});

// Create Fargate service
new awsx.ecs.FargateService('admin-service', {
    cluster: cluster.arn,
    assignPublicIp: true,
    enableExecuteCommand: true,
    taskDefinitionArgs: {
        containers: {
            app: {
                name: 'app',
                image: adminImage.imageUri,
                cpu: cpu,
                memory: memory,
                essential: true,
                linuxParameters: {
                    initProcessEnabled: true
                },
                readonlyRootFilesystem: false,
                portMappings: [{
                    containerPort: containerPort,
                    hostPort: containerPort,
                    targetGroup: loadbalancer.defaultTargetGroup,
                }],
            }
        },
    },
});


Troubleshooting Steps Taken:

  • I have already attempted to increase the waitForSteadyStateTimeoutSeconds, but the issue persists.
0

There are 0 best solutions below