2021. november 11., csütörtök

Terraform, Cloudformation és Cognito

Némi IT és némi felhő újra

IaC eszközökkel dolgozom már nem is igazán tudom mióta. Az AWS CloudFormation-nel kezdtem valamikor 2014 körül (nem biztos, ez a ködös múltba vész)


Amikor elkezdtem a Terraformról tanulni, bennem volt a félelem, hogy nem fogok teljes AWS funkcionalitást kapni. A CloudFormation natív AWS eszköz. Valami amit egy külső gyártó fejleszt - elméletben - csak követheti a szolgáltató natív eszközét.

Elkezdtem Terraformot használni, mert ez volt az ügyfél elvárása, tehát a váltás nem az én döntésem volt. A fenti félelmem akkor vált kicsit valósággá amikor az ügyfél nem követte az AWS Provider verzióit megfelelően a saját deployment agent-jein (tehát ez nem róható fel sem a HashiCorpnak, sem a Terraform közösségnek). Tehát tulajdonképpen nem látszott valós lemaradás a Terraform oldalán. Emellett Terraform kódot írni sokkal kényelmesebb, sokkal több lehetőséget nyújt amikor feldolgozni, konvertálni kell, a rendelkezésre álló információt.

Egy pár hete, kb. három év kizárólagos Terraform munka után belecsöppentem újra egy CloudFormation projectbe.

Van egy - azt hittem - szuper egyszerű feladat. Publikálni egy Cognito User Pool Client titkos kulcsot az SSM Parameter Store-ba, titkosítva.

Terraformban ez így néz ki:

// Create Cognito User Pool
resource "aws_cognito_user_pool" "pool" {
  name = "pool"
}

// Create Cognito User Pool Client
resource "aws_cognito_user_pool_client" "client" {
  name = "client"
  user_pool_id = aws_cognito_user_pool.pool.id
  generate_secret     = true
}

// Publish to SSM Parameter Store
resource "aws_ssm_parameter" "secret" {
  name        = "/production/cognito/clientSecret"
  type        = "SecureString"
  value       = ${aws_cognito_user_pool_client.client.client_secret}
}

És kész is vagyunk.

Próbáljuk meg ugyanezt a CloudFormation-ben.

Vajon a AWS::Cognito::UserPoolClient objektum, ki tudja-e exportálni a titkos kulcsot? Nem. Forrás: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cognito-userpoolclient.html

Vajon a AWS::SSM::Parameter objektum tud-e SecureString értéket létrehozni? Nem. Forrás: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ssm-parameter.html

Itt van ahol a fenti teóriám "A CloudFormation-nek előrébb kell járnia mint a Terraformnak" megbukik.

Sok mindennel próbálkoztam sikertelenül, hogy megoldjam ezt. Végülis a következő kódrészlet működött (egy megjegyzés: a Python kódban, az import cfnresponse nem az én trehányságom miatt van külön sorban. Ez kell az AWS lambdának, hogy észrevegye, kell neki a cfnresponse.py és belerakja a deployment során a zip fájlba, ugyanis nem része a pip repónak):

