There is no need for loops, cursors or recursive CTEs... It's as easy as the following.
    WITH 
        cte_n1 (n) AS (SELECT 1 FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) n (n)),   -- 10
        cte_n2 (n) AS (SELECT 1 FROM cte_n1 a CROSS JOIN cte_n1 b),                             -- 100
        cte_Calendar (dt) AS (
            SELECT TOP (DATEDIFF(DAY, '2012-01-01', '2020-12-31') + 1)
                CONVERT(DATE, DATEADD(DAY, ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) - 1, '2012-01-01'))
            FROM
                cte_n2 a CROSS JOIN cte_n2 b                                                    -- 10,000
            )
    SELECT
        ID = DATEDIFF(DAY, '2012-01-01', c.dt) + 1,
        [Year] = YEAR(c.dt),
        [Month] = MONTH(c.dt),
        [Day] = DAY(c.dt)
    FROM
        cte_Calendar c;
GO
Or you can use it to populate a permanent table...
    IF OBJECT_ID('tempdb.dbo.YMD', 'U') IS NOT NULL 
    BEGIN DROP TABLE tempdb.dbo.YMD; END;
    GO
    
    CREATE TABLE tempdb.dbo.YMD (
            ID int NOT NULL IDENTITY(1,1)
                CONSTRAINT pk_YMD PRIMARY KEY CLUSTERED (ID),
            [Year] int NOT NULL,
            [Month] tinyint NOT NULL,
            [Day] tinyint NOT NULL 
        );
    GO
    
    --------------------------------------------------------------------------------------------------------
    WITH 
        cte_n1 (n) AS (SELECT 1 FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) n (n)),   -- 10
        cte_n2 (n) AS (SELECT 1 FROM cte_n1 a CROSS JOIN cte_n1 b),                             -- 100
        cte_Calendar (dt) AS (
            SELECT TOP (DATEDIFF(DAY, '2012-01-01', '2020-12-31') + 1)
                CONVERT(DATE, DATEADD(DAY, ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) - 1, '2012-01-01'))
            FROM
                cte_n2 a CROSS JOIN cte_n2 b                                                    -- 10,000
            )
    INSERT tempdb.dbo.YMD (Year, Month, Day)
    SELECT 
        [Year] = YEAR(c.dt),
        [Month] = MONTH(c.dt),
        [Day] = DAY(c.dt)
    FROM
        cte_Calendar c;
GO
    
    ------------------------------------------------------------------------------------------------------
    SELECT
        YMD.ID,
        YMD.Year,
        YMD.Month,
        YMD.Day
    FROM
        tempdb.dbo.YMD;
GO