Vu25`sQVvRlvaav=5--5lL2iMTa?-f)bXLo>}0?5G*h8
zA3)~xH&{^4eCzt644u|nX)QKcZom!P?{y#j$z6Z2QeOK9(Ovfi`N}%-AAoq>I-5HyLPmbRoC!Ze&Uz3NAe~T;g3V=O_l4U3LiAM^@5L~8;?NWUGRf7R@)<+D?
zWvwQN*_#!E9ClCssskLquxDeP`N4mm&@8Fc_B*SWfs~2QH+abY0eX(Qr?94r=ud5~
z-aw$Ty?@Dnzwht~49PKLljk1@zDsMlOUh_*dknh`_&Y8H`~C{$r1|B+wfG#jnSEkn
za2wz-MQ|{;XD9DDwX?9-s;9o5LHTXqv$L8o79Ee`>FSSZ@wH!efvq!p?d{LgKumkh
zUtTkkPekmR<8dWaJpMLfs3%tIduqgLOp?IVad~U~ygK&o9S7+*5k{(rt3#dYVWz@t
zpX~>eFsXK#@C`P~#aCbH!=r6VZ^v8j{|HXRuB`c{<&LYF`UJD(0oyC-xszMIms%=J
z)-3B(t$grq6pv@g-`u3T2pGAh-|r~Vs~O+B601cD>gSHN(5FZu{Lb@E5L+F6fw@s00D;UJ}+G
zX&Wu@9akpHDzw)X_Ovys)c*sxZAjiT*U&fRYxVTMocks5OeT8Jj=J+=e%58-*r4MM
z>B}}Ws$s(z=oLhNAHGl+C)5((a(;6BQ2!IEf8{Go%pv;o%6peF=r8SY@}KR}9T}T(
z-w~kznV}q5vB#~I%h!R0SrGR_fAcH$!l9a#^rtL*6UhB?qI810IAv-4L%YJANisdp
zelx4zPj8acCj^nJsvTF`-_voKdgT)He1<))bktnXNYk{ePv{Z8(7U+1-&Hf!)yDhJ
z7k^8MEr?qnKN&?-hI;&p3h)i!FnbhN>V2Ck@$A!kME_
zUu>PEuNCwb{RnnhsvaK^qb!k9hrg{=H@@AHowJghR kBTht=0{Z8#vfEWnrquy6aY~{kU&4R{e25^8!S=``{
StzXRGkSBgkYy1#QD2W-*WI9VI=QAYbmm>G3BBr` zh+MU_*;b(J!)C45nm8)Prh#&fh}-xU`>WY1xvtVF4+rhZHCMD%$x5uLZ)&2`Z@$DP z;`or)_eTlMQhj6|6Mjwo*(35tfAX9fo_~Zf6-%qLV;8r>WcRL8`Q_F-C9t-U%V{Ea zjVf_ZKhZ{fSY)NuC32)R6X#LZ)J`*T@}GLdEk5@ooG>Qg`*DZHm$E>^6n+B%I@q-K zeoRfCuw7OcPPr!x(Bmj#^FAgJ*-%TluH_d)6DB`s9ue{0f>xbJpAfr~R8sE&V9CjJ zNhVeI4wbbc%2u6i!$@{L^n)@H@h(N7V7@@Es^6*135Du$Bn?;l7HjovL-k=uY|{0$ zi*lG0ez&gyZE=F`b|pThs|BxXQUfDt8VE79$W(-w(OIdWcF!~L+c{!GYj`l-AN1_T zPdKv{4ZC`XKaHun7WaiX8v2<4t(y=~TPx#|PCDW1YBBEAy3sEG>#*QwUI}S0BbstN zKt>720Nf;Ok_1X0ZWs)qdYRC3leRK2GrCP!GPyoO%+rLc?v%(Z*T3GNi63Rk@k1iN zL<7f;xh)B$L>YfACu}-8%KMlKYnUG3Cw*>HfmnQG+!!qK`w}l?^jpiN)`2vAY4MR~ z)9>e1rC>L`igm4;jb)_}xv3@{HZ}3tfE-<#r=xOYpCUDfWXyR6Lt1;3cO%JdBK`sH zyG-sm(P>A)+yNty&!wB`KnYYb8L3VFSgWFX$r;o6)6HxEuwvp8H2pARgY9Ssvq?s7)lAAvJTJb> z7Vu+a)>vq+u%dp^xRwQ;@S5pF_{+Qzn`6tODYdUIZ9I&!w)iLssgmAwTj?ZzigT2+ zFfHdzbz-|}*&z 4awKd9? zVJ-G4x1UJz(x5-O?DbpbK|#x6>PJc`eU&!P eH^qTb1;Sy3nTF-?J^%ZFHftnJpl1n)g8`EJv{EO}~G^HT7YJ8h(CD+Qz%iU^B7Cf=i}(A4!sqYZ`5r^TU;V zUy&!g$UM_HC$o`#KQa;XI#8+!Ge4JXG_|v1{i@Af2I=k-?Y%16{1F#= ^)`vbEkONfcs5%<#?U32Um=VbE8A43=e+mLT$|^BTVb$q|wQ%{%~Y zHrXm%d I0%?8_><|WwqtPzev{)#1z z|CrR`sizH6X4p8PVYwgDc(!X^*=Xe71n%^@^d3rFEVBtUSL|+%_y8siP$j^-jB!iB z2_kysWfu6H+&){=Ey3J6f%}=l_X&UUo`t$k>}Y?ut-k2IQ}!9pUdDLR8t;pjYd;F7 zX^8m;_N753A6LdSl%?1@^WA!^=F8S5T`I<5&X4!}wvxZS2&_B@TmNxfS|9c0kQuNS zxS1{Cx2>e3;&y#O{vkZiISA=EXRe~7lQ-qA$kZbkb*#q`%W{p6 6Zb?9qd zN$EO8Y7H7FI7o!G ^@3#ruPx%rY=yfq!7aNzr }Rp2YU_7q?KLjKsmAnD{R>C hkQk!aHi`6v1D|L(m^q z(_n8l_27D|pSfkNO-?t8iHr`>Bs)K9Z)Q@KIovswCr5R!YZqi5ilwKY^*cK=zpTE= z0Qq|u5yp*>X-@jutXb e`&5(lP$AyZ_{eN!=Ri{Eg-N|5 zc(*56K|{WV^XbBY?q|5VOHBL#cfm`~Y@KG(aqUOJ;fd&P7pbFSVM?Z0bX*;OYd9Mj z%aKW~xdD6q{x7<_dydT!eKYS6L!6c+9QOYJ6t%oXm$cH`K{*{Xjw@R(tzio)jFEp< zxJu`@2dn%Kth?TPJE<-fHQ+EyIJz~4!dCnJwrxmad{7e`X&kTYy&CB&y?xfnHp7Pa z=H;JK{*;MG(%)Q3&{G+|i>0X{4IGyi()E>C7*YwY9e-H%v7kCp-2UJjkPa;H)HH&b zzoWJlsI~ABjE?Lt=Zj`n9>Bw^lkbx&m)ou~XcfC{60@G`nn~`D+2O%TvVgnf{AyH> zfij(8`juBA7GZ9i*0SHrT{4{9fY3byq?;K^CSWfj`9_+$;pw+S6RtGEo Ycnge_^Dz+%-*` zTj0XsP -r?n0!VO9a TFiG}WzSEGZ_B%;u-AV*F5!2r`T zm5}z6gf??Sn@f#nQ~5M&P+GAlOR^-QGmZy%pvr_DsY(fLi*t)*r@Lhv(0KWq`a4iS z^lZZ!V@X;8uNMbb&{XgNVrE7ks5$>RJH(8Qy=9)5zy;yA#EoCh-`&_48=?4PD^?n> zG)}9v^|hqy%6>Adx?C$ksq5-E%#A9Y!1&&H>I+| &}CyVPQ`)` zmfNMCRPOn?y{f!LWc7nne3a!AEZ9b4ay=*^#; D}yU z6$@f{Pc# OR!0ZG`%7^CyhobZMEW6Oz)~{ZSgG-){(7#hdYoUb4}UNA>Mx zk*_Iam2D-xKAHI>rpiD|KSH;UtRM GIs&>|&C7MTI a5Yl$zRaxqzwL5 zVw2f>t)Tr$j4mHKy~)Wxz$#n7?E#eY ht#^!8>qYPZp5~|Geud$2xF6~10G z7o^F_`wVU8Wn(-6j~<|H8LTb#+;^Uc7-&ztR2&Jx8w$r%F14ZVgH9DqZLyjh9lqD2 zi=h5$eu?Ygv1DA6Iq~e4hIAU$*J4#aYgW8J=T?$)=8V6;YX4!WPb4#8_EP!SNE1nA z9 7T(oB{Z;(T*s7xyTGGa;`%xvbe>|V-HZWA@7u5t0x*Q3wK_RG5)zWfO-#wf- z{%jPnQgXbOx;x5H;YieWh9~X2(sBQ&`j|1w_b~2;@+#p$5`kNY(Q`iY6}o_kMJMie z?D&%{@7XD%&*b?dJ758Cqy{CpDWY;X$mYk*Ng3)_ tS`wyU9^NIQs#3a`&9rtn8`RRMzDbawHA~>&;UoZvV-+hPnO?bWd z;S)?p^I<}8quFdPuO 4MleuDNGMymteXFb!$nz10=NWR2 zt)En?^eSz@ngcAGL n49tC3QG5+r!4TQQ(TpDJ{C%)yOWq9v fIpe0N4rK*YX64JAuM$sQKg}cP z8MZ;UQZ)8_M{X3^bI6hLseULj`p)|$io?oW)vBygc}aRWyvn&x5@$!;<0t^^#*H+6 z7m&Bm@JnEDH^?l!bMVmyf#M-VXB%6CLz2leD{ZV^yUryoWsE=H!Et?PR+78>%Az$K z{n`sQG*;t+lb+VTu=2gbFvLhfJDfmE?pcV!w>#GvW_A7$gO2W|=JXZ!62wx9LGH5{ z!@28hbZJ^Cs}^^6;31JE^siS`IPeXBI!fzXx{jj>vSUK6!n&nvNo!x^&Lm^d3>}1{ zljatPo%MYgX?a~qx99X2(}~&IX_r!C5te=hTV(A*s|Q2TN)rLWou&&J;Gkqw~uv zT2fBJv`lq`lx`GIjov=@PUM10i5GeXVHLx2q#U{*J9oN`t9MVozCdRBTzdx3CVhI{ z^=dbyT1GD)b$aBRN}ZS`{vk*>Sv^)M`uEXLf=vIb#80QvG!@OTn3<=_uc;2HRH_78 zN1Noogp_-7a$*b6KlYQW^PCBihs+r^^MiFd%vmwb6EZ4T!9-&1m*MlqRiXZ 5tC))=^Mfi#?NX^k+Egu|`r6g4pHgx<*P3D3R zZ#7N}yWhShw?csy qm5sSjPJ?!uKNrJ?uG`7k!AkI)#XdZm60sU2dS`rXg%ZuW5 z`RuB^gb%(rs #XG< zx!% 4_rq{voTQBxI=iUJ zmsVJXwU(I0HtI^(C1zDSEXG Ugd6Y_g;!w1dRC{!+cE9EtNFrQWDBnKZa>? 1p3Rjv_eFWJyD{UJadazS4QA_7o`V%P=GS$Ex{dptI7&D6wb9UL;&Eg8B90;@ z)|#48zrWvWz8QpQ^cmHwtN`r>$!5|qwdXB~Y`c%?YJ9~KYjrgm>T>!!{q=jD-<|z* zuvN?I&d&eaWj}ImwQygMK?t#vOYzt#;9nUUWqM`~vChmM(k$Xh%X`WiS*K&3ea|1O zp?;TQ6I8DoJrM4XEjRM+=XN8?R>c7AgT_;qv3KnFUS}Sx-B)uoF-?4kjA<{dH%c4y z^hBIslQ#|ZT7Nu%i_2y;%q;a`Z-owq1+3dl2U{jE2Uri~v~ Io-3uX@%!p0jFVqB$L@92lbjOg`qZ(HRKc%K{RcB;V@q`XWu z6?39T>x!?GzEQ%iBFq(9H%un!My2akOxbzfTFf_#HeN198R`)CZ8DtwL~=>hn!YD# z7!@D$w2+C$m{gOw3ez^nJ!01EOM7yU79?ZRsyGb-JHL8p0G~f`A)q;&GJ;UP{8yWI zHM8Nns} r%V5&4VxJ+!g=U5w-NZ=|IxwZ15wKSyP8H;Bf|wYeEi6ST<~jP^_~LcYsA zq*KZm?6!Auy{R 2rgB%M2e1%s}85_j(wT!vqqm8?vR2s5jxN_K|mtx#&qSiuK z4zltqJ17oYLF8Ms$?p7KXUB+f`@ W z$Iwc1l^RTjH=E_rB52jTwV_RbKp?c2riEQ!_>);JGX5atG*U-2#$h3SX8X-1$R4%` zXF=N+tPi}OmYy_eNuzR=+qs7r(G1<;?H=ofQP~hA zTOS&~6QU)JrxrtutJbR3ja=ue=;z^5zIFIUgDPUeJJ
Ytp0jtf_@kB zPPO}c*G1cn3f_a#w?!I%Lqns_!@5w^lQ4>JOS)XbiUR``y9#Kn@*@JctqNHO=obnf zmE%N3UdR8jvCFe7Aiowih3_$DTm_V_@$#P}S(w5p } z_-j{f7Ha3}envI7U+%I*r{sbS5Zb$z%?|rIA-ultM&)piP4vn-+5^I|NW`X%wQB8F zKP7N>@ya)N$~+ieAwN4}0qZ>Jl+E{3AdK3HX;!w+vaVR=%wiLK=|5BJrGCzuLJlPV zGSt_Da-Ou7(R@t_KdI8UX>Gp?ltn)8UogLU^#X#$wHEvQ*hbd9StX+F6@H!P$A+#4 z6NeWI%q79RR~CeME&f=)76tfBV&*vAjlAU{noG^jBx#5v`*xHkxd69pc!tf3s98sn z(kulOD7?9sHSx0Jx{OCZyqrldw@b6s%qw!~)Pf%b)4OU|%`*vEyebkRJSZm(nEN)( z@nLkzvw}P>*Q!}HxoL I;iu$qSgxzFc{1eY$KEJwlUGHgeRplsD&74&`E@)|<_d zHRl{y`|`s)$ICt?kp#BUusQz?c06gEJq{DHmae42qk2(M7N{J<$wXwuq*v?TbhpIe zBo0G?MF@6>L}r_iLDFokm#s8A=VrF^%c2KG;^QYadsS5ClB6xvq-!J(rmM0>(5s<4 z7T1oYAT|o2twDF|qoiFg4vIA+NS2QEM?H60Q#9=>X_|y~xgOe`W3&3SZvqtCO_sUA z(s-RbbMWNITn$w(mItn@#bb!Op{j43JUQb6_PF11 vsAQ+k!^6(*N=mA60>BU)pIQawqjES?0F$Iou*mYAFJO~cbTWP`;prHFdax8 zYE2z{_;Oya> zF-?9$}PZtJbTSpq>DRAXRQ6-sij;HoZn> zvhBDx<}S)iqz~`X*vU9Hlv^T{37j&%5_t)1__uKv1lZaok%R LdU4F0C&x`O2o|)Hgo#?fb>4Y|TPa;4Ol|!zxG(FO&_{ zcx5A&@e@gRt=7T`1eDruE(rW}6yYP2HRUxkz9NaTRTvYS{~!T `a@#dWBbUr*HzC=m|qe9uxj1MH+%?z z9a?bn`67zyoicSkIQqV)LDHc SOgXUa2T*=BW4Bf#!-5rRuZYFyM|E%} zG {0Xo8;gqP=$0gJrJ85#jsyOLT7R56j zx@+WklBh)66*`SeY}jC^fur-GAGVV$V-~pkt#3FYIeFEGMziuvaF%nu9q+bs8%;Dh zB~|&9%d<-OZN$RN+w*fT?e2-gx>BmVRyFIU;H-<1f{w~uy^vHNA9?=g1}NG(IzWW| z!nGSNlO*qnn&196tVNDwRF14bO4{1OLgV8#|Ed^ZMVSM^2OHPom<}HU!O8VU25_%O zhObcF5*ePf8~9r`@O3$@cf0lmAFGh(b^lKQVGy40OMKEd<5<+CIXk9SsOxR?>sb)4 zMo&tD@4_uR4Y&=CD>C0!HqwCX2(G72@f-maT<86& h&*U4{JixAv{~c^n$!L=SIpc9GY&dcSY&6`tb0h3m`H0~QQ+`c@6zq9uG} zwtLjtgUCi0aan5#GXsj&jVPsdH5-M*4J3IB#Vv%U2ii#=TIg(}fuPwi80<)@cNWMc zVh0_KY3& e5LXL{v95mv}=Dy~s4F$D2zICfh3CNAovc z1!u{nO%7Nl SQCVv-T-^m^QmxlDrGH~>v2F<)N#N(DaZWAj(ClTT*72Q;0U4`t z>Kbge<_3sv&MP`utfVZVlOW?Y97$%gs~1y_derhOUEE0p=9>!S+oJM##X7}jupVNL zdSD9JI)#8lMG8-T^>*G{R*1gU#(5a1b!Ezwt_sI6(cS8EljROQt3OfGS~WYP8;7NK zk?U4g5;~Po4>-kV+~3*W+=pdV40?C1BU)-&EehthLzL5XIrQl^j+Lm|{IfP(3{_oL z+9hD=k7~zxN@oLsU1|`k@1#T3ofNv9k}lOhl~qNMv34e^Y4-}`0tIY5VW2xlKGl?x zgSCdt+snjN#yQ0 8|tOq`|opB2^#1eTt){TrNF_DfdS*XSXQRX(Td^-fT*+L6@ z3c)&L)^iL4k?mWSnt_AmX8_Y~b!cRp?uI_K%?g!Pja?AaOls 6OlUZKC?c#`TQM8un4DGkk~PI) zz3k+ZkPSUG1`G27O;qVhTaBiX*Z%-&6tFRw1~H6RCv$REW(eOcR(qKxJxCQ3h69=@ zVfi;E#-^WX_Nhkhd*Za^)7A%4haRG_bo-eikQ8hYR PFydl@#Ht8jac3%YPeMo|S_vid>OR5;G`Knqh`O zK_HP+PMlyj?jh;(HzR{q)d~!S;;E#;8 dh-LNpImoE2 zl1s)LNFQ3Ma?0n9Mr&uo;ueqxWl%k9X(bAGNVTCa*{`8OBtpyB)hXUkcDCS8t#`p~ zq=yM0BoA81)Gc9kAb@L;Ro78-+~j_Ia!pj8LZcuW*Sm%|Ps^I1(X6Kjp{~kuPg2uX zGoze4g(H(!THE(|UrI;Qm0U35twgRPD#It%w4B%35r$!M 64LzFr}k(3eCE*#n9rvhvq%I#kZQB(x!!Q$)UD6%IVE zaa#t=7wB{AP)}+XzG#hAu*#{b%M$HDNOdX6%`e$UTv6o#+OPM0P!+9iS_zfC4RtH1 zeXCC~`GX_1ae4GLdd}>lg(r%tw6Cd1hTt?e3{;Q_rX$GBjqUl>`{ PfAd`+Op<5|_z+@+ZZngbyP|1{d skK* zV`(MHJx?D>==6}bNJ%(2;M1uqM#!Dsg&Um|T1r_y?r BU{XzA_wj$9l`S zf7Y^(H2yMLD!hZt+-lO?s>WA}&17bC!Kj=_8*eq#>8V(8m5l|H&X8pBSC-K>f?I>l zV@JL`8o0Mjv}U4keF>80EnURERs&X1fU9RUbWCP6@D~6aQiE{ZorJed(Qr8x1kx2^ zrmn>zCRVE4!REeHQj1sAI+=0 P7Vu08&iW&75(}aUmYn zl2|2871KsIsHnM-Yg2k?AWSGDr9&p08>a`7GAj}9OA<+`;?^A(ocdNi#-iDZDfBH{ z*{Vo)bgAbNDA=qsj`f!MqweE8_Nvcx(mzhMN|fHR8`oAo=|OG7twKRjj`d{}I^fbc z85Oi;(3_OVZ1N3RwBYkr;fWY$ib-M-@}N-aC!o2DOConX(_}`Fe4?|=m^n3m3Bggw ztR)7uMD-#to`hA~ZLxEnl~&?>oC8$N(*ufplA0{&8&C`P8G${;K>Eb0Kxf_QSjO+x zt4lF<&p4tuWz;Ne&3+|Q{pz4@nOm(=4ngZrCnGtn<4Q3dx*G860#E~B8oL~^k(`R= z;%%*(zYFfgVN#8?LcN)#BO{#gNeuo}gJ~G5kM~V7IYx1wl^mBvZgfk06mB@F7V0Mc z0h3(&OY-n)1E@S*D (G6bK`zr2K2Me+ewH D1L;=2&$>)i*!0hr zJ$RU)FgnXx05$Q8J{l&06oBaW2;hshj|!l2*tlhU%AQ`97ju(=L1(x-d2NQqol zJhwO_nwZEQF;MC1BwvDMmz?l=(mV=WjPcsC;G9Px9Ah 2hdx(gZ(_By0T+=> zlW35PQZv4K@lkbtO*Ee2a#viCMOcLK%~l}e WL2Z2Hzk!VZW(DynrGR${fvvoJj>H5n9+r+x@It1()!T-Qr#D0?EQ z7&xS<=Y*#wtDdyey3lAl)!TbRB9aa&nCp)9vtkq{?=#Y~t3Ff{DM*hCVDzQIb;vbt z?G?W7BB~hzRK@cnFi9FV>rV4`j #R!{?Ioujzxd%0R*rjpr7TS-XsY@0W3C?M+ zFjo{FYIv?Zw$C+MftoCy fbhm~EKG z4#SFq<^vOPnw2QF9KA?z3E (S9J_h%RV8sWSZLGIt2Ax6^HLeX>(-Ob z%}j29>Mgub(fp=Ql#B&EYfj5jSy#+==hD3IBpm0ZY*=5EKsYA3s^R%px;E@}8l=YZ z-IN|paq&VTnX-G v6*hH4%L4t8y zH=ZJp9(XmgXW|boFDnO{%DpK|;n)pLS648 f z$Tf#I%QFB?R1%u8NY|R(3}Lv n_0(7Y(Q=tR*YZ>`c=wS6^yn*r<#qV=jm4NKZ>(o@79pi zO%0Ib=7dKlAx%txGYpK@t*lYxe1fV{ j8W z#9)wV#N<;}l-A%8{oz_l$|KEZ54 YTTDwS0r&+Ad!q3MrI?ESh{JwM3CvF^B9mgH5EI(H1(~mZ3Y6C zfk5j($72GJ4zwPWFG@lXj%v-RUBDAn&q_>?K@>H81EJKzZyTb51xGcMNOCYes-~Yb zhCjY)S>$t^v91QC8Ey!-ZZ>0URF?&0TrkP3*d4R?jaYU&dek`UaOzQ&6 S%UzIHLS&6_!+>efNxnb{6;7WKB0+;%I4c(&&XOx7kuq> **API Keys** in the Scaleway Console + - Create a new API key + - Note down the **Access Key** and **Secret Key** + - Copy your **Project ID** from the project settings + - Give permissions for **BlockStorageFullAccess**, **ProjectReadOnly**, **InstancesFullAccess** as a starting point + +## Architecture + +This template creates the following resources for each workspace: + +### Persistent Resources + +- **Block Volume**: Mounted as user's home directory (preserves all data, configs, and projects) + +### Ephemeral Resources (destroyed when workspace stops) + +- **Scaleway Instance**: Virtual machine created fresh on each workspace start +- **IPv4 Address**: Routed IPv4 address assigned dynamically +- **IPv6 Address**: Routed IPv6 address assigned dynamically +- **Cloud-init Configuration**: Automated setup of the Coder agent and persistent storage mounting + +## Configuration Options + +### Region Selection + +Choose from three available regions: + +- **France - Paris (fr-par)**: Default, lowest latency for European users +- **Netherlands - Amsterdam (nl-ams)**: Alternative European location +- **Poland - Warsaw (pl-waw)**: Eastern European option + +### Instance Types + +The template supports a comprehensive range of Scaleway instance types: + +#### Development Instances + +- **STARDUST1-S**: 1 CPU, 1GB RAM - Basic development +- **DEV1-S/M/L/XL**: 2-4 CPUs, 2-12GB RAM - Standard development + +#### Production Instances + +- **ENT1 Series**: 2-96 CPUs, 8-384GB RAM - Enterprise workloads +- **GP1 Series**: 4-48 CPUs, 16-256GB RAM - General purpose +- **PRO2 Series**: 2-32 CPUs, 8-128GB RAM - Professional workloads + +#### Specialized Instances + +- **L4 Series**: GPU-enabled instances for AI/ML workloads +- **COPARM1 Series**: ARM64 architecture for specific use cases + +### Operating System Options + +- **Debian 13 (Trixie)**: Latest Debian release +- **Debian 12 (Bookworm)**: Stable Debian LTS +- **Ubuntu 24.04 (Noble)**: Latest Ubuntu LTS +- **Fedora 41**: Cutting-edge features and packages + +### Storage Configuration + +- **Home Directory Size**: 10-500GB adjustable via slider (your entire home directory) +- **IOPS**: 5,000 or 15,000 IOPS options for performance tuning + +## Template Components + +### Included Tools + +- **VS Code Server**: Browser-based IDE with full extension support +- **System Monitoring**: CPU, RAM, and disk usage metrics +- **Dotfiles Support**: Automatic dotfiles synchronization on workspace start +- **Custom Environment Variables**: Pre-configured welcome message + +### Cloud-init Setup + +The template uses cloud-init for: + +- Automatic Coder agent installation and configuration +- User account setup with proper permissions +- Persistent home directory mounting (automatic disk partitioning and filesystem creation) +- Development tools initialization + +## Usage + +### Creating a Workspace + +1. **Select Template**: Choose "Scaleway Instance" from your Coder templates +2. **Configure Region**: Pick your preferred Scaleway region +3. **Choose Instance**: Select instance type based on your performance needs +4. **Select OS**: Pick your preferred operating system +5. **Set Home Directory Size**: Adjust storage size (10-500GB) for your persistent home directory +6. **Create**: Launch your workspace + +### Managing Costs + +- **VM instances are destroyed** when workspace stops (zero compute costs when not in use) +- **IP addresses are released** when workspace stops (no static IP charges) +- **Home directory persists** on dedicated block volume (small storage cost only) +- **Fresh OS** on each workspace start with persistent user data +- Choose appropriate instance sizes for your workload requirements + +## Customization + +### Extending the Template + +You can customize this template by: + +1. **Adding Software**: Modify cloud-init scripts to install additional tools +2. **Custom Modules**: Include additional Coder modules from the registry +3. **Network Configuration**: Adjust security groups or network settings +4. **Startup Scripts**: Add custom initialization logic + +## Maintenance + +### Updating Instance Types + +To update the available instance types, regenerate the `scaleway-config.json` file: + +```bash +scw instance server-type list -o json | jq 'map({name, cpu, gpu, ram, arch})' > scaleway-config.json.json +``` + +This pulls the latest instance types from Scaleway and formats them for use in the template. + +## References + +- [Scaleway Documentation](https://www.scaleway.com/en/docs/) +- [Scaleway Instance Types](https://www.scaleway.com/en/pricing/#instances) +- [Coder Templates Documentation](https://coder.com/docs/templates) +- [Terraform Scaleway Provider](https://registry.terraform.io/providers/scaleway/scaleway/latest/docs) diff --git a/registry/mossylion/templates/scaleway-instance/cloud-init/cloud-config.yaml.tftpl b/registry/mossylion/templates/scaleway-instance/cloud-init/cloud-config.yaml.tftpl new file mode 100644 index 000000000..3aeb35ce0 --- /dev/null +++ b/registry/mossylion/templates/scaleway-instance/cloud-init/cloud-config.yaml.tftpl @@ -0,0 +1,35 @@ +#cloud-config +cloud_final_modules: + - [scripts-user, always] +hostname: ${hostname} +users: + - name: ${linux_user} + sudo: ALL=(ALL) NOPASSWD:ALL + shell: /bin/bash + +# Setup persistent storage disk +disk_setup: + /dev/sdb: + table_type: gpt + layout: true + overwrite: false + +fs_setup: + - label: persistent-home + filesystem: ext4 + device: /dev/sdb1 + partition: auto + +mounts: + - ["/dev/sdb1", "/home/${linux_user}", "ext4", "defaults", "0", "2"] + +# Fix ownership after mounting +runcmd: + - chown -R ${linux_user}:${linux_user} /home/${linux_user} + - chmod 755 /home/${linux_user} + +# Automatically grow the partition +growpart: + mode: auto + devices: ['/'] + ignore_growroot_disabled: false diff --git a/registry/mossylion/templates/scaleway-instance/cloud-init/userdata.sh.tftpl b/registry/mossylion/templates/scaleway-instance/cloud-init/userdata.sh.tftpl new file mode 100644 index 000000000..2070bc0a7 --- /dev/null +++ b/registry/mossylion/templates/scaleway-instance/cloud-init/userdata.sh.tftpl @@ -0,0 +1,2 @@ +#!/bin/bash +sudo -u '${linux_user}' CODER_AGENT_TOKEN=${coder_agent_token} sh -c '${init_script}' diff --git a/registry/mossylion/templates/scaleway-instance/main.tf b/registry/mossylion/templates/scaleway-instance/main.tf new file mode 100644 index 000000000..041bf123e --- /dev/null +++ b/registry/mossylion/templates/scaleway-instance/main.tf @@ -0,0 +1,271 @@ + +terraform { + required_providers { + coder = { + source = "coder/coder" + version = "~> 2" + } + scaleway = { + source = "scaleway/scaleway" + version = "~> 2" + } + cloudinit = { + source = "hashicorp/cloudinit" + version = "~> 2" + } + } + required_version = ">= 1.0" +} + +provider "scaleway" { + access_key = var.access_key + secret_key = var.secret_key + region = data.coder_parameter.region.value +} + +locals { + hostname = lower(data.coder_workspace.me.name) + linux_user = "coder" +} + +data "cloudinit_config" "user_data" { + gzip = false + base64_encode = false + + boundary = "//" + + part { + filename = "cloud-config.yaml" + content_type = "text/cloud-config" + + content = templatefile("${path.module}/cloud-init/cloud-config.yaml.tftpl", { + hostname = local.hostname + linux_user = local.linux_user + }) + } + + part { + filename = "userdata.sh" + content_type = "text/x-shellscript" + + content = templatefile("${path.module}/cloud-init/userdata.sh.tftpl", { + linux_user = local.linux_user + init_script = coder_agent.main.init_script + coder_agent_token = coder_agent.main.token + }) + } +} +data "coder_provisioner" "me" {} + +data "coder_workspace" "me" {} + +resource "coder_agent" "main" { + arch = data.coder_provisioner.me.arch + os = data.coder_provisioner.me.os + auth = "token" + + metadata { + display_name = "CPU Usage" + key = "0_cpu_usage" + script = "coder stat cpu" + interval = 10 + timeout = 1 + } + + metadata { + display_name = "RAM Usage" + key = "1_ram_usage" + script = "coder stat mem" + interval = 10 + timeout = 1 + } + metadata { + display_name = "Disk Usage" + key = "1_disk_usage" + script = "coder stat disk" + interval = 10 + timeout = 1 + } +} + +module "code-server" { + source = "registry.coder.com/modules/code-server/coder" + version = "1.3.1" + agent_id = coder_agent.main.id +} + +# Runs a script at workspace start/stop or on a cron schedule +# details: https://registry.terraform.io/providers/coder/coder/latest/docs/resources/script + +module "dotfiles" { + count = data.coder_workspace.me.start_count + source = "registry.coder.com/coder/dotfiles/coder" + version = "1.2.1" + agent_id = coder_agent.main.id +} + +data "coder_parameter" "region" { + name = "Scaleway Region" + description = "Region to deploy server into" + type = "string" + default = "fr-par" + option { + name = "France - Paris (fr-par)" + value = "fr-par" + icon = "/emojis/1f1eb-1f1f7.png" + } + option { + name = "Netherlands - Amsterdam (nl-ams)" + value = "nl-ams" + icon = "/emojis/1f1f3-1f1f1.png" + } + option { + name = "Poland - Warsaw (pl-waw)" + value = "pl-waw" + icon = "/emojis/1f1f5-1f1f1.png" + } +} + +data "coder_parameter" "base_image" { + name = "Image" + description = "Which base image would you like to use?" + type = "string" + form_type = "radio" + default = "debian_trixie" + + option { + name = "Debian 13 (Trixie)" + value = "debian_trixie" + icon = "/icon/debian.svg" + } + + option { + name = "Debian 12 (Bookworm)" + value = "debian_bookworm" + icon = "/icon/debian.svg" + } + + option { + name = "Ubuntu 24.04 (Noble)" + value = "ubuntu_noble" + icon = "/icon/fedora.svg" + } + + option { + name = "Fedora 41" + value = "fedora_41" + icon = "/icon/fedora.svg" + } +} + +data "coder_parameter" "disk_size" { + name = "Disk Size" + type = "number" + form_type = "slider" + default = "10" + order = 8 + validation { + min = 10 + max = 500 + monotonic = "increasing" + } +} + +locals { + scaleway_config_raw = jsondecode(file("${path.module}/scaleway-config.json")) + + scaleway_instance_options = { + for instance in local.scaleway_config_raw : + instance.name => { + name = "${instance.name} (${instance.cpu} CPU, ${instance.gpu} GPU, ${floor(instance.ram / 1073741824)} GB RAM)" + value = instance.name + } + } +} + +data "coder_parameter" "instance_size" { + name = "instance_size" + display_name = "Instance Size" + description = "Which Instance Size should be used?" + default = "STARDUST1-S" + type = "string" + icon = "/icon/memory.svg" + mutable = false + form_type = "dropdown" + + dynamic "option" { + for_each = local.scaleway_instance_options + content { + name = option.value.name + value = option.value.value + } + } +} + +data "coder_parameter" "volume_iops" { + name = "Volume IOPS" + description = "IOPS to provision for disk" + type = "number" + default = 5000 + option { + name = "5000" + value = 5000 + } + option { + name = "15000" + value = 15000 + } +} + +resource "scaleway_instance_server" "workspace" { + count = data.coder_workspace.me.start_count + name = data.coder_workspace.me.name + type = data.coder_parameter.instance_size.value + image = data.coder_parameter.base_image.value + ip_ids = [scaleway_instance_ip.server_ip[0].id, scaleway_instance_ip.v4_server_ip[0].id] + project_id = var.project_id + user_data = { + cloud-init = data.cloudinit_config.user_data.rendered + } + additional_volume_ids = [scaleway_block_volume.persistent_storage.id] +} + +resource "scaleway_block_volume" "persistent_storage" { + iops = data.coder_parameter.volume_iops.value + name = "${data.coder_workspace.me.name}-home" + size_in_gb = data.coder_parameter.disk_size.value + project_id = var.project_id +} + + +resource "scaleway_instance_ip" "server_ip" { + count = data.coder_workspace.me.start_count + type = "routed_ipv6" + project_id = var.project_id +} + +resource "scaleway_instance_ip" "v4_server_ip" { + count = data.coder_workspace.me.start_count + type = "routed_ipv4" + project_id = var.project_id +} + +variable "project_id" { + type = string + description = "ID of the project to deploy into" +} + +variable "access_key" { + type = string + description = "Access key to use to deploy" +} + +variable "secret_key" { + type = string + description = "Secret key to use to deploy" +} + +variable "region" { + type = string + description = "Region to deploy into" +} diff --git a/registry/mossylion/templates/scaleway-instance/scaleway-config.json b/registry/mossylion/templates/scaleway-instance/scaleway-config.json new file mode 100644 index 000000000..e48fb05c6 --- /dev/null +++ b/registry/mossylion/templates/scaleway-instance/scaleway-config.json @@ -0,0 +1,450 @@ +[ + { + "name": "COPARM1-2C-8G", + "cpu": 2, + "gpu": 0, + "ram": 8589934592, + "arch": "arm64" + }, + { + "name": "COPARM1-4C-16G", + "cpu": 4, + "gpu": 0, + "ram": 17179869184, + "arch": "arm64" + }, + { + "name": "COPARM1-8C-32G", + "cpu": 8, + "gpu": 0, + "ram": 34359738368, + "arch": "arm64" + }, + { + "name": "COPARM1-16C-64G", + "cpu": 16, + "gpu": 0, + "ram": 68719476736, + "arch": "arm64" + }, + { + "name": "COPARM1-32C-128G", + "cpu": 32, + "gpu": 0, + "ram": 137438953472, + "arch": "arm64" + }, + { + "name": "DEV1-S", + "cpu": 2, + "gpu": 0, + "ram": 2147483648, + "arch": "x86_64" + }, + { + "name": "DEV1-M", + "cpu": 3, + "gpu": 0, + "ram": 4294967296, + "arch": "x86_64" + }, + { + "name": "DEV1-L", + "cpu": 4, + "gpu": 0, + "ram": 8589934592, + "arch": "x86_64" + }, + { + "name": "DEV1-XL", + "cpu": 4, + "gpu": 0, + "ram": 12884901888, + "arch": "x86_64" + }, + { + "name": "ENT1-XXS", + "cpu": 2, + "gpu": 0, + "ram": 8589934592, + "arch": "x86_64" + }, + { + "name": "ENT1-XS", + "cpu": 4, + "gpu": 0, + "ram": 17179869184, + "arch": "x86_64" + }, + { + "name": "ENT1-S", + "cpu": 8, + "gpu": 0, + "ram": 34359738368, + "arch": "x86_64" + }, + { + "name": "ENT1-M", + "cpu": 16, + "gpu": 0, + "ram": 68719476736, + "arch": "x86_64" + }, + { + "name": "ENT1-L", + "cpu": 32, + "gpu": 0, + "ram": 137438953472, + "arch": "x86_64" + }, + { + "name": "ENT1-XL", + "cpu": 64, + "gpu": 0, + "ram": 274877906944, + "arch": "x86_64" + }, + { + "name": "ENT1-2XL", + "cpu": 96, + "gpu": 0, + "ram": 412316860416, + "arch": "x86_64" + }, + { + "name": "GP1-XS", + "cpu": 4, + "gpu": 0, + "ram": 17179869184, + "arch": "x86_64" + }, + { + "name": "GP1-S", + "cpu": 8, + "gpu": 0, + "ram": 34359738368, + "arch": "x86_64" + }, + { + "name": "GP1-M", + "cpu": 16, + "gpu": 0, + "ram": 68719476736, + "arch": "x86_64" + }, + { + "name": "GP1-L", + "cpu": 32, + "gpu": 0, + "ram": 137438953472, + "arch": "x86_64" + }, + { + "name": "GP1-XL", + "cpu": 48, + "gpu": 0, + "ram": 274877906944, + "arch": "x86_64" + }, + { + "name": "L4-1-24G", + "cpu": 8, + "gpu": 1, + "ram": 51539607552, + "arch": "x86_64" + }, + { + "name": "L4-2-24G", + "cpu": 16, + "gpu": 2, + "ram": 103079215104, + "arch": "x86_64" + }, + { + "name": "L4-4-24G", + "cpu": 32, + "gpu": 4, + "ram": 206158430208, + "arch": "x86_64" + }, + { + "name": "L4-8-24G", + "cpu": 64, + "gpu": 8, + "ram": 412316860416, + "arch": "x86_64" + }, + { + "name": "PLAY2-PICO", + "cpu": 1, + "gpu": 0, + "ram": 2147483648, + "arch": "x86_64" + }, + { + "name": "PLAY2-NANO", + "cpu": 2, + "gpu": 0, + "ram": 4294967296, + "arch": "x86_64" + }, + { + "name": "PLAY2-MICRO", + "cpu": 4, + "gpu": 0, + "ram": 8589934592, + "arch": "x86_64" + }, + { + "name": "POP2-HC-2C-4G", + "cpu": 2, + "gpu": 0, + "ram": 4294967296, + "arch": "x86_64" + }, + { + "name": "POP2-2C-8G", + "cpu": 2, + "gpu": 0, + "ram": 8589934592, + "arch": "x86_64" + }, + { + "name": "POP2-HM-2C-16G", + "cpu": 2, + "gpu": 0, + "ram": 17179869184, + "arch": "x86_64" + }, + { + "name": "POP2-HC-4C-8G", + "cpu": 4, + "gpu": 0, + "ram": 8589934592, + "arch": "x86_64" + }, + { + "name": "POP2-4C-16G", + "cpu": 4, + "gpu": 0, + "ram": 17179869184, + "arch": "x86_64" + }, + { + "name": "POP2-2C-8G-WIN", + "cpu": 2, + "gpu": 0, + "ram": 8589934592, + "arch": "x86_64" + }, + { + "name": "POP2-HM-4C-32G", + "cpu": 4, + "gpu": 0, + "ram": 34359738368, + "arch": "x86_64" + }, + { + "name": "POP2-HC-8C-16G", + "cpu": 8, + "gpu": 0, + "ram": 17179869184, + "arch": "x86_64" + }, + { + "name": "POP2-HN-3", + "cpu": 2, + "gpu": 0, + "ram": 4294967296, + "arch": "x86_64" + }, + { + "name": "POP2-8C-32G", + "cpu": 8, + "gpu": 0, + "ram": 34359738368, + "arch": "x86_64" + }, + { + "name": "POP2-4C-16G-WIN", + "cpu": 4, + "gpu": 0, + "ram": 17179869184, + "arch": "x86_64" + }, + { + "name": "POP2-HM-8C-64G", + "cpu": 8, + "gpu": 0, + "ram": 68719476736, + "arch": "x86_64" + }, + { + "name": "POP2-HC-16C-32G", + "cpu": 16, + "gpu": 0, + "ram": 34359738368, + "arch": "x86_64" + }, + { + "name": "POP2-HN-5", + "cpu": 4, + "gpu": 0, + "ram": 8589934592, + "arch": "x86_64" + }, + { + "name": "POP2-16C-64G", + "cpu": 16, + "gpu": 0, + "ram": 68719476736, + "arch": "x86_64" + }, + { + "name": "POP2-8C-32G-WIN", + "cpu": 8, + "gpu": 0, + "ram": 34359738368, + "arch": "x86_64" + }, + { + "name": "POP2-HN-10", + "cpu": 4, + "gpu": 0, + "ram": 8589934592, + "arch": "x86_64" + }, + { + "name": "POP2-HM-16C-128G", + "cpu": 16, + "gpu": 0, + "ram": 137438953472, + "arch": "x86_64" + }, + { + "name": "POP2-HC-32C-64G", + "cpu": 32, + "gpu": 0, + "ram": 68719476736, + "arch": "x86_64" + }, + { + "name": "POP2-32C-128G", + "cpu": 32, + "gpu": 0, + "ram": 137438953472, + "arch": "x86_64" + }, + { + "name": "POP2-HC-48C-96G", + "cpu": 48, + "gpu": 0, + "ram": 103079215104, + "arch": "x86_64" + }, + { + "name": "POP2-16C-64G-WIN", + "cpu": 16, + "gpu": 0, + "ram": 68719476736, + "arch": "x86_64" + }, + { + "name": "POP2-HM-32C-256G", + "cpu": 32, + "gpu": 0, + "ram": 274877906944, + "arch": "x86_64" + }, + { + "name": "POP2-HC-64C-128G", + "cpu": 64, + "gpu": 0, + "ram": 137438953472, + "arch": "x86_64" + }, + { + "name": "POP2-48C-192G", + "cpu": 48, + "gpu": 0, + "ram": 206158430208, + "arch": "x86_64" + }, + { + "name": "POP2-64C-256G", + "cpu": 64, + "gpu": 0, + "ram": 274877906944, + "arch": "x86_64" + }, + { + "name": "POP2-HM-48C-384G", + "cpu": 48, + "gpu": 0, + "ram": 412316860416, + "arch": "x86_64" + }, + { + "name": "POP2-32C-128G-WIN", + "cpu": 32, + "gpu": 0, + "ram": 137438953472, + "arch": "x86_64" + }, + { + "name": "POP2-HM-64C-512G", + "cpu": 64, + "gpu": 0, + "ram": 549755813888, + "arch": "x86_64" + }, + { + "name": "PRO2-XXS", + "cpu": 2, + "gpu": 0, + "ram": 8589934592, + "arch": "x86_64" + }, + { + "name": "PRO2-XS", + "cpu": 4, + "gpu": 0, + "ram": 17179869184, + "arch": "x86_64" + }, + { + "name": "PRO2-S", + "cpu": 8, + "gpu": 0, + "ram": 34359738368, + "arch": "x86_64" + }, + { + "name": "PRO2-M", + "cpu": 16, + "gpu": 0, + "ram": 68719476736, + "arch": "x86_64" + }, + { + "name": "PRO2-L", + "cpu": 32, + "gpu": 0, + "ram": 137438953472, + "arch": "x86_64" + }, + { + "name": "RENDER-S", + "cpu": 10, + "gpu": 1, + "ram": 45097156608, + "arch": "x86_64" + }, + { + "name": "STARDUST1-S", + "cpu": 1, + "gpu": 0, + "ram": 1073741824, + "arch": "x86_64" + } +] From 041e5ba0f134ba7de932f9974c6bff93a95301e2 Mon Sep 17 00:00:00 2001 From: mossylion <222695950+mossylion@users.noreply.github.com> Date: Tue, 30 Sep 2025 17:15:25 +0100 Subject: [PATCH 2/7] Scaleway template - Additional QoL fixes --- .../cloud-init/userdata.sh.tftpl | 2 +- .../templates/scaleway-instance/main.tf | 61 +++++++++++++++---- 2 files changed, 51 insertions(+), 12 deletions(-) diff --git a/registry/mossylion/templates/scaleway-instance/cloud-init/userdata.sh.tftpl b/registry/mossylion/templates/scaleway-instance/cloud-init/userdata.sh.tftpl index 2070bc0a7..031628dab 100644 --- a/registry/mossylion/templates/scaleway-instance/cloud-init/userdata.sh.tftpl +++ b/registry/mossylion/templates/scaleway-instance/cloud-init/userdata.sh.tftpl @@ -1,2 +1,2 @@ #!/bin/bash -sudo -u '${linux_user}' CODER_AGENT_TOKEN=${coder_agent_token} sh -c '${init_script}' +sudo -u '${linux_user}' sh -c 'CODER_AGENT_TOKEN="${coder_agent_token}" ${init_script}' diff --git a/registry/mossylion/templates/scaleway-instance/main.tf b/registry/mossylion/templates/scaleway-instance/main.tf index 041bf123e..450d7fdb3 100644 --- a/registry/mossylion/templates/scaleway-instance/main.tf +++ b/registry/mossylion/templates/scaleway-instance/main.tf @@ -59,11 +59,22 @@ data "coder_provisioner" "me" {} data "coder_workspace" "me" {} +data "coder_workspace_owner" "me" {} + resource "coder_agent" "main" { arch = data.coder_provisioner.me.arch os = data.coder_provisioner.me.os auth = "token" + startup_script = <<-EOT + set -e + + # Install additional tools or run commands at workspace startup + # Uncomment and customize as needed: + # sudo apt-get update + # sudo apt-get install -y build-essential + EOT + metadata { display_name = "CPU Usage" key = "0_cpu_usage" @@ -82,9 +93,9 @@ resource "coder_agent" "main" { metadata { display_name = "Disk Usage" key = "1_disk_usage" - script = "coder stat disk" - interval = 10 - timeout = 1 + script = "coder stat disk --path /home/${local.linux_user}" + interval = 600 + timeout = 30 } } @@ -92,6 +103,8 @@ module "code-server" { source = "registry.coder.com/modules/code-server/coder" version = "1.3.1" agent_id = coder_agent.main.id + order = 1 + folder = "/home/${local.linux_user}" } # Runs a script at workspace start/stop or on a cron schedule @@ -104,6 +117,37 @@ module "dotfiles" { agent_id = coder_agent.main.id } +resource "coder_metadata" "workspace_info" { + count = data.coder_workspace.me.start_count + resource_id = scaleway_instance_server.workspace[0].id + + item { + key = "region" + value = data.coder_parameter.region.value + } + item { + key = "instance type" + value = scaleway_instance_server.workspace[0].type + } + item { + key = "image" + value = data.coder_parameter.base_image.value + } +} + +resource "coder_metadata" "volume_info" { + resource_id = scaleway_block_volume.persistent_storage.id + + item { + key = "size" + value = "${scaleway_block_volume.persistent_storage.size_in_gb} GiB" + } + item { + key = "iops" + value = scaleway_block_volume.persistent_storage.iops + } +} + data "coder_parameter" "region" { name = "Scaleway Region" description = "Region to deploy server into" @@ -148,7 +192,7 @@ data "coder_parameter" "base_image" { option { name = "Ubuntu 24.04 (Noble)" value = "ubuntu_noble" - icon = "/icon/fedora.svg" + icon = "/icon/ubuntu.svg" } option { @@ -219,7 +263,7 @@ data "coder_parameter" "volume_iops" { resource "scaleway_instance_server" "workspace" { count = data.coder_workspace.me.start_count - name = data.coder_workspace.me.name + name = "coder-${lower(data.coder_workspace_owner.me.name)}-${lower(data.coder_workspace.me.name)}" type = data.coder_parameter.instance_size.value image = data.coder_parameter.base_image.value ip_ids = [scaleway_instance_ip.server_ip[0].id, scaleway_instance_ip.v4_server_ip[0].id] @@ -232,7 +276,7 @@ resource "scaleway_instance_server" "workspace" { resource "scaleway_block_volume" "persistent_storage" { iops = data.coder_parameter.volume_iops.value - name = "${data.coder_workspace.me.name}-home" + name = "coder-${lower(data.coder_workspace_owner.me.name)}-${lower(data.coder_workspace.me.name)}-home" size_in_gb = data.coder_parameter.disk_size.value project_id = var.project_id } @@ -264,8 +308,3 @@ variable "secret_key" { type = string description = "Secret key to use to deploy" } - -variable "region" { - type = string - description = "Region to deploy into" -} From 3662464981a9d2c0c2a1288bb9788869fe0f7fe6 Mon Sep 17 00:00:00 2001 From: mossylion <222695950+mossylion@users.noreply.github.com> Date: Fri, 3 Oct 2025 10:16:27 +0100 Subject: [PATCH 3/7] fix: export CODER_AGENT_TOKEN in scaleway template The agent token was being set as a shell variable but not exported to the environment, causing the coder agent to fail with "CODER_AGENT_TOKEN must be set" error during cloud-init execution. --- .../templates/scaleway-instance/cloud-init/userdata.sh.tftpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/registry/mossylion/templates/scaleway-instance/cloud-init/userdata.sh.tftpl b/registry/mossylion/templates/scaleway-instance/cloud-init/userdata.sh.tftpl index 031628dab..72819ce99 100644 --- a/registry/mossylion/templates/scaleway-instance/cloud-init/userdata.sh.tftpl +++ b/registry/mossylion/templates/scaleway-instance/cloud-init/userdata.sh.tftpl @@ -1,2 +1,2 @@ #!/bin/bash -sudo -u '${linux_user}' sh -c 'CODER_AGENT_TOKEN="${coder_agent_token}" ${init_script}' +sudo -u '${linux_user}' sh -c 'export CODER_AGENT_TOKEN="${coder_agent_token}"; ${init_script}' From a03dc03195873c0832f4714a61f8c0fcadf74f91 Mon Sep 17 00:00:00 2001 From: mossylion <222695950+mossylion@users.noreply.github.com> Date: Wed, 15 Oct 2025 17:05:57 +0100 Subject: [PATCH 4/7] Replace scaleway logo with just the icon --- .icons/scaleway.svg | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.icons/scaleway.svg b/.icons/scaleway.svg index e5d0f39f7..ebe1ddf20 100644 --- a/.icons/scaleway.svg +++ b/.icons/scaleway.svg @@ -1 +1,2 @@ - + + \ No newline at end of file From 9d8fd6a2edf04e0e8a02804458704ce2e89c110a Mon Sep 17 00:00:00 2001 From: mossylion <222695950+mossylion@users.noreply.github.com> Date: Wed, 15 Oct 2025 22:09:10 +0100 Subject: [PATCH 5/7] Fix Scaleway Arch and more sensible instance default --- .../mossylion/templates/scaleway-instance/main.tf | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/registry/mossylion/templates/scaleway-instance/main.tf b/registry/mossylion/templates/scaleway-instance/main.tf index 450d7fdb3..c8ccbe5ac 100644 --- a/registry/mossylion/templates/scaleway-instance/main.tf +++ b/registry/mossylion/templates/scaleway-instance/main.tf @@ -62,7 +62,7 @@ data "coder_workspace" "me" {} data "coder_workspace_owner" "me" {} resource "coder_agent" "main" { - arch = data.coder_provisioner.me.arch + arch = local.selected_arch os = data.coder_provisioner.me.os auth = "token" @@ -225,13 +225,21 @@ locals { value = instance.name } } + + instance_arch_map = { + for instance in local.scaleway_config_raw : + instance.name => instance.arch + } + + # Convert Scaleway arch format to Coder arch format + selected_arch = local.instance_arch_map[data.coder_parameter.instance_size.value] == "x86_64" ? "amd64" : local.instance_arch_map[data.coder_parameter.instance_size.value] } data "coder_parameter" "instance_size" { name = "instance_size" display_name = "Instance Size" description = "Which Instance Size should be used?" - default = "STARDUST1-S" + default = "DEV1-M" type = "string" icon = "/icon/memory.svg" mutable = false From 4661bfc0b59bcc52f2d02d302ac1d3eecce9f47d Mon Sep 17 00:00:00 2001 From: mossylion <222695950+mossylion@users.noreply.github.com> Date: Wed, 15 Oct 2025 22:18:47 +0100 Subject: [PATCH 6/7] Scaleway make OS disk size configurable --- .../templates/scaleway-instance/main.tf | 29 +++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/registry/mossylion/templates/scaleway-instance/main.tf b/registry/mossylion/templates/scaleway-instance/main.tf index c8ccbe5ac..a4ef968ac 100644 --- a/registry/mossylion/templates/scaleway-instance/main.tf +++ b/registry/mossylion/templates/scaleway-instance/main.tf @@ -202,12 +202,27 @@ data "coder_parameter" "base_image" { } } +data "coder_parameter" "root_volume_size" { + name = "Root Volume Size" + description = "Size of the OS/boot disk in GB" + type = "number" + form_type = "slider" + default = "20" + order = 7 + validation { + min = 10 + max = 1000 + monotonic = "increasing" + } +} + data "coder_parameter" "disk_size" { - name = "Disk Size" - type = "number" - form_type = "slider" - default = "10" - order = 8 + name = "Persistent Storage Size" + description = "Size of the additional persistent storage volume in GB" + type = "number" + form_type = "slider" + default = "10" + order = 8 validation { min = 10 max = 500 @@ -280,6 +295,10 @@ resource "scaleway_instance_server" "workspace" { cloud-init = data.cloudinit_config.user_data.rendered } additional_volume_ids = [scaleway_block_volume.persistent_storage.id] + + root_volume { + size_in_gb = data.coder_parameter.root_volume_size.value + } } resource "scaleway_block_volume" "persistent_storage" { From 498a1e616b7203ec309458862fc4a57522c6a41a Mon Sep 17 00:00:00 2001 From: Mossy <222695950+mossylion@users.noreply.github.com> Date: Thu, 30 Oct 2025 08:22:00 +0000 Subject: [PATCH 7/7] Update registry/mossylion/templates/scaleway-instance/README.md Co-authored-by: Atif Ali --- registry/mossylion/templates/scaleway-instance/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/registry/mossylion/templates/scaleway-instance/README.md b/registry/mossylion/templates/scaleway-instance/README.md index cea95d317..065c9311b 100644 --- a/registry/mossylion/templates/scaleway-instance/README.md +++ b/registry/mossylion/templates/scaleway-instance/README.md @@ -3,7 +3,7 @@ display_name: "Scaleway Instance" description: "A workspace spun up on a Scaleway Instance" icon: "../../../../.icons/scaleway.svg" verified: false -tags: ["scaleway", "dev", "tools"] +tags: ["scaleway", "vm", "linux"] --- # Scaleway Instance Template