# Sample code, software libraries, command line tools, proofs of concept, templates, or other related technology are provided as AWS Content or Third-Party Content under the AWS Customer Agreement, or the relevant written agreement between you and AWS (whichever applies). You should not use this AWS Content or Third-Party Content in your production accounts, or on production or other critical data. You are responsible for testing, securing, and optimizing the AWS Content or Third-Party Content, such as sample code, as appropriate for production grade use based on your specific quality control practices and standards. Deploying AWS Content or Third-Party Content may incur AWS charges for creating or using AWS chargeable resources, such as running Amazon EC2 instances or using Amazon S3 storage.
Description:  Arbitrum One full node serverless - Sepolia
Parameters:
  ParentChainBeaconURL:
    Type: String
    Description: Enter parent chain beacon endpoint to be used as --parent-chain.blob-client.beacon-url parameter
  ParentChainURL:
    Type: String
    Description: Enter parent chain endpoint to be used as --parent-chain.connection.url parameter
Resources:
  ArbitrumVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: arbitrum-vpc
  ArbitrumPublicSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref ArbitrumVPC
      AvailabilityZone: !Select [ 0, !GetAZs '' ]
      CidrBlock: 10.0.0.0/24
      Tags:
        - Key: Name
          Value: arbitrum-public-subnet
  ArbitrumPrivateSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref ArbitrumVPC
      AvailabilityZone: !Select [ 0, !GetAZs '' ]
      CidrBlock: 10.0.1.0/24
      Tags:
        - Key: Name
          Value: arbitrum-private-subnet
  ArbitrumInternetGateway:
    Type: 'AWS::EC2::InternetGateway'
    Properties:
      Tags:
      - Key: Name
        Value: arbitrum-IGW
  ArbitrumInternetGatewayAttachment:
    Type: 'AWS::EC2::VPCGatewayAttachment'
    Properties:
      VpcId: !Ref ArbitrumVPC
      InternetGatewayId: !Ref ArbitrumInternetGateway
  ArbitrumPublicRT: 
    Type: 'AWS::EC2::RouteTable'
    Properties:
      VpcId: !Ref ArbitrumVPC
      Tags:
      - Key: Name
        Value: arbitrum-public-rt
  ArbitrumPublicRTDefaultRoute:
    Type: AWS::EC2::Route
    DependsOn: "ArbitrumVPC"
    Properties:
      GatewayId: !Ref ArbitrumInternetGateway
      RouteTableId: !Ref ArbitrumPublicRT
      DestinationCidrBlock: "0.0.0.0/0"
  ArbitrumRTAssociationPublic:
    Type: 'AWS::EC2::SubnetRouteTableAssociation'
    Properties:
      SubnetId: !Ref ArbitrumPublicSubnet
      RouteTableId:
        Ref: ArbitrumPublicRT
  ArbitrumNATGatewayEIP:
    Type: 'AWS::EC2::EIP'
    Properties:
      Domain: vpc
      Tags:
      - Key: Name
        Value: arbitrum-natgateway-eip
  ArbitrumNATGateway:
    Type: 'AWS::EC2::NatGateway'
    Properties:
      AllocationId: !GetAtt 'ArbitrumNATGatewayEIP.AllocationId'
      SubnetId: !Ref ArbitrumPublicSubnet
      Tags:
      - Key: Name
        Value: arbitrum-natgateway
  ArbitrumPrivateRT: 
    Type: 'AWS::EC2::RouteTable'
    Properties:
      VpcId: !Ref ArbitrumVPC
      Tags:
      - Key: Name
        Value: arbitrum-private-rt
  Route:
    Type: 'AWS::EC2::Route'
    Properties:
      RouteTableId: !Ref ArbitrumPrivateRT
      DestinationCidrBlock: '0.0.0.0/0'
      NatGatewayId: !Ref ArbitrumNATGateway
  ArbitrumRTAssociationPrivate:
    Type: 'AWS::EC2::SubnetRouteTableAssociation'
    Properties:
      SubnetId: !Ref ArbitrumPrivateSubnet
      RouteTableId:
        Ref: ArbitrumPrivateRT
  ArbitrumVPCSG:
    Type: 'AWS::EC2::SecurityGroup'
    Properties:
      VpcId: !Ref ArbitrumVPC
      GroupDescription: Arbitrum VPN security group
      SecurityGroupEgress:
      - Description: Allow outbound TCP traffic
        IpProtocol: tcp
        FromPort: 0
        ToPort: 65535
        CidrIp: '0.0.0.0/0'
      Tags:
      - Key: Name
        Value: arbitrum-vpn-sg
  ArbitrumNodeSG:
    Type: 'AWS::EC2::SecurityGroup'
    Properties:
      VpcId: !Ref ArbitrumVPC
      GroupDescription: Arbitrum node security group
      SecurityGroupIngress: 
      - Description: Arbitrum RPC
        IpProtocol: tcp
        FromPort: 8547
        ToPort: 8547
        SourceSecurityGroupId: !Ref ArbitrumVPCSG
      SecurityGroupEgress:
      - Description: Allow outbound TCP traffic
        IpProtocol: tcp
        FromPort: 0
        ToPort: 65535
        CidrIp: '0.0.0.0/0'
      Tags:
      - Key: Name
        Value: arbitrum-node-sg
  ArbitrumEcsTaskExecutionRole:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement: 
        - Effect: Allow
          Principal:
            Service:
            - 'ecs-tasks.amazonaws.com'
          Action: 
          - 'sts:AssumeRole'
      Description: Role assumed by Arbitrum ECS task
      ManagedPolicyArns:
      - arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
      Policies:
      - PolicyName: ArbitrumCreateLogGroupPolicy
        PolicyDocument: 
          Version: "2012-10-17"
          Statement:
          - Effect: Allow
            Action: 
            - "logs:CreateLogGroup"
            Resource:
            - "arn:aws:logs:*:*:*"
  ArbitrumEcsServiceRole:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement: 
        - Effect: Allow
          Principal:
            Service:
            - 'ecs.amazonaws.com'
          Action: 
          - 'sts:AssumeRole'
      Description: Role assumed by Arbitrum ECS service
      ManagedPolicyArns:
      - arn:aws:iam::aws:policy/service-role/AmazonECSInfrastructureRolePolicyForVolumes
  ArbitrumECSCluster:
    Type: 'AWS::ECS::Cluster'
    Properties:
      CapacityProviders: 
      - FARGATE
      ClusterName: arbitrum-ecs-cluster
  ArbitrumTaskDefinition:
    Type: 'AWS::ECS::TaskDefinition'
    Properties:
      ContainerDefinitions: 
      - Command: 
        - !Sub "--parent-chain.blob-client.beacon-url=${ParentChainBeaconURL}"
        - !Sub "--parent-chain.connection.url=${ParentChainURL}"
        - "--init.url=https://snapshot.arbitrum.foundation/sepolia/nitro-pruned.tar"
        - "--chain.id=421614"
        - "--http.api=net,web3,eth,arb"
        - "--http.corsdomain=*"
        - "--http.addr=0.0.0.0"
        - "--http.vhosts=*"
        - "--init.download-path=/root/.arbitrum/"
        Cpu: 4096
        Essential: true
        Image: 'offchainlabs/nitro-node:v2.3.1-26fad6f'
        User: 'root'
        LogConfiguration: 
          LogDriver: awslogs
          Options:
            awslogs-create-group: true
            awslogs-group: /ecs/arbitrum-node
            awslogs-region: !Ref "AWS::Region"
            awslogs-stream-prefix: ecs
        Memory: 16384
        MemoryReservation: 16384
        MountPoints:
        - ContainerPath: '/root/.arbitrum'
          ReadOnly: false
          SourceVolume: arbitrum-volume
        Name: arbitrum-container
        PortMappings:
        - AppProtocol: http
          ContainerPort: 8547
          Name: arbitrum-8547-tcp
          Protocol: tcp
      Cpu: '4096'
      EphemeralStorage: 
        SizeInGiB: 21
      ExecutionRoleArn: !GetAtt 'ArbitrumEcsTaskExecutionRole.Arn'
      Family: 'arbitrum-node'
      Memory: '16384'
      NetworkMode: awsvpc
      RequiresCompatibilities: 
      - FARGATE
      RuntimePlatform: 
        CpuArchitecture: ARM64
        OperatingSystemFamily: LINUX
      Volumes: 
      - Name: arbitrum-volume
        ConfiguredAtLaunch: true
  ArbitrumECSService:
    Type: 'AWS::ECS::Service'       
    Properties:
      Cluster: !Ref ArbitrumECSCluster
      DesiredCount: 1
      DeploymentController:
        Type: ECS
      DeploymentConfiguration:
        DeploymentCircuitBreaker:
          Enable: true
          Rollback: true
        MinimumHealthyPercent: 0
        MaximumPercent: 100
      LaunchType: FARGATE
      NetworkConfiguration:
        AwsvpcConfiguration: 
          AssignPublicIp: DISABLED
          SecurityGroups: 
          - !Ref ArbitrumNodeSG
          Subnets:
          - !Ref ArbitrumPrivateSubnet
      PlatformVersion: LATEST
      ServiceName: arbitrum-node-service
      TaskDefinition: !Ref ArbitrumTaskDefinition
      VolumeConfigurations:
      - Name: arbitrum-volume
        ManagedEBSVolume: 
          FilesystemType: ext4
          Iops: 5000
          RoleArn: !GetAtt ArbitrumEcsServiceRole.Arn
          SizeInGiB: 1000
          VolumeType: gp3
          