Resources:
  # Create Cognito User Pool
  UserPool:
    Type: "AWS::Cognito::UserPool"
    Properties:
      UserPoolName: pool

  # Create Cognito User Pool Client
  UserPoolClient:
    Type: "AWS::Cognito::UserPoolClient"
    Properties:
      AccessTokenValidity: 15
      AllowedOAuthFlowsUserPoolClient: false
      ClientName: client
      GenerateSecret: true

  # You need a lambda to
  #     - read from the cognito user pool client
  #     - write to the parameter store
  #     - report back to the CloudFormation when finished
  CognitoSecretExporterLambda:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: CognitoSecretExporter
      Runtime: python3.9
      Role: !GetAtt CognitoSecretExporterExecutionRole.Arn
      Handler: index.handler
      Timeout: 30
      Environment:
        Variables:
          CognitoUserPoolId: !Ref UserPool
          CognitoUserPoolClientId: !Ref UserPoolClient
          ssmParameterName: /production/cognito/ClientSecret
      Code:
        ZipFile: |
          import boto3, os
          import cfnresponse

          def handler(event, context):
              CognitoUserPoolId = os.environ['CognitoUserPoolId']
              CognitoUserPoolClientId = os.environ['CognitoUserPoolClientId']
              ssmParameterName = os.environ['ssmParameterName']

              # Read Cognito
              cognito = boto3.client('cognito-idp')
              response = cognito.describe_user_pool_client(
                  UserPoolId = CognitoUserPoolId,
                  ClientId = CognitoUserPoolClientId
              )
              cognitoClientSecret = response['UserPoolClient']['ClientSecret']
              print(cognitoClientSecret)
              ssm = boto3.client('ssm')

              # Write to parameter store
              response = ssm.put_parameter(
                  Name = ssmParameterName,
                  Description = '[CF] Cognito Client Secret used by the WebApp',
                  Value = cognitoClientSecret,
                  Type = 'SecureString',
                  KeyId = 'alias/aws/ssm',
                  Overwrite = True,
                  Tier='Standard'
              )

              # Report success to CloudFormation
              responseData = {}
              responseData['Data'] = 120
              cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData) 

  # Trigger the lambda from the CloudFormation stack
  CognitoSecretExporterInvoke:
    Type: AWS::CloudFormation::CustomResource
    DependsOn: CognitoSecretExporterLambda
    Version: "1.0"
    Properties:
      ServiceToken: !GetAtt CognitoSecretExporterLambda.Arn 

  # IAM Role for the lambda above
  CognitoSecretExporterExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: CognitoSecretExporterExecutionRole
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Principal:
            Service:
              - lambda.amazonaws.com
          Action:
            - sts:AssumeRole
      Path: "/"
      Policies:
      - PolicyName: root
      PolicyDocument:
          Version: '2012-10-17'
          Statement:
            - Sid: EnablePutLogEvents
              Effect: Allow
              Action:
                - logs:CreateLogGroup
                - logs:CreateLogStream
                - logs:PutLogEvents
              Resource:
                - '*'
            - Sid: ReadCognito
              Effect: Allow
              Action:
                - cognito-idp:DescribeUserPoolClient
              Resource:
                - !GetAtt UserPool.Arn
            - Sid: ParamStore
              Effect: Allow
              Action:
                - ssm:DeleteParameter
                - ssm:PutParameter
                - ssm:GetParameter
              Resource: 
                - !Sub arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/production/cognito/ClientSecret

2021. október 15., péntek

Gigabyte és a moduláris tápegységek

A CNC maró mellett (mint mindig), elkezdtem egy másik projectet is. Egy egy sima PC építés. Össze akarok rakni egy NAS dobozt, abból ami itthon van (padlás takarítás 😂).

A hosszú évek alatt több - úgynevezett moduláris - ATX tápegységet használtam. Ezek a cuccok lehetővé teszik, hogy kicsit csökkentsd a PC házon belül uralkodó kábeldzsungelt, azzal, hogy a szükségtelen periféria kábeleket le tudod választani a tápegységről. Ezek a háttértárolók, grafikus kártyák, stb. kábelei.

A tápokon található moduláris csatlakozók nincsenek szabványosítva, és általában azonos típusok a különböző gyártóknál (2 soros, 6 vagy 8 érintkezős Molex Mini Fit).

Igen, vettem tápokat különböző gyártóktól (Gigabyte, Chieftec, stb.). Igen, sosem címkéztem fel ezeket. És igen, egy dobozban tartom az egészet. Ez azt jelenti, hogy halvány fogalmam sincs, melyik kábel, melyik táphoz tartozik.

A NAS tápjához, szükségem van jópár kábelre (mindenféle keretekben, összesen 14 HDDt, SSDt tervezek használni). Ha ezeket összekavarom, el tudom képzelni, milyen tűzijáték lesz belőle.

Az alanyunk aktuálisan egy 550W-os Gigabyte Odin (valahol van belőle egy 800W-os is, csak még nem került elő a padlásról). Letöltöttem a doksiját. Benne is van a kérdéses csatlakozó kiosztása. (Azért húztam át pirossal, nehogy valaki használja, mert rossz)

Elkezdtem vakarni a fejem. A dobozban lévő kábelek egyike sem rendelkezik ezzel a kiosztással.

Multiméter bekapcs. Mér.

A gyanúm beigazolódott. A doksi hulladék.

