【AWS-CloudForamation】Yaml記述の基礎知識

# 擬似パラメータ
AWS CloudFormationでは、定義しなくても使用できる擬似パラメータ存在する。

1. **AWS::Region:** スタックがデプロイされているAWSリージョンを取得します。
   ```yaml
   MyBucket:
     Type: "AWS::S3::Bucket"
     Properties:
       BucketName: !Sub "my-bucket-${AWS::Region}"
       # 例:ap-northeast-1
   ```
   
2. **AWS::StackName:** スタックの名前を取得します。スタック内で一意です。
   ```yaml
   MyBucket:
     Type: "AWS::S3::Bucket"
     Properties:
       BucketName: !Sub "my-bucket-${AWS::StackName}"
   ```

3. **AWS::StackId:** スタックの一意のIDを取得します。
   ```yaml
   MyBucket:
     Type: "AWS::S3::Bucket"
     Properties:
       BucketName: !Sub "my-bucket-${AWS::StackId}"
   ```

4. **AWS::AccountId:** AWSアカウントのIDを取得します。
   ```yaml
   MyBucketPolicy:
     Type: "AWS::S3::BucketPolicy"
     Properties:
       Bucket: !Ref MyBucket
       PolicyDocument:
         Statement:
           - Effect: "Allow"
             Principal:
               AWS: !Sub arn:aws:iam::${AWS::AccountId}:root
             Action: "s3:GetObject"
             Resource: !Sub "arn:aws:s3:::${MyBucket}/*"
   ```

これらの擬似パラメータは、テンプレート内で情報を動的に取得したり、リソースを一意に識別したりするのに役立ちます。

# 関数
## !Ref関数　(Reference 参照)
1. **リソース名の参照:**
```yaml
Resources:
  MyBucket:
    Type: "AWS::S3::Bucket"

Outputs:
  BucketName:
    Value: !Ref MyBucket
```
この例では、`MyBucket`というS3バケットを作成し、`!Ref MyBucket`を使用してその名前を取得しています。

2. **パラメータの参照:**
```yaml
Parameters:
  Environment:
    Type: String
    Default: "Production"

Resources:
  MyInstance:
    Type: "AWS::EC2::Instance"
    Properties:
      InstanceType: "t2.micro"
      ImageId: "ami-12345678"
      Tags:
        - Key: "Environment"
          Value: !Ref Environment
```
ここでは、`Environment`というパラメータの値を`!Ref Environment`を使ってEC2インスタンスのタグに設定しています。

3. **条件付きリソースの参照:**
```yaml
Parameters:
  CreateResource: 
    Type: String
    AllowedValues: ["Yes", "No"]
    Default: "Yes"

Resources:
  MyResource:
    Type: "AWS::SomeResourceType"
    Condition: ShouldCreateResource
    Properties:
      # リソースの設定

Conditions:
  ShouldCreateResource: !Equals [!Ref CreateResource, "Yes"]
```
この例では、`CreateResource`パラメータに基づいて条件付きでリソースを作成し、`!Ref CreateResource`を使ってその値を条件として参照しています。

## !Sub関数　(Substitution 置換)
`!Sub`関数は文字列内で変数やリソースの属性を置換するために使用する。

1. **変数の置換:**
```yaml
Parameters:
  Environment:
    Type: String
    Default: "Production"

Resources:
  MyBucket:
    Type: "AWS::S3::Bucket"
    Properties:
      BucketName: !Sub "my-bucket-${Environment}"
```
この例では、`!Sub`関数を使って`BucketName`に`Environment`変数を埋め込んでいます。

2. **リソース属性の置換:**
```yaml
Resources:
  MyInstance:
    Type: "AWS::EC2::Instance"
    Properties:
      ImageId: "ami-12345678"
      UserData: !Sub |
        #!/bin/bash
        echo "Instance ID: $(curl http://169.254.169.254/latest/meta-data/instance-id)" > /tmp/instance-info
```
この例では、`!Sub`関数を使って`UserData`スクリプト内でEC2インスタンスIDを含む文字列を生成しています。

3. **複数の変数の組み合わせ:**
```yaml
Parameters:
  ProjectName:
    Type: String
    Default: "MyProject"
  Environment:
    Type: String
    Default: "Production"

Resources:
  MyBucket:
    Type: "AWS::S3::Bucket"
    Properties:
      BucketName: !Sub "${ProjectName}-${Environment}-data-bucket"
```
この例では、`!Sub`関数を使って`BucketName`に`ProjectName`と`Environment`変数を組み合わせています。

`!Sub`関数はこれらのようにしてテンプレート内で動的な文字列を生成するのに便利です。

## !GetAtt関数　(Get Attribute 属性情報の取得)
`!GetAtt`関数は、CloudFormationテンプレート内でAWSリソースの特定の属性を取得するために使用されます。

1. **リソース属性の取得:**
```yaml
Resources:
  MyLambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      Handler: index.handler
      Role: arn:aws:iam::123456789012:role/execution_role
      FunctionName: my-function

Outputs:
  FunctionArn:
    Description: Lambda Function ARN
    Value: !GetAtt MyLambdaFunction.Arn

  Runtime:
    Description: Lambda Function Runtime
    Value: !GetAtt MyLambdaFunction.Runtime

    # !GetAtt 論理ID.属性情報
```

この例では、AWS Lambda関数 `MyLambdaFunction` のARN（Amazon Resource Name）とランタイムを取得しています。ここで:

- `!GetAtt MyLambdaFunction.Arn` はLambda関数のARNを取得します。
- `!GetAtt MyLambdaFunction.Runtime` はLambda関数のランタイムを取得します。

このように、各リソースはそのリソースタイプに固有の属性を持ちます。Lambda関数の場合、`Arn`と`Runtime`はその属性の例です。お使いのAWSサービスによっては、取得できる属性が異なるため、AWSの公式ドキュメントを参照してください。

## !Join関数
`Join`関数は、AWS CloudFormationテンプレート内で文字列を連結するために使用される関数です。`Join`を使うと、指定したデリミタを使って複数の文字列を一つの文字列にまとめることができます。
＊デリミタ（Delimiter）は、文字列やデータを区切るための記号や文字(ex.コンマ)

以下は`Join`関数を使用してリスト内の文字列をコンマで連結する例です。

```yaml
!Join
  - ","
  - - "Item1"
    - "Item2"
    - "Item3"

Fn::Join:
  - ","
  - - "Item1"
    - "Item2"
    - "Item3"
```

上記の例では、`"Item1,Item2,Item3"`という文字列が生成されます。最初の引数がデリミタ（`,`）、次の引数が連結したい文字列のリストです。

`Join`関数は、テンプレート内で動的に文字列を生成する場合や、リソース名やタグの生成など、様々な場面で利用されます。