Ez a jó kiosztás (a csatlakozó rajz a Molex-től van és a tápon magán lévő csatit mutatja), és megegyezik a dobozban található kábelekkel (lehet, hogy véletlen, de a Gigabyte, és a Chieftec ugyanazt a kiosztást használja):



2021. szeptember 29., szerda

Azure BB 2. - Allowed (inherited) ~ != Allowed


Van két git repo az Azure DevOps-ban. Két különböző org, két különböző project.

Az egyik a másik másolata. Írtam egy pipeline scriptet ami egy irányban szinkronban tartja.

Pár branch (kb. 10) szinkronja szétesett az elején, mert nem ezzel a scripttel történt az eredeti szinkron.

Rendbe akartam rakni. Azt tudom a fejlesztőktől, hogy a forrással a cél nyugodtan felülírható. Szóval forrás checkout cél push --force.

Ez ment is, két branch kivételével, ahol is közölte őnagysága, hogy nincs a baranch-re force update jogom.

Mi vaaaaan????

Túrom a jogosultságokat. Egyetlen csoportnak vagyok a tagja a cél projecten. Megnézem branch-re lebontva. Azt írja a GUI, hogy a csoportnak van öröklött force update joga.

Ok, de akkor miért nem megy? Adok a csoportnak közvetlen force update jogot, és csodák csodája, lefutnak a parancsaim. Nem, nincs valami deny ami bekavar, hiszen ez az egyetlen csoporttagságom és nincs közvetlen jogom. Továbbá, minden branch-nél be van kapcsolva az öröklődés, szóval ennél a kettőnél miért más az eredmény.

Csak nem mert BB?

2021. szeptember 28., kedd

Azure BB 1.


Tegnap kiírtam az FBn, hogy a BB az Azure szempontjából nem Balatonboglár vagy Budapest Bank, hanem Bugos Bmeg.

Volt aki kérdezte, hogy mi a bajom vele, mit nem tud amit az AWS igen. Egy dolgot: Az AWS működik.

Arra gondoltam, hogy leírom most már, amibe belefutok. Jelzem, ez a mostani, kb. az ötödik az elmúlt két hétben, csak most szakadt el a cérna végképp.

Na szóval. Tegnap este 6 körül próbáltam egy fura npm autentikációs hibát javítani az újonnan épülő Azure Pipelines környezetünkben. Még jó, hogy a jobokat egyenlőre senki sem használja, így el lehetett napolni a hibajavítást.

A jelenség a következő: egyszercsak az összes automatikus jobunk meghalt. Hibaüzenet nincs, mind cancel-re fut. Debug bekacs, a hibaüzenetek száma jelentősen nő. Nulláról, nullára.

Remek. Az össz dolog ami egyszer valahol a 15 körüli pipeline valamelyikében egy pillanatra bevillant, hogy a key vault hátterű variable group-ban használt service connection nem tudja olvasni a key vault-ot.

Végig is néztem, kibogarásztam a kapcsolódó service principalt, megnézetm a key vault-on a jogait, ott minden rendben. A variable group sem jelez hibát. Kb. ezzel hagytam ott tegnap. Hátha valami intermittent azsúr marhaság és mára megjavul.

Nem javult meg.

Nyomozok a neten, kugli a barátunk. Találok egy ilyet:

https://developercommunity.visualstudio.com/t/azure-devops-pipeline-job-cancelled-with-no-obviou/980961

Ebben a két dolog összevág. A key vaultos variable group, meg a canceled pipeline.

Na, újra is gyártom a service connection-t, berakom a helyére és láss csodát, elindul.

'95-ben érzem magam. Értelmetlen hibaüzenet (vagy még az se), újraindítom, ha nem javúl meg, újratelepítem.

2021. szeptember 25., szombat

CNC maró újjászületés 1.

2014-ben vettem egy CNC marót az Aliexpressen. Megtanultam használni. Volt vele egy rakás probléma, amit meg akartam (és el is kezdtem) oldani.

Lecseréltem az alulméretezett tápegységet két kapcsolóüzeműre, terveztem (és rengeteg munkát tettem bele) egy új maró motor vezérlőt. Elkövettem közben rengeteg hibát (leégettem az az egyik új tápegységet, majd később, a javítási kísérlet közben véglegesen kinyírtam). Még egy porleválasztót is terveztem hozzá (az is félkész).

A végén rájöttem, hogy sosem fog megfelelni az igényeimnek. Feladtam. Egyszer összeszedtem hozzá vezérlő alkatrészeket, hogy "csak úgy" működjön, de a végén hagytam az egészet ott kallódni a műhelyben.

Az alapvető problémák, amik miatt végül is feladtam:

  • Rájöttem, hogy a 3040-es méret kicsi nekem. Sokkal inkább kellene egy 6040 vagy méginkább egy 6090
  • A 300W-os (később 400W-osra cserélt) maró motor túl kicsi nekem. A felhasznált szénkefés DC motornak alacsony a nyomatéka alacsony fordulaton. Alumínium maráshoz alacsony fordulaton nagy nyomaték lenne az ideális. Nem tudok nagyobb motort (vagy akár egy kisteljesítményű BLDC motort) belerakni az 52mm-es tartóba. Ahhoz, hogy nagyobb motor kerüljön bele, a komplett Z tengelyt cserélni kéne miután az egészet (motor kengyel, lineáris csapágytartó, golyós orsó tartó) egyetlen darab aluból marták ki.

Végül arra jutottam, hogy az átalakítás túl sokba kerülne, és a végén a méret így is túl kicsi maradna.

Itt tartok most. Öt éve hozzá sem nyúltam.

Folyamatosan piszkálom a fiam, hogy csináljunk valami közös projektet, és ne csak a gépén játszon a szabadidejében. Néhány hete, előjött valami ötlettel. Arra jutottunk, hogy a megvalósításhoz kellene a működő CNC maró (próbáltam meggyőzni, hogy 3D nyomtassuk, de nem volt rá vevő).

Úgy éreztem, hogy ez egy jó alkalom, hogy újáépítsem a CNC marót, és ez engem is talán újra sínre tesz.

A terv:

Építek egy új vezérlődobozt a CNC maróhoz és összerakom a teljes munkafolyamatot a tervezéstől a marásig. Alapvetően azokból az alkatrészekből akarok építkezni, amik már most is megvannak. A cél, hogy a végén (a fiam projektjének befejezése után) eladjam a CNC3040-et és tudjak egy nagyobbat építeni.

A vezérlődoboz:

Egy régi PC midi torony. Ilyesmi mindig kallódik nálam, miután a 30 éve informatikából élek. :-)

  • Egy mini-ITX alaplap: Gigabyte GA-E6010N - ezt most újonnan vettem, ehhez a projekthez
  • 8GB DDR-3 RAM - volt otthon
  • 60GB SSD - volt otthon
  • 600W 48V tápegység a maró motorhoz - az előző CNC próbálkozásból maradt
  • 100W 24V tápegység a léptetőmotorokhoz - az előző CNC próbálkozásból maradt
  • 350W Chieftec PC tápegység az alaplaphoz és a GRBL vezérlőhöz - már megvolt
  • Szilárdtest relé - volt otthon
  • GRBL vezérlő kártya - évekkel ezelőtt megvettem a CNChez
  • TB6600 léptetőmotor vezérlők - évekkel ezelőtt megvettem a CNChez
  • Maró motor fordulatszám szabályozó - évekkel ezelőtt megvettem a CNChez
  • Csatlakozók - a korábbi vezérlőből bontottam

1. Összeraktam a PCt az asztalomon, hogy a vezérlő szoftvert felrakjam rá


Egy Ubuntu Desktop 20.04 LTS került rá. Az ablakkezelőt lecseréltem az LXQt-re, hogy csökkentsem az előforrásigényt. Felraktam a Dockert rá (a munkámból adódóan az utóbbi években Docker függő lettem), és egy CNC.js konténert rá. Némi javítgatás még szükséges, de ez már csak akkor lesz lehetséges, ha a GRBL vezérlő a helyére kerül.

Az első feladat teljesítve a CNC.js elindult.


2. Rakjuk össze a vezérlődobozt

Kifúrtam pár popszegecset a PC doboz hátából. Kivettem a PC kártya tartó/alaplap ATX kitörés teljes acélszerelvényét. Kettévágtam az első kártyahely után (az első kártyahely még a mini-ITX alaplapon is rajta van). Amint megvoltam ezzel, visszaszegecseltem az egészet.

Levágtam pár merevlemez tartó fület a 3,5"-es helyeknél. Ez a 100W-os táp elhelyezéséhez volt szükséges. Szerencsére a találtam pár lyukat a doboz alján aminél fel tudtam fogatni a tápot csavarozás nélkül.

Vágtam két L alu profilt a 600W-os táphoz, hogy be tudjam rakni az 5,25"-ös helyre. Némi fúrás, menetvágás, csiszolás után, a helyére is került.

Csináltam egy papa tápcsatiból (a régi ata cuccokhoz valóból, ami volt otthon szereletlen) egy kábelt a szilárdtest reléhez, és beszereltem a relét a helyére (a doboz felső ventilátor lyukjai pont jók voltak).

Az az elképzelésem, hogy a relé majd elindítja a két plusz tápot, ha megnyomom az előlapi tápkapcsolót.


Módosítottam a PC tápot kicsit.

  • Kicseréltem a hátlapi főkapcsolót nagyobbra, hogy kibírja a plusz két tápegység áramát
  • Kivezettem egy sorkapocsra a hálózati feszültséget - Nem akarok még plusz hálózati aljzatot látni a doboz hátán.
  • Kicseréltem a zajos (haldokló) ventilátort

Összeraktam a fentieket, valamint az alaplap, az SSD meghajtó is a helyére került.


Tudom, hogy ez most még nem látszik többnek, mint egy szokásos PC (semmi érdekes sincs benne, építettünk ilyet többszázszor), de a folytatás következik.

2021. szeptember 17., péntek

Újrakezdés

Talán észrevetted, hogy nem írtam semmit március óta. Nem voltam túl aktív az elmúlt két évben sem.

Sok dolog történik most körülöttem, ami kapcsolódik a blogoláshoz, a hobbijaimhoz, és akár a munkámhoz.

Azt tervezem, hogy sűrűbben fogok írni mostantól. Újrakezdek korábban félbehagyott projecteket. Meglátjuk, hogy ez a terv, mennyire vállik valósággá.

2021. szeptember 11., szombat

9/11

Hagy mondjak el egy történetet. Az én történetemet.

1996 December

New Yorkba látogattam, édesanyámmal. Nagymamám egy barátja hívott meg. Három hétig voltunk ott. Nem akarom az egész utat részletezni, csak két eseményt kiemelni.

Elmentünk az Empire States Building-hez (a tetejére). 5 órát álltunk sorba, hogy a liftekhez jussunk. Mire feljutottunk a tetőre már besötétedett. Megnéztük a várost felülről.

Az utazás utolsó napján láttam valahol a városban egy táblát, hogy a 86-os mólónál áll a USS Intrepid, múzeummá alakítva. Miután már csak pár óránk maradt, nem volt elég időnk meglátogatni. Ez volt a fejemben: Legközelebb.

2000

Ebben az időben a nyomdaiparban dolgoztam. Terveztünk egy céges látogatást a düsseldorfi Drupa kiállításra. Édesapám súlyosan megbetegedett, ezért töröltük az utat. A következő évre terveztek egy hasonló kiállítást, ezúttal Chicago-ba, a PRINT 01-et.

2001 September 6.

Édesapám meggyógyult, szóval irány Chicago. Az utat a Nyomdász Szakmai Szövetség szervezte. Összesen 10 emberel indultunk el. Azt terveztük, hogy a szakmai program után két napot New Yorkban töltünk.

2001 September 9.

Megérkeztünk New Yorkba. Tettünk egy buszos körtúrát, mert néhány embernek a csoportból ez volt az első New Yorki útja. Még a WTC-hez is elmentünk körülnézni.

2001 September 10.

Két kollégám másnap reggelre azt tervezte, hogy hajnalban korán felmegy a WTC tetejére, hogy megnézze a várost felülről. Engem is hívtak. Úgy döntöttem, hogy nem megyek. Először is öt évvel korábban már láttam a várost egy felhőkarcoló tetejéről, másodszor, meg akartam végre nézni a USS Intrepid-et, ami '96-ban lemaradt.

Miután a két kolléga nem beszélt angolul, úgy döntöttek, hogy velem jönnek másnap reggel a múzeumba ...

A véletlenek összjátéka, hogyan mentheti meg az életed.

Ma 20 éve történt